[Chromium] Enable deferred canvas rendering in the skia port
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Feb 2012 23:05:31 +0000 (23:05 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Feb 2012 23:05:31 +0000 (23:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76732

Patch by Justin Novosad <junov@chromium.org> on 2012-02-01
Reviewed by Stephen White.

Source/WebCore:

No new tests: covered by existing canvas layout tests

Adding a new setting to enable deferred 2d canvas rendering.
Added support for deferred 2d canvas rendering in ImageBufferSkia
and Canvas2DLayerChromium, mostly plumbing. Deffered rendering
implementation is provided by skia (class SkDeferredCanvas).

* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::shouldDefer):
(WebCore):
(WebCore::HTMLCanvasElement::createImageBuffer):
* html/HTMLCanvasElement.h:
(HTMLCanvasElement):
* page/Settings.cpp:
(WebCore::Settings::Settings):
(WebCore::Settings::setAccelerated2dCanvasEnabled):
(WebCore):
(WebCore::Settings::setDeferred2dCanvasEnabled):
* page/Settings.h:
(Settings):
(WebCore::Settings::deferred2dCanvasEnabled):
* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::create):
(ImageBuffer):
* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/chromium/Canvas2DLayerChromium.cpp:
(WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
(WebCore):
(WebCore::Canvas2DLayerChromium::setCanvas):
(WebCore::Canvas2DLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/Canvas2DLayerChromium.h:
(Canvas2DLayerChromium):
* platform/graphics/qt/ImageBufferQt.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/skia/ImageBufferSkia.cpp:
(AcceleratedDeviceContext):
(WebCore::AcceleratedDeviceContext::AcceleratedDeviceContext):
(WebCore::AcceleratedDeviceContext::prepareForDraw):
(WebCore::AcceleratedDeviceContext::flush):
(WebCore):
(WebCore::createAcceleratedCanvas):
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/wince/ImageBufferWinCE.cpp:
(WebCore::ImageBuffer::ImageBuffer):
* platform/graphics/wx/ImageBufferWx.cpp:
(WebCore::ImageBuffer::ImageBuffer):

Source/WebKit/chromium:

Adding a new setting for enabling deferred 2d canvas rendering

* public/WebSettings.h:
* src/WebSettingsImpl.cpp:
(WebKit::WebSettingsImpl::setDeferred2dCanvasEnabled):
(WebKit):
* src/WebSettingsImpl.h:
(WebSettingsImpl):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106500 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLCanvasElement.cpp
Source/WebCore/html/HTMLCanvasElement.h
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.h
Source/WebCore/platform/graphics/ImageBuffer.h
Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
Source/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp
Source/WebCore/platform/graphics/wx/ImageBufferWx.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebSettings.h
Source/WebKit/chromium/src/WebSettingsImpl.cpp
Source/WebKit/chromium/src/WebSettingsImpl.h

index 78b4ca4..81d331b 100644 (file)
@@ -1,3 +1,60 @@
+2012-02-01  Justin Novosad  <junov@chromium.org>
+
+        [Chromium] Enable deferred canvas rendering in the skia port
+        https://bugs.webkit.org/show_bug.cgi?id=76732
+
+        Reviewed by Stephen White.
+
+        No new tests: covered by existing canvas layout tests
+
+        Adding a new setting to enable deferred 2d canvas rendering.
+        Added support for deferred 2d canvas rendering in ImageBufferSkia
+        and Canvas2DLayerChromium, mostly plumbing. Deffered rendering
+        implementation is provided by skia (class SkDeferredCanvas).
+
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::HTMLCanvasElement::shouldDefer):
+        (WebCore):
+        (WebCore::HTMLCanvasElement::createImageBuffer):
+        * html/HTMLCanvasElement.h:
+        (HTMLCanvasElement):
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+        (WebCore::Settings::setAccelerated2dCanvasEnabled):
+        (WebCore):
+        (WebCore::Settings::setDeferred2dCanvasEnabled):
+        * page/Settings.h:
+        (Settings):
+        (WebCore::Settings::deferred2dCanvasEnabled):
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::create):
+        (ImageBuffer):
+        * platform/graphics/cairo/ImageBufferCairo.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+        (WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
+        (WebCore):
+        (WebCore::Canvas2DLayerChromium::setCanvas):
+        (WebCore::Canvas2DLayerChromium::paintContentsIfDirty):
+        * platform/graphics/chromium/Canvas2DLayerChromium.h:
+        (Canvas2DLayerChromium):
+        * platform/graphics/qt/ImageBufferQt.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (AcceleratedDeviceContext):
+        (WebCore::AcceleratedDeviceContext::AcceleratedDeviceContext):
+        (WebCore::AcceleratedDeviceContext::prepareForDraw):
+        (WebCore::AcceleratedDeviceContext::flush):
+        (WebCore):
+        (WebCore::createAcceleratedCanvas):
+        (WebCore::ImageBuffer::ImageBuffer):
+        * platform/graphics/wince/ImageBufferWinCE.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+        * platform/graphics/wx/ImageBufferWx.cpp:
+        (WebCore::ImageBuffer::ImageBuffer):
+
 2012-02-01  Ryosuke Niwa  <rniwa@webkit.org>
 
         Gcc build fix after r106482.
index 681fb93..143d334 100644 (file)
@@ -443,6 +443,22 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
 #endif
 }
 
