Title: [101908] trunk/Source/WebCore
Revision
101908
Author
commit-qu...@webkit.org
Date
2011-12-02 22:14:08 -0800 (Fri, 02 Dec 2011)

Log Message

[chromium] Scissor rect optimization for chromium compositor
https://bugs.webkit.org/show_bug.cgi?id=67341

Patch by Shawn Singh <shawnsi...@chromium.org> on 2011-12-02
Reviewed by James Robinson.

Mostly covered by damage tracker tests. Currently this relies on
manually running layout tests, because this patch requires partial
swaps that are not supported by DumpRenderTree. The feature
automatically disables if partial swap is not supported.

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::initialize):
(WebCore::LayerRendererChromium::trackDamageForAllSurfaces):
(WebCore::LayerRendererChromium::drawLayersOntoRenderSurfaces):
(WebCore::LayerRendererChromium::drawLayersInternal):
(WebCore::LayerRendererChromium::swapBuffers):
(WebCore::LayerRendererChromium::drawLayer):
* platform/graphics/chromium/LayerRendererChromium.h:
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore::CCSettings::CCSettings):
(WebCore::LayerRendererCapabilities::LayerRendererCapabilities):
* platform/graphics/chromium/cc/CCRenderSurface.cpp:
(WebCore::CCRenderSurface::draw):
* platform/graphics/chromium/cc/CCRenderSurface.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (101907 => 101908)


--- trunk/Source/WebCore/ChangeLog	2011-12-03 06:06:56 UTC (rev 101907)
+++ trunk/Source/WebCore/ChangeLog	2011-12-03 06:14:08 UTC (rev 101908)
@@ -1,3 +1,30 @@
+2011-12-02  Shawn Singh  <shawnsi...@chromium.org>
+
+        [chromium] Scissor rect optimization for chromium compositor
+        https://bugs.webkit.org/show_bug.cgi?id=67341
+
+        Reviewed by James Robinson.
+
+        Mostly covered by damage tracker tests. Currently this relies on
+        manually running layout tests, because this patch requires partial
+        swaps that are not supported by DumpRenderTree. The feature
+        automatically disables if partial swap is not supported.
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::initialize):
+        (WebCore::LayerRendererChromium::trackDamageForAllSurfaces):
+        (WebCore::LayerRendererChromium::drawLayersOntoRenderSurfaces):
+        (WebCore::LayerRendererChromium::drawLayersInternal):
+        (WebCore::LayerRendererChromium::swapBuffers):
+        (WebCore::LayerRendererChromium::drawLayer):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        (WebCore::CCSettings::CCSettings):
+        (WebCore::LayerRendererCapabilities::LayerRendererCapabilities):
+        * platform/graphics/chromium/cc/CCRenderSurface.cpp:
+        (WebCore::CCRenderSurface::draw):
+        * platform/graphics/chromium/cc/CCRenderSurface.h:
+
 2011-12-02  Dmitry Lomov  <dslo...@google.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=73691

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (101907 => 101908)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-12-03 06:06:56 UTC (rev 101907)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2011-12-03 06:14:08 UTC (rev 101908)
@@ -53,6 +53,7 @@
 #include "TrackingTextureAllocator.h"
 #include "TreeSynchronizer.h"
 #include "WebGLLayerChromium.h"
+#include "cc/CCDamageTracker.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCLayerTreeHostCommon.h"
 #include "cc/CCProxy.h"
@@ -107,6 +108,21 @@
     return screen;
 }
 
