void LayerTextureUpdaterSkPicture::updateTextureRect(LayerTexture* texture, const IntRect& sourceRect, const IntRect& destRect) { if (m_createFrameBuffer) { deleteFrameBuffer(); createFrameBuffer(); m_createFrameBuffer = false; } if (!m_fbo) return; // Bind texture. context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); texture->framebufferTexture2D(); ASSERT(context()->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) == GraphicsContext3D::FRAMEBUFFER_COMPLETE); // Notify SKIA to sync its internal GL state. m_skiaContext->resetContext(); m_canvas->save(); m_canvas->clipRect(SkRect(destRect)); // Translate the origin of contentRect to that of destRect. // Note that destRect is defined relative to sourceRect. m_canvas->translate(contentRect().x() - sourceRect.x() + destRect.x(), contentRect().y() - sourceRect.y() + destRect.y()); m_canvas->drawPicture(m_picture); m_canvas->restore(); // Flush SKIA context so that all the rendered stuff appears on the texture. m_skiaContext->flush(GrContext::kForceCurrentRenderTarget_FlushBit); // Unbind texture. context()->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, 0, 0); context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0); }
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; }
void LayerTextureUpdaterSkPicture::updateTextureRect(GraphicsContext3D* compositorContext, TextureAllocator* allocator, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect) { ASSERT(!m_context || m_context == compositorContext); m_context = compositorContext; if (m_createFrameBuffer) { deleteFrameBuffer(); createFrameBuffer(); m_createFrameBuffer = false; } if (!m_fbo) return; // Bind texture. context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); texture->framebufferTexture2D(context(), allocator); ASSERT(context()->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) == GraphicsContext3D::FRAMEBUFFER_COMPLETE); // Make sure SKIA uses the correct GL context. context()->makeContextCurrent(); GrContext* skiaContext = m_context->grContext(); // Notify SKIA to sync its internal GL state. skiaContext->resetContext(); m_canvas->save(); m_canvas->clipRect(SkRect(destRect)); // Translate the origin of contentRect to that of destRect. // Note that destRect is defined relative to sourceRect. m_canvas->translate(contentRect().x() - sourceRect.x() + destRect.x(), contentRect().y() - sourceRect.y() + destRect.y()); m_canvas->drawPicture(m_picture); m_canvas->restore(); // Flush SKIA context so that all the rendered stuff appears on the texture. skiaContext->flush(); // Unbind texture. context()->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, 0, 0); context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0); }
LayerTextureUpdaterSkPicture::~LayerTextureUpdaterSkPicture() { deleteFrameBuffer(); }