+bool HTMLCanvasElement::shouldDefer() const
+{
+#if USE(SKIA)
+    if (m_context && !m_context->is2d())
+        return false;
+
+    Settings* settings = document()->settings();
+    if (!settings || !settings->deferred2dCanvasEnabled())
+        return false;
+
+    return true;
+#else
+    return false;
+#endif
+}
+
 void HTMLCanvasElement::createImageBuffer() const
 {
     ASSERT(!m_imageBuffer);
@@ -471,7 +487,8 @@ void HTMLCanvasElement::createImageBuffer() const
 #else
         Unaccelerated;
 #endif
-    m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode);
+    DeferralMode deferralMode = shouldDefer() ? Deferred : NonDeferred;
+    m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode, deferralMode);
     if (!m_imageBuffer)
         return;
     m_imageBuffer->context()->scale(FloatSize(bufferSize.width() / logicalSize.width(), bufferSize.height() / logicalSize.height()));
index 1bfe52c..0493902 100644 (file)
@@ -146,6 +146,8 @@ private:
 
     void setSurfaceSize(const IntSize&);
 
+    bool shouldDefer() const;
+
     HashSet<CanvasObserver*> m_observers;
 
     IntSize m_size;
index 1861660..599cb31 100644 (file)
@@ -193,6 +193,7 @@ Settings::Settings(Page* page)
     , m_privilegedWebGLExtensionsEnabled(false)
     , m_webAudioEnabled(false)
     , m_acceleratedCanvas2dEnabled(false)
+    , m_deferredCanvas2dEnabled(false)
     , m_loadDeferringEnabled(true)
     , m_tiledBackingStoreEnabled(false)
     , m_paginateDuringLayoutEnabled(false)
@@ -817,6 +818,11 @@ void Settings::setAccelerated2dCanvasEnabled(bool enabled)
     m_acceleratedCanvas2dEnabled = enabled;
 }
 