+static TransformationMatrix computeScreenSpaceTransformForSurface(CCLayerImpl* renderSurfaceLayer)
+{
+    // The layer's screen space transform can be written as:
+    //   layerScreenSpaceTransform = surfaceScreenSpaceTransform * layerOriginTransform
+    // So, to compute the surface screen space, we can do:
+    //   surfaceScreenSpaceTransform = layerScreenSpaceTransform * inverse(layerOriginTransform)
+
+    TransformationMatrix layerOriginTransform = renderSurfaceLayer->drawTransform();
+    layerOriginTransform.translate(-0.5 * renderSurfaceLayer->bounds().width(), -0.5 * renderSurfaceLayer->bounds().height());
+    TransformationMatrix surfaceScreenSpaceTransform = renderSurfaceLayer->screenSpaceTransform();
+    surfaceScreenSpaceTransform.multiply(layerOriginTransform.inverse());
+
+    return surfaceScreenSpaceTransform;
+}
+
 #if USE(SKIA)
 bool contextSupportsAcceleratedPainting(GraphicsContext3D* context)
 {
@@ -191,9 +207,12 @@
     if (m_capabilities.contextHasCachedFrontBuffer)
         extensions->ensureEnabled("GL_CHROMIUM_front_buffer_cached");
 
-    m_capabilities.usingPostSubBuffer = extensions->supports("GL_CHROMIUM_post_sub_buffer");
-    if (m_capabilities.usingPostSubBuffer)
+    m_capabilities.usingPartialSwap = extensions->supports("GL_CHROMIUM_post_sub_buffer");
+    if (m_capabilities.usingPartialSwap)
         extensions->ensureEnabled("GL_CHROMIUM_post_sub_buffer");
+    // FIXME: eventually we would like to have usingPartialSwap enabled by default,
+    //        whenever it is supported. For now, we force it off.
+    m_capabilities.usingPartialSwap = false;
 
     m_capabilities.usingMapSub = extensions->supports("GL_CHROMIUM_map_sub");
     if (m_capabilities.usingMapSub)
@@ -317,10 +336,30 @@
         copyOffscreenTextureToDisplay();
 }
 
+void LayerRendererChromium::trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList)
+{
+    // For now, we use damage tracking to compute a global scissor. To do this, we must
+    // compute all damage tracking before drawing anything, so that we know the root
+    // damage rect. The root damage rect is then used to scissor each surface.
+
+    ASSERT(m_capabilities.usingPartialSwap);
+
+    for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
+        CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
+        CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
+        ASSERT(renderSurface);
+        renderSurface->damageTracker()->updateDamageRectForNextFrame(renderSurface->layerList(), renderSurfaceLayer->id(), renderSurfaceLayer->maskLayer());
+    }
+}
+
 void LayerRendererChromium::drawLayersOntoRenderSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList)
 {
     TRACE_EVENT("LayerRendererChromium::drawLayersOntoRenderSurfaces", this, 0);
 
+    if (m_capabilities.usingPartialSwap)
+        trackDamageForAllSurfaces(rootDrawLayer, renderSurfaceLayerList);
+    m_rootDamageRect = rootDrawLayer->renderSurface()->damageTracker()->currentDamageRect();
+
     // Update the contents of the render surfaces. We traverse the render surfaces
     // from back to front to guarantee that nested render surfaces get rendered in
     // the correct order.
@@ -332,16 +371,31 @@
 
         if (useRenderSurface(renderSurface)) {
 
+            FloatRect surfaceDamageRect;
+            if (m_capabilities.usingPartialSwap) {
+                // For now, we conservatively use the root damage as the damage for all
+                // surfaces, except perspective transforms.
+                TransformationMatrix screenSpaceTransform = computeScreenSpaceTransformForSurface(renderSurfaceLayer);
+                if (screenSpaceTransform.hasPerspective()) {
+                    // Perspective projections do not play nice with mapRect of inverse transforms.
+                    // In this uncommon case, its simpler to just redraw the entire surface.
+                    surfaceDamageRect = renderSurface->contentRect();
+                } else {
+                    TransformationMatrix inverseScreenSpaceTransform = screenSpaceTransform.inverse();
+                    surfaceDamageRect = inverseScreenSpaceTransform.mapRect(m_rootDamageRect);
+                }
+            }
+
             if (renderSurfaceLayer != rootDrawLayer) {
-                GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
+                if (m_capabilities.usingPartialSwap)
+                    setScissorToRect(enclosingIntRect(surfaceDamageRect));
                 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
                 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
-                GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
             }
 
             const CCLayerList& layerList = renderSurface->layerList();
             for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
-                drawLayer(layerList[layerIndex].get(), renderSurface);
+                drawLayer(layerList[layerIndex].get(), renderSurface, surfaceDamageRect);
         }
     }
 
