SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo) { // Ganesh should be the only code in the rendering thread that is using GL // and setting the EGLContext. If this is not the case then we need to // reset the Ganesh context to prevent rendering issues. bool contextNeedsReset = false; if (eglGetCurrentContext() != m_surfaceContext) { XLOG("Warning: EGLContext has Changed! %p, %p", m_surfaceContext, eglGetCurrentContext()); contextNeedsReset = true; } EGLDisplay display; if (!m_surfaceContext) { if(eglGetCurrentContext() != EGL_NO_CONTEXT) { XLOG("ERROR: should not have a context yet"); } display = eglGetDisplay(EGL_DEFAULT_DISPLAY); GLUtils::checkEglError("eglGetDisplay"); EGLint majorVersion; EGLint minorVersion; EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion); GLUtils::checkEglError("eglInitialize", returnValue); EGLint numConfigs; static const EGLint configAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_STENCIL_SIZE, 8, EGL_NONE }; eglChooseConfig(display, configAttribs, &m_surfaceConfig, 1, &numConfigs); GLUtils::checkEglError("eglChooseConfig"); static const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; m_surfaceContext = eglCreateContext(display, m_surfaceConfig, NULL, contextAttribs); GLUtils::checkEglError("eglCreateContext"); } else { display = eglGetCurrentDisplay(); GLUtils::checkEglError("eglGetCurrentDisplay"); } TransferQueue* tileQueue = TilesManager::instance()->transferQueue(); if (tileQueue->m_eglSurface == EGL_NO_SURFACE) { const float tileWidth = renderInfo.tileSize.width(); const float tileHeight = renderInfo.tileSize.height(); ANativeWindow* anw = tileQueue->m_ANW.get(); int result = ANativeWindow_setBuffersGeometry(anw, (int)tileWidth, (int)tileHeight, WINDOW_FORMAT_RGBA_8888); renderInfo.textureInfo->m_width = tileWidth; renderInfo.textureInfo->m_height = tileHeight; tileQueue->m_eglSurface = eglCreateWindowSurface(display, m_surfaceConfig, anw, NULL); GLUtils::checkEglError("eglCreateWindowSurface"); XLOG("eglCreateWindowSurface"); } EGLBoolean returnValue = eglMakeCurrent(display, tileQueue->m_eglSurface, tileQueue->m_eglSurface, m_surfaceContext); GLUtils::checkEglError("eglMakeCurrent", returnValue); XLOG("eglMakeCurrent"); if (!m_baseTileDeviceSurface) { GrPlatformRenderTargetDesc renderTargetDesc; renderTargetDesc.fWidth = TilesManager::tileWidth(); renderTargetDesc.fHeight = TilesManager::tileHeight(); renderTargetDesc.fConfig = kRGBA_8888_PM_GrPixelConfig; renderTargetDesc.fSampleCnt = 0; renderTargetDesc.fStencilBits = 8; renderTargetDesc.fRenderTargetHandle = 0; GrContext* grContext = getGrContext(); GrRenderTarget* renderTarget = grContext->createPlatformRenderTarget(renderTargetDesc); m_baseTileDeviceSurface = new SkGpuDevice(grContext, renderTarget); renderTarget->unref(); XLOG("generated device %p", m_baseTileDeviceSurface); } GLUtils::checkGlError("getDeviceForBaseTile"); // We must reset the Ganesh context only after we are sure we have // re-established our EGLContext as the current context. if (m_baseTileDeviceSurface && contextNeedsReset) getGrContext()->resetContext(); return m_baseTileDeviceSurface; }