+void Settings::setDeferred2dCanvasEnabled(bool enabled)
+{
+    m_deferredCanvas2dEnabled = enabled;
+}
+
 void Settings::setMinimumAccelerated2dCanvasSize(int numPixels)
 {
     m_minimumAccelerated2dCanvasSize = numPixels;
index 8e4d91d..5ef8eea 100644 (file)
@@ -366,6 +366,9 @@ namespace WebCore {
         void setAccelerated2dCanvasEnabled(bool);
         bool accelerated2dCanvasEnabled() const { return m_acceleratedCanvas2dEnabled; }
 
+        void setDeferred2dCanvasEnabled(bool);
+        bool deferred2dCanvasEnabled() const { return m_deferredCanvas2dEnabled; }
+
         // Number of pixels below which 2D canvas is rendered in software
         // even if hardware acceleration is enabled.
         // Hardware acceleration is useful for large canvases where it can avoid the
@@ -619,6 +622,7 @@ namespace WebCore {
         bool m_privilegedWebGLExtensionsEnabled : 1;
         bool m_webAudioEnabled : 1;
         bool m_acceleratedCanvas2dEnabled : 1;
+        bool m_deferredCanvas2dEnabled : 1;
         bool m_loadDeferringEnabled : 1;
         bool m_tiledBackingStoreEnabled : 1;
         bool m_paginateDuringLayoutEnabled : 1;
index 1307000..ebc5bfa 100644 (file)
@@ -68,14 +68,19 @@ namespace WebCore {
         DontCopyBackingStore // Subsequent draws may affect the copy.
     };
 
+    enum DeferralMode {
+        NonDeferred,
+        Deferred
+    };
+
     class ImageBuffer {
         WTF_MAKE_NONCOPYABLE(ImageBuffer); WTF_MAKE_FAST_ALLOCATED;
     public:
         // Will return a null pointer on allocation failure.
-        static PassOwnPtr<ImageBuffer> create(const IntSize& size, ColorSpace colorSpace = ColorSpaceDeviceRGB, RenderingMode renderingMode = Unaccelerated)
+        static PassOwnPtr<ImageBuffer> create(const IntSize& size, ColorSpace colorSpace = ColorSpaceDeviceRGB, RenderingMode renderingMode = Unaccelerated, DeferralMode deferralMode = NonDeferred)
         {
             bool success = false;
-            OwnPtr<ImageBuffer> buf = adoptPtr(new ImageBuffer(size, colorSpace, renderingMode, success));
+            OwnPtr<ImageBuffer> buf = adoptPtr(new ImageBuffer(size, colorSpace, renderingMode, deferralMode, success));
             if (success)
                 return buf.release();
             return nullptr;
@@ -143,7 +148,7 @@ namespace WebCore {
 
         // This constructor will place its success into the given out-variable
         // so that create() knows when it should return failure.
-        ImageBuffer(const IntSize&, ColorSpace, RenderingMode, bool& success);
+        ImageBuffer(const IntSize&, ColorSpace, RenderingMode, DeferralMode, bool& success);
     };
 
 #if USE(CG) || USE(SKIA)
index 81c5ae4..f4d2ea2 100644 (file)
@@ -54,7 +54,7 @@ ImageBufferData::ImageBufferData(const IntSize& size)
 {
 }
 
-ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, DeferralMode, bool& success)
     : m_data(size)
     , m_size(size)
 {
index d896419..02ba8cf 100644 (file)
@@ -107,7 +107,7 @@ static void releaseImageData(void*, const void* data, size_t)
     fastFree(const_cast<void*>(data));
 }
 
-ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace imageColorSpace, RenderingMode renderingMode, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace imageColorSpace, RenderingMode renderingMode, DeferralMode, bool& success)
     : m_data(size)
     , m_size(size)
 {
index 0905474..6c778bf 100644 (file)
@@ -41,9 +41,9 @@
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h" // For the GLC() macro
 
-#if USE(SKIA)
 #include "GrContext.h"
-#endif
+#include "SkCanvas.h"
+#include "SkDevice.h"
 
 namespace WebCore {
 
@@ -59,6 +59,7 @@ Canvas2DLayerChromium::Canvas2DLayerChromium(GraphicsContext3D* context, const I
     , m_backTextureId(0)
     , m_fbo(0)
     , m_useDoubleBuffering(CCProxy::hasImplThread())
+    , m_canvas(0)
 {
     if (m_useDoubleBuffering)
         GLC(m_context, m_fbo = m_context->createFramebuffer());
@@ -91,6 +92,11 @@ bool Canvas2DLayerChromium::drawsContent() const
         && m_context && (m_context->getExtensions()->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR);
 }
 
+void Canvas2DLayerChromium::setCanvas(SkCanvas* canvas)
+{
+    m_canvas = canvas;
+}
+
 void Canvas2DLayerChromium::paintContentsIfDirty(const Region& /* occludedScreenSpace */)
 {
     if (!drawsContent())
@@ -107,11 +113,15 @@ void Canvas2DLayerChromium::paintContentsIfDirty(const Region& /* occludedScreen
     bool success = m_context->makeContextCurrent();
     ASSERT_UNUSED(success, success);
 
-#if USE(SKIA)
+    // FIXME: Replace this block of skia code with m_canvas->flush, when that
+    // API becomes available.
+    // https://bugs.webkit.org/show_bug.cgi?id=77463
+    if (m_canvas)
+        m_canvas->getDevice()->accessRenderTarget(); // Triggers execution of pending draw operations.
+
     GrContext* grContext = m_context->grContext();
     if (grContext)
         grContext->flush();
-#endif
 
     m_context->flush();
 }
index ecba90f..877224f 100644 (file)
@@ -37,6 +37,8 @@
 #include "CanvasLayerChromium.h"
 #include "ManagedTexture.h"
 
+class SkCanvas;
+
 namespace WebCore {
 
 class GraphicsContext3D;
@@ -61,6 +63,8 @@ public:
     virtual void unreserveContentsTexture();
     virtual void cleanupResources();
 
+    void setCanvas(SkCanvas*);
+
 private:
     Canvas2DLayerChromium(GraphicsContext3D*, const IntSize&);
 
@@ -77,6 +81,7 @@ private:
     // synchronize its draws with the canvas updates.
     bool m_useDoubleBuffering;
     OwnPtr<ManagedTexture> m_frontTexture;
+    SkCanvas* m_canvas;
 };
 
 }
index 919cba3..e36ff85 100644 (file)
@@ -94,7 +94,7 @@ QImage ImageBufferData::toQImage() const
     return image;
 }
 
-ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, DeferralMode, bool& success)
     : m_data(size)
     , m_size(size)
 {
index ef0a933..eaa1d77 100644 (file)
@@ -46,6 +46,7 @@
 #include "PlatformContextSkia.h"
 #include "SharedGraphicsContext3D.h"
 #include "SkColorPriv.h"
+#include "SkDeferredCanvas.h"
 #include "SkGpuDevice.h"
 #include "SkiaUtils.h"
 #include "WEBPImageEncoder.h"
@@ -65,7 +66,29 @@ ImageBufferData::ImageBufferData(const IntSize& size)
 {
 }
 
-static SkCanvas* createAcceleratedCanvas(const IntSize& size, ImageBufferData* data)
+class AcceleratedDeviceContext : public SkDeferredCanvas::DeviceContext {
+public:
+    AcceleratedDeviceContext(GraphicsContext3D* context3D)
+    {
+        ASSERT(context3D);
+        m_context3D = context3D;
+    }
+
+    virtual void prepareForDraw()
+    {
+        m_context3D->makeContextCurrent();
+    }
+
+    virtual void flush()
+    {
+        m_context3D->flush();
+    }
+
+private:
+    GraphicsContext3D* m_context3D;
+};
+
+static SkCanvas* createAcceleratedCanvas(const IntSize& size, ImageBufferData* data, DeferralMode deferralMode)
 {
     GraphicsContext3D* context3D = SharedGraphicsContext3D::get();
     if (!context3D)
@@ -83,12 +106,18 @@ static SkCanvas* createAcceleratedCanvas(const IntSize& size, ImageBufferData* d
     SkAutoTUnref<GrTexture> texture(gr->createUncachedTexture(desc, 0, 0));
     if (!texture.get())
         return 0;
-    SkCanvas* canvas = new SkCanvas();
-    canvas->setDevice(new SkGpuDevice(gr, texture.get()))->unref();
+    SkCanvas* canvas;
+    SkAutoTUnref<SkDevice> device(new SkGpuDevice(gr, texture.get()));
+    if (deferralMode == Deferred) {
+        SkAutoTUnref<AcceleratedDeviceContext> deviceContext(new AcceleratedDeviceContext(context3D));
+        canvas = new SkDeferredCanvas(device.get(), deviceContext.get());
+    } else
+        canvas = new SkCanvas(device.get());
     data->m_platformContext.setGraphicsContext3D(context3D);
 #if USE(ACCELERATED_COMPOSITING)
     data->m_platformLayer = Canvas2DLayerChromium::create(context3D, size);
     data->m_platformLayer->setTextureId(texture.get()->getTextureHandle());
+    data->m_platformLayer->setCanvas(canvas);
 #endif
     return canvas;
 }
@@ -100,14 +129,14 @@ static SkCanvas* createNonPlatformCanvas(const IntSize& size)
     return canvas;
 }
 
-ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode renderingMode, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode renderingMode, DeferralMode deferralMode, bool& success)
     : m_data(size)
     , m_size(size)
 {
     OwnPtr<SkCanvas> canvas;
 
     if (renderingMode == Accelerated)
-        canvas = adoptPtr(createAcceleratedCanvas(size, &m_data));
+        canvas = adoptPtr(createAcceleratedCanvas(size, &m_data, deferralMode));
     else if (renderingMode == UnacceleratedNonPlatformBuffer)
         canvas = adoptPtr(createNonPlatformCanvas(size));
 
index c1de965..39ef155 100644 (file)
@@ -72,7 +72,7 @@ ImageBufferData::ImageBufferData(const IntSize& size)
     m_bitmap->setHasAlpha(true);
 }
 
-ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace colorSpace, RenderingMode, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace colorSpace, RenderingMode, DeferralMode, bool& success)
     : m_data(size)
     , m_size(size)
 {
index d01391f..7c909b5 100644 (file)
@@ -37,7 +37,7 @@ ImageBufferData::ImageBufferData(const IntSize&)
 {
 }
 
-ImageBuffer::ImageBuffer(const IntSize&, ColorSpace imageColorSpace, RenderingMode, bool& success) : 
+ImageBuffer::ImageBuffer(const IntSize&, ColorSpace imageColorSpace, RenderingMode, DeferralMode, bool& success) : 
     m_data(IntSize())
 {
     notImplemented();
index 074b2d1..3e30cf3 100644 (file)
@@ -1,3 +1,19 @@
+2012-02-01  Justin Novosad  <junov@chromium.org>
+
+        [Chromium] Enable deferred canvas rendering in the skia port
+        https://bugs.webkit.org/show_bug.cgi?id=76732
+
+        Reviewed by Stephen White.
+
+        Adding a new setting for enabling deferred 2d canvas rendering
+
+        * public/WebSettings.h:
+        * src/WebSettingsImpl.cpp:
+        (WebKit::WebSettingsImpl::setDeferred2dCanvasEnabled):
+        (WebKit):
+        * src/WebSettingsImpl.h:
+        (WebSettingsImpl):
+
 2012-02-01  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r106382.
index ff789e6..b5da4e6 100644 (file)
@@ -115,6 +115,7 @@ public:
     virtual void setAcceleratedCompositingForPluginsEnabled(bool) = 0;
     virtual void setAcceleratedCompositingForAnimationEnabled(bool) = 0;
     virtual void setAccelerated2dCanvasEnabled(bool) = 0;
+    virtual void setDeferred2dCanvasEnabled(bool) = 0;
     virtual void setAcceleratedCompositingForFixedPositionEnabled(bool)  = 0;
     virtual void setMinimumAccelerated2dCanvasSize(int) = 0;
     virtual void setAcceleratedFiltersEnabled(bool) = 0;
index dbc023a..2723ca7 100644 (file)
@@ -373,6 +373,11 @@ void WebSettingsImpl::setAccelerated2dCanvasEnabled(bool enabled)
     m_settings->setAccelerated2dCanvasEnabled(enabled);
 }
 
+void WebSettingsImpl::setDeferred2dCanvasEnabled(bool enabled)
+{
+    m_settings->setDeferred2dCanvasEnabled(enabled);
+}
+
 void WebSettingsImpl::setAcceleratedCompositingForFixedPositionEnabled(bool enabled)
 {
     m_settings->setAcceleratedCompositingForFixedPositionEnabled(enabled);
index a82735a..63a00a0 100644 (file)
@@ -107,6 +107,7 @@ public:
     virtual void setAcceleratedCompositingForCanvasEnabled(bool);
     virtual void setAcceleratedCompositingForAnimationEnabled(bool);
     virtual void setAccelerated2dCanvasEnabled(bool);
+    virtual void setDeferred2dCanvasEnabled(bool);
     virtual void setAcceleratedCompositingForFixedPositionEnabled(bool);
     virtual void setMinimumAccelerated2dCanvasSize(int);
     virtual void setAcceleratedFiltersEnabled(bool);