@@ -392,20 +446,20 @@
     // Bind the common vertex attributes used for drawing all the layers.
     m_sharedGeometry->prepareForDraw();
 
-    GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
     GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
     GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
 
     useRenderSurface(m_defaultRenderSurface);
 
     // Clear to blue to make it easier to spot unrendered regions.
+    if (m_capabilities.usingPartialSwap)
+        setScissorToRect(enclosingIntRect(m_rootDamageRect));
     m_context->clearColor(0, 0, 1, 1);
     m_context->colorMask(true, true, true, true);
     m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
 
     GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
     GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
-    GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
 
     drawLayersOntoRenderSurfaces(rootDrawLayer, renderSurfaceLayerList);
 
@@ -487,9 +541,17 @@
     TRACE_EVENT("LayerRendererChromium::swapBuffers", this, 0);
     // We're done! Time to swapbuffers!
 
-    // Note that currently this has the same effect as swapBuffers; we should
-    // consider exposing a different entry point on GraphicsContext3D.
-    m_context->prepareTexture();
+    if (m_capabilities.usingPartialSwap) {
+        // If supported, we can save significant bandwidth by only swapping the damaged/scissored region (clamped to the viewport)
+        IntRect subBuffer = enclosingIntRect(m_rootDamageRect);
+        subBuffer.intersect(IntRect(IntPoint::zero(), viewportSize()));
+        Extensions3DChromium* extensions3DChromium = static_cast<Extensions3DChromium*>(m_context->getExtensions());
+        int flippedYPosOfRectBottom = viewportHeight() - subBuffer.y() - subBuffer.height();
+        extensions3DChromium->postSubBufferCHROMIUM(subBuffer.x(), flippedYPosOfRectBottom, subBuffer.width(), subBuffer.height());
+    } else
+        // Note that currently this has the same effect as swapBuffers; we should
+        // consider exposing a different entry point on GraphicsContext3D.
+        m_context->prepareTexture();
 
     m_headsUpDisplay->onSwapBuffers();
 }
@@ -582,10 +644,10 @@
     return true;
 }
 
-void LayerRendererChromium::drawLayer(CCLayerImpl* layer, CCRenderSurface* targetSurface)
+void LayerRendererChromium::drawLayer(CCLayerImpl* layer, CCRenderSurface* targetSurface, const FloatRect& surfaceDamageRect)
 {
     if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<CCLayerImpl>(layer, targetSurface->owningLayerId())) {
-        layer->renderSurface()->draw(this, layer->getDrawRect());
+        layer->renderSurface()->draw(this, surfaceDamageRect);
         layer->renderSurface()->releaseContentsTexture();
         return;
     }
@@ -593,7 +655,13 @@
     if (layer->visibleLayerRect().isEmpty())
         return;
 
-    if (layer->usesLayerClipping())
+    if (layer->usesLayerClipping() && m_capabilities.usingPartialSwap) {
+        FloatRect clipAndDamageRect(layer->clipRect());
+        clipAndDamageRect.intersect(surfaceDamageRect);
+        setScissorToRect(enclosingIntRect(clipAndDamageRect));
+    } else if (m_capabilities.usingPartialSwap)
+        setScissorToRect(enclosingIntRect(surfaceDamageRect));
+    else if (layer->usesLayerClipping())
         setScissorToRect(layer->clipRect());
     else
         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h (101907 => 101908)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h	2011-12-03 06:06:56 UTC (rev 101907)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h	2011-12-03 06:14:08 UTC (rev 101908)
@@ -165,8 +165,10 @@
 
     void drawLayersInternal();
     void drawLayersOntoRenderSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
