Title: [98277] trunk/Source/WebCore
Revision
98277
Author
[email protected]
Date
2011-10-24 13:48:33 -0700 (Mon, 24 Oct 2011)

Log Message

[chromium] Make accelerated drawing work with threaded compositing
https://bugs.webkit.org/show_bug.cgi?id=70656

Reviewed by James Robinson.

Make sure that the compositor context is not used outside LayerTextureUpdater::updateTextureRect().
Created a FrameBuffer class that wraps skia gpu canvas and manages GL resources.

* platform/graphics/chromium/ContentLayerChromium.cpp:
(WebCore::ContentLayerChromium::createTextureUpdater):
* platform/graphics/chromium/LayerTextureUpdaterCanvas.cpp:
(WebCore::FrameBuffer::FrameBuffer::FrameBuffer):
(WebCore::FrameBuffer::FrameBuffer::~FrameBuffer):
(WebCore::FrameBuffer::FrameBuffer::initialize):
(WebCore::LayerTextureUpdaterSkPicture::LayerTextureUpdaterSkPicture):
(WebCore::LayerTextureUpdaterSkPicture::~LayerTextureUpdaterSkPicture):
(WebCore::LayerTextureUpdaterSkPicture::prepareToUpdate):
(WebCore::LayerTextureUpdaterSkPicture::updateTextureRect):
* platform/graphics/chromium/LayerTextureUpdaterCanvas.h:
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::initialize):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (98276 => 98277)


--- trunk/Source/WebCore/ChangeLog	2011-10-24 20:47:45 UTC (rev 98276)
+++ trunk/Source/WebCore/ChangeLog	2011-10-24 20:48:33 UTC (rev 98277)
@@ -1,3 +1,27 @@
+2011-10-24  Alok Priyadarshi  <[email protected]>
+
+        [chromium] Make accelerated drawing work with threaded compositing
+        https://bugs.webkit.org/show_bug.cgi?id=70656
+
+        Reviewed by James Robinson.
+
+        Make sure that the compositor context is not used outside LayerTextureUpdater::updateTextureRect().
+        Created a FrameBuffer class that wraps skia gpu canvas and manages GL resources.
+
+        * platform/graphics/chromium/ContentLayerChromium.cpp:
+        (WebCore::ContentLayerChromium::createTextureUpdater):
+        * platform/graphics/chromium/LayerTextureUpdaterCanvas.cpp:
+        (WebCore::FrameBuffer::FrameBuffer::FrameBuffer):
+        (WebCore::FrameBuffer::FrameBuffer::~FrameBuffer):
+        (WebCore::FrameBuffer::FrameBuffer::initialize):
+        (WebCore::LayerTextureUpdaterSkPicture::LayerTextureUpdaterSkPicture):
+        (WebCore::LayerTextureUpdaterSkPicture::~LayerTextureUpdaterSkPicture):
+        (WebCore::LayerTextureUpdaterSkPicture::prepareToUpdate):
+        (WebCore::LayerTextureUpdaterSkPicture::updateTextureRect):
+        * platform/graphics/chromium/LayerTextureUpdaterCanvas.h:
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::initialize):
+
 2011-10-24  Adam Klein  <[email protected]>
 
         Optimize Node::isInShadowTree to execute in constant-time

Modified: trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp (98276 => 98277)


--- trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp	2011-10-24 20:47:45 UTC (rev 98276)
+++ trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp	2011-10-24 20:48:33 UTC (rev 98277)
@@ -120,15 +120,12 @@
 
 void ContentLayerChromium::createTextureUpdater(const CCLayerTreeHost* host)
 {
-#if USE(SKIA) && USE(ACCELERATED_DRAWING)
-    // Note that host->skiaContext() will crash if called while in threaded
-    // mode. This thus depends on CCLayerTreeHost::initialize turning off
-    // acceleratePainting to prevent this from crashing.
+#if USE(SKIA)
     if (host->settings().acceleratePainting) {
         m_textureUpdater = LayerTextureUpdaterSkPicture::create(ContentLayerPainter::create(m_delegate));
         return;
     }
-#endif // USE(SKIA) && USE(ACCELERATED_DRAWING)
+#endif // USE(SKIA)
 
     m_textureUpdater = LayerTextureUpdaterBitmap::create(ContentLayerPainter::create(m_delegate), host->layerRendererCapabilities().usingMapSub);
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerTextureUpdaterCanvas.cpp (98276 => 98277)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerTextureUpdaterCanvas.cpp	2011-10-24 20:47:45 UTC (rev 98276)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerTextureUpdaterCanvas.cpp	2011-10-24 20:48:33 UTC (rev 98277)
@@ -46,6 +46,66 @@
 
 namespace WebCore {
 
+#if USE(SKIA)
+namespace {
+
+class FrameBuffer {
+public:
+    FrameBuffer();
+    ~FrameBuffer();
+
+    SkCanvas* initialize(GraphicsContext3D*, TextureAllocator*, ManagedTexture*);
+
+private:
+    GraphicsContext3D* m_context;
+    Platform3DObject m_fbo;
+    OwnPtr<SkCanvas> m_canvas;
+};
+
+FrameBuffer::FrameBuffer()
+    : m_context(0)
+    , m_fbo(0)
+{
+}
+
+FrameBuffer::~FrameBuffer()
+{
+    m_canvas.clear();
+
+    if (m_fbo)
+        m_context->deleteFramebuffer(m_fbo);
+}
+
+SkCanvas* FrameBuffer::initialize(GraphicsContext3D* context, TextureAllocator* allocator, ManagedTexture* texture)
+{
+    m_context = context;
+    m_fbo = m_context->createFramebuffer();
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+    texture->framebufferTexture2D(m_context, allocator);
+
+    // Create a skia gpu canvas.
+    GrContext* grContext = m_context->grContext();
+    IntSize canvasSize = texture->size();
+    GrPlatformSurfaceDesc targetDesc;
+    targetDesc.reset();
+    targetDesc.fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType;
+    targetDesc.fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit;
+    targetDesc.fWidth = canvasSize.width();
+    targetDesc.fHeight = canvasSize.height();
+    targetDesc.fConfig = kRGBA_8888_GrPixelConfig;
+    targetDesc.fStencilBits = 8;
+    targetDesc.fPlatformTexture = texture->textureId();
+    targetDesc.fPlatformRenderTarget = m_fbo;
+    SkAutoTUnref<GrTexture> target(static_cast<GrTexture*>(grContext->createPlatformSurface(targetDesc)));
+    SkAutoTUnref<SkDevice> device(new SkGpuDevice(grContext, target.get()));
+    m_canvas = adoptPtr(new SkCanvas(device.get()));
+
+    return m_canvas.get();
+}
+
+} // namespace
+#endif // USE(SKIA)
+
 LayerTextureUpdaterCanvas::LayerTextureUpdaterCanvas(PassOwnPtr<LayerPainterChromium> painter)
     : m_painter(painter)
 {
@@ -101,7 +161,7 @@
     m_texSubImage.upload(locker.pixels(), contentRect(), sourceRect, destRect, texture->format(), context);
 }
 
-#if USE(SKIA) && USE(ACCELERATED_DRAWING)
+#if USE(SKIA)
 PassRefPtr<LayerTextureUpdaterSkPicture> LayerTextureUpdaterSkPicture::create(PassOwnPtr<LayerPainterChromium> painter)
 {
     return adoptRef(new LayerTextureUpdaterSkPicture(painter));
@@ -109,16 +169,11 @@
 
 LayerTextureUpdaterSkPicture::LayerTextureUpdaterSkPicture(PassOwnPtr<LayerPainterChromium> painter)
     : LayerTextureUpdaterCanvas(painter)
-    , m_context(0)
-    , m_createFrameBuffer(false)
-    , m_fbo(0)
-    , m_depthStencilBuffer(0)
 {
 }
 
 LayerTextureUpdaterSkPicture::~LayerTextureUpdaterSkPicture()
 {
-    deleteFrameBuffer();
 }
 
 LayerTextureUpdater::SampledTexelFormat LayerTextureUpdaterSkPicture::sampledTexelFormat(GC3Denum textureFormat)
@@ -129,14 +184,6 @@
 
 void LayerTextureUpdaterSkPicture::prepareToUpdate(const IntRect& contentRect, const IntSize& tileSize, int borderTexels)
 {
-    // Need to recreate FBO if tile-size changed.
-    // Note that we cannot create the framebuffer here because this function does not run in compositor thread
-    // and hence does not have access to compositor context.
-    if (m_bufferSize != tileSize) {
-        m_createFrameBuffer = true;
-        m_bufferSize = tileSize;
-    }
-
     SkCanvas* canvas = m_picture.beginRecording(contentRect.width(), contentRect.height());
     PlatformContextSkia platformContext(canvas);
     GraphicsContext graphicsContext(&platformContext);
@@ -144,116 +191,28 @@
     m_picture.endRecording();
 }
 
-void LayerTextureUpdaterSkPicture::updateTextureRect(GraphicsContext3D* compositorContext, TextureAllocator* allocator, ManagedTexture* texture, const IntRect& sourceRect, const IntRect& destRect)
+void LayerTextureUpdaterSkPicture::updateTextureRect(GraphicsContext3D* context, 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();
+    context->makeContextCurrent();
     // Notify SKIA to sync its internal GL state.
-    skiaContext->resetContext();
-    m_canvas->save();
-    m_canvas->clipRect(SkRect(destRect));
+    context->grContext()->resetContext();
+
+    // Create an accelerated canvas to draw on.
+    FrameBuffer buffer;
+    SkCanvas* canvas = buffer.initialize(context, allocator, texture);
+
+    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();
+    canvas->translate(contentRect().x() - sourceRect.x() + destRect.x(),
+                      contentRect().y() - sourceRect.y() + destRect.y());
+    canvas->drawPicture(m_picture);
 
-    // Unbind texture.
-    context()->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, 0, 0);
-    context()->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+    // Flush SKIA context so that all the rendered stuff appears on the texture.
+    context->grContext()->flush();
 }
+#endif // USE(SKIA)
 
-void LayerTextureUpdaterSkPicture::deleteFrameBuffer()
-{
-    m_canvas.clear();
-
-    if (m_depthStencilBuffer) {
-        context()->deleteRenderbuffer(m_depthStencilBuffer);
-        m_depthStencilBuffer = 0;
-    }
-    if (m_fbo) {
-        context()->deleteFramebuffer(m_fbo);
-        m_fbo = 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;
-}
-#endif // USE(SKIA) && USE(ACCELERATED_DRAWING)
-
 } // namespace WebCore
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerTextureUpdaterCanvas.h (98276 => 98277)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerTextureUpdaterCanvas.h	2011-10-24 20:47:45 UTC (rev 98276)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerTextureUpdaterCanvas.h	2011-10-24 20:48:33 UTC (rev 98277)
@@ -79,7 +79,7 @@
     LayerTextureSubImage m_texSubImage;
 };
 
-#if USE(SKIA) && USE(ACCELERATED_DRAWING)
+#if USE(SKIA)
 class LayerTextureUpdaterSkPicture : public LayerTextureUpdaterCanvas {
 public:
     static PassRefPtr<LayerTextureUpdaterSkPicture> create(PassOwnPtr<LayerPainterChromium>);
@@ -92,20 +92,10 @@
 
 private:
     explicit LayerTextureUpdaterSkPicture(PassOwnPtr<LayerPainterChromium>);
-    void deleteFrameBuffer();
-    bool createFrameBuffer();
-    GraphicsContext3D* context() { return m_context; }
-
-    GraphicsContext3D* m_context;
-
-    bool m_createFrameBuffer; // Need to create FBO if true.
+  
     SkPicture m_picture; // Recording canvas.
-    IntSize m_bufferSize; // Frame buffer size.
-    Platform3DObject m_fbo; // Frame buffer id.
-    Platform3DObject m_depthStencilBuffer;
-    OwnPtr<SkCanvas> m_canvas; // GPU accelerated canvas.
 };
-#endif // USE(SKIA) && USE(ACCELERATED_DRAWING)
+#endif // USE(SKIA)
 
 } // namespace WebCore
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (98276 => 98277)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2011-10-24 20:47:45 UTC (rev 98276)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2011-10-24 20:48:33 UTC (rev 98277)
@@ -65,8 +65,6 @@
 {
     TRACE_EVENT("CCLayerTreeHost::initialize", this, 0);
     if (m_settings.enableCompositorThread) {
-        // Accelerated Painting is not supported in threaded mode. Turn it off.
-        m_settings.acceleratePainting = false;
         // The HUD does not work in threaded mode. Turn it off.
         m_settings.showFPSCounter = false;
         m_settings.showPlatformLayerTree = false;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to