bool LayerTextureUpdaterSkPicture::createFrameBuffer() { ASSERT(!m_fbo); ASSERT(!m_bufferSize.isEmpty()); // SKIA only needs color and stencil buffers, not depth buffer. // But it is very uncommon for cards to support color + stencil FBO config. // The most common config is color + packed-depth-stencil. // Instead of iterating through all possible FBO configs, we only try the // most common one here. // FIXME: Delegate the task of creating frame-buffer to SKIA. // It has all necessary code to iterate through all possible configs // and choose the one most suitable for its purposes. Extensions3D* extensions = context()->getExtensions(); if (!extensions->supports("GL_OES_packed_depth_stencil")) return false; extensions->ensureEnabled("GL_OES_packed_depth_stencil"); // Create and bind a frame-buffer-object. m_fbo = context()->createFramebuffer(); if (!m_fbo) return false; context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); // We just need to create a stencil buffer for FBO. // The color buffer (texture) will be provided by tiles. // SKIA does not need depth buffer. m_depthStencilBuffer = context()->createRenderbuffer(); if (!m_depthStencilBuffer) { deleteFrameBuffer(); return false; } context()->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); context()->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, Extensions3D::DEPTH24_STENCIL8, m_bufferSize.width(), m_bufferSize.height()); context()->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); context()->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); // Create a skia gpu canvas. GrContext* skiaContext = m_context->grContext(); GrPlatformSurfaceDesc targetDesc; targetDesc.reset(); targetDesc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType; targetDesc.fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit; targetDesc.fWidth = m_bufferSize.width(); targetDesc.fHeight = m_bufferSize.height(); targetDesc.fConfig = kRGBA_8888_GrPixelConfig; targetDesc.fStencilBits = 8; targetDesc.fPlatformRenderTarget = m_fbo; SkAutoTUnref<GrRenderTarget> target(static_cast<GrRenderTarget*>(skiaContext->createPlatformSurface(targetDesc))); SkAutoTUnref<SkDevice> device(new SkGpuDevice(skiaContext, target.get())); m_canvas = adoptPtr(new SkCanvas(device.get())); context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0); return true; }