-    void drawLayer(CCLayerImpl*, CCRenderSurface*);
+    void drawLayer(CCLayerImpl*, CCRenderSurface*, const FloatRect&);
 
+    void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList);
+
     ManagedTexture* getOffscreenLayerTexture();
     void copyOffscreenTextureToDisplay();
 
@@ -243,6 +245,8 @@
     FloatQuad m_sharedGeometryQuad;
 
     bool m_isViewportChanged;
+
+    FloatRect m_rootDamageRect;
 };
 
 // Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (101907 => 101908)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h	2011-12-03 06:06:56 UTC (rev 101907)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h	2011-12-03 06:14:08 UTC (rev 101908)
@@ -73,14 +73,12 @@
             , compositeOffscreen(false)
             , showFPSCounter(false)
             , showPlatformLayerTree(false)
-            , useDamageTracker(false)
             , refreshRate(0) { }
 
     bool acceleratePainting;
     bool compositeOffscreen;
     bool showFPSCounter;
     bool showPlatformLayerTree;
-    bool useDamageTracker;
     double refreshRate;
 };
 
@@ -89,7 +87,7 @@
     LayerRendererCapabilities()
         : bestTextureFormat(0)
         , contextHasCachedFrontBuffer(false)
-        , usingPostSubBuffer(false)
+        , usingPartialSwap(false)
         , usingMapSub(false)
         , usingAcceleratedPainting(false)
         , usingSetVisibility(false)
@@ -98,7 +96,7 @@
 
     GC3Denum bestTextureFormat;
     bool contextHasCachedFrontBuffer;
-    bool usingPostSubBuffer;
+    bool usingPartialSwap;
     bool usingMapSub;
     bool usingAcceleratedPainting;
     bool usingSetVisibility;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp (101907 => 101908)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp	2011-12-03 06:06:56 UTC (rev 101907)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp	2011-12-03 06:14:08 UTC (rev 101908)
@@ -101,7 +101,7 @@
     m_contentsTexture->unreserve();
 }
 
-void CCRenderSurface::draw(LayerRendererChromium* layerRenderer, const IntRect&)
+void CCRenderSurface::draw(LayerRendererChromium* layerRenderer, const FloatRect& surfaceDamageRect)
 {
     if (m_skipsDraw || !m_contentsTexture)
         return;
@@ -115,7 +115,13 @@
     if (!m_maskLayer && m_owningLayer->replicaLayer())
         replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer();
 
-    if (m_owningLayer->parent() && m_owningLayer->parent()->usesLayerClipping())
+    if (m_owningLayer->parent() && m_owningLayer->parent()->usesLayerClipping() && layerRenderer->capabilities().usingPartialSwap) {
+        FloatRect clipAndDamageRect = m_clipRect;
+        clipAndDamageRect.intersect(surfaceDamageRect);
+        layerRenderer->setScissorToRect(enclosingIntRect(clipAndDamageRect));
+    } else if (layerRenderer->capabilities().usingPartialSwap)
+        layerRenderer->setScissorToRect(enclosingIntRect(surfaceDamageRect));
+    else if (m_owningLayer->parent() && m_owningLayer->parent()->usesLayerClipping())
         layerRenderer->setScissorToRect(m_clipRect);
     else
         GLC(layerRenderer->context(), layerRenderer->context()->disable(GraphicsContext3D::SCISSOR_TEST));

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h (101907 => 101908)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h	2011-12-03 06:06:56 UTC (rev 101907)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h	2011-12-03 06:14:08 UTC (rev 101908)
@@ -54,7 +54,7 @@
     bool prepareContentsTexture(LayerRendererChromium*);
     void releaseContentsTexture();
     void cleanupResources();
-    void draw(LayerRendererChromium*, const IntRect& targetSurfaceRect);
+    void draw(LayerRendererChromium*, const FloatRect& surfaceDamageRect);
 
     String name() const;
     void dumpSurface(TextStream&, int indent) const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to