Exemplo n.º 1
0
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;
}