[mac] ImageBuffer should create accelerated buffers for small canvases, but we should...
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jan 2013 23:34:57 +0000 (23:34 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Jan 2013 23:34:57 +0000 (23:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107804
<rdar://problem/11752381>

Reviewed by Simon Fraser.

Make all canvases IOSurface-backed if requested, instead of having a size threshold
under which we won't use accelerated canvas.

Make requiresCompositingForCanvas take the size of the canvas into account, using
the threshold which was previously in ImageBuffer to determine whether or not a
canvas should be forced into a compositing layer.

This improves canvas performance on some benchmarks
(http://www.mikechambers.com/html5/javascript/QuadTree/examples/collision.html, for example)
significantly, in cases where canvases which fall below the size limit
(and thus are unaccelerated) are being drawn rapidly into either accelerated
tiles or another accelerated canvas, by preventing excessive copying to/from the GPU.

* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore):
(WebCore::ImageBuffer::ImageBuffer):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingForCanvas):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp

index 04a7c64..4ba220b 100644 (file)
@@ -1,3 +1,30 @@
+2013-01-30  Tim Horton  <timothy_horton@apple.com>
+
+        [mac] ImageBuffer should create accelerated buffers for small canvases, but we shouldn't force them to create compositing layers
+        https://bugs.webkit.org/show_bug.cgi?id=107804
+        <rdar://problem/11752381>
+
+        Reviewed by Simon Fraser.
+
+        Make all canvases IOSurface-backed if requested, instead of having a size threshold
+        under which we won't use accelerated canvas.
+
+        Make requiresCompositingForCanvas take the size of the canvas into account, using
+        the threshold which was previously in ImageBuffer to determine whether or not a
+        canvas should be forced into a compositing layer.
+
+        This improves canvas performance on some benchmarks
+        (http://www.mikechambers.com/html5/javascript/QuadTree/examples/collision.html, for example)
+        significantly, in cases where canvases which fall below the size limit
+        (and thus are unaccelerated) are being drawn rapidly into either accelerated
+        tiles or another accelerated canvas, by preventing excessive copying to/from the GPU.
+
+        * platform/graphics/cg/ImageBufferCG.cpp:
+        (WebCore):
+        (WebCore::ImageBuffer::ImageBuffer):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::requiresCompositingForCanvas):
+
 2013-01-30  Alec Flett  <alecflett@chromium.org>
 
         IndexedDB: clean up scheduleTask return type
index 1d99e08..7e0434c 100644 (file)
@@ -62,7 +62,6 @@ namespace WebCore {
 
 #if USE(IOSURFACE_CANVAS_BACKING_STORE)
 static const int maxIOSurfaceDimension = 4096;
-static const int minIOSurfaceArea = 50 * 100;
 
 static RetainPtr<IOSurfaceRef> createIOSurface(const IntSize& size)
 {
@@ -136,7 +135,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace
         return;
 
 #if USE(IOSURFACE_CANVAS_BACKING_STORE)
-    if (width.unsafeGet() >= maxIOSurfaceDimension || height.unsafeGet() >= maxIOSurfaceDimension || (width * height).unsafeGet() < minIOSurfaceArea)
+    if (width.unsafeGet() >= maxIOSurfaceDimension || height.unsafeGet() >= maxIOSurfaceDimension)
         accelerateRendering = false;
 #else
     ASSERT(renderingMode == Unaccelerated);
index 7db0a1f..6b4b460 100644 (file)
 bool WebCoreHas3DRendering = true;
 #endif
 
+#if !PLATFORM(MAC) && !PLATFORM(IOS)
+#define WTF_USE_COMPOSITING_FOR_SMALL_CANVASES 1
+#endif
+
+static const int canvasAreaThresholdRequiringCompositing = 50 * 100;
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -1906,7 +1912,12 @@ bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer)
 
     if (renderer->isCanvas()) {
         HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
-        return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
+#if USE(COMPOSITING_FOR_SMALL_CANVASES)
+        bool isCanvasLargeEnoughToForceCompositing = true;
+#else
+        bool isCanvasLargeEnoughToForceCompositing = canvas->size().area() >= canvasAreaThresholdRequiringCompositing;
+#endif
+        return canvas->renderingContext() && canvas->renderingContext()->isAccelerated() && (canvas->renderingContext()->is3d() || isCanvasLargeEnoughToForceCompositing);
     }
     return false;
 }