[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

darin at chromium.org darin at chromium.org
Wed Dec 22 13:18:51 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit d89cb2eee5f74de0cf20e48cb0d24e9a1aad192b
Author: darin at chromium.org <darin at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Sep 10 22:33:14 2010 +0000

    2010-09-10  Nat Duca  <nduca at chromium.org>
    
            Reviewed by Darin Fisher.
    
            [chromium] Accelerated Compositing: screen garbage when scrolling
            https://bugs.webkit.org/show_bug.cgi?id=45092
    
            Split LayerRenderChromium::drawLayers into several different
            functions, responsible for preparing the backbuffer, updating the
            root texture, compositing and performing the final
            swapbuffers. This are then used by the new
            WebViewImpl::composite rendering path.
    
            * platform/graphics/chromium/LayerChromium.cpp:
            (WebCore::LayerChromium::setBounds):
            (WebCore::LayerChromium::setFrame):
            (WebCore::LayerChromium::setNeedsDisplay):
            (WebCore::LayerChromium::resetNeedsDisplay):
            * platform/graphics/chromium/LayerChromium.h:
            (WebCore::LayerChromium::dirtyRect):
            * platform/graphics/chromium/LayerRendererChromium.cpp:
            (WebCore::LayerRendererChromium::prepareToDrawLayers):
            (WebCore::LayerRendererChromium::updateRootLayerTextureRect):
            (WebCore::LayerRendererChromium::drawLayers):
            (WebCore::LayerRendererChromium::present):
            * platform/graphics/chromium/LayerRendererChromium.h:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b48908c..fb411e9 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,30 @@
+2010-09-10  Nat Duca  <nduca at chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        [chromium] Accelerated Compositing: screen garbage when scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=45092
+
+        Split LayerRenderChromium::drawLayers into several different
+        functions, responsible for preparing the backbuffer, updating the
+        root texture, compositing and performing the final
+        swapbuffers. This are then used by the new
+        WebViewImpl::composite rendering path.
+
+        * platform/graphics/chromium/LayerChromium.cpp:
+        (WebCore::LayerChromium::setBounds):
+        (WebCore::LayerChromium::setFrame):
+        (WebCore::LayerChromium::setNeedsDisplay):
+        (WebCore::LayerChromium::resetNeedsDisplay):
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore::LayerChromium::dirtyRect):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::prepareToDrawLayers):
+        (WebCore::LayerRendererChromium::updateRootLayerTextureRect):
+        (WebCore::LayerRendererChromium::drawLayers):
+        (WebCore::LayerRendererChromium::present):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+
 2010-09-10  David Holloway  <dhollowa at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 6519f1f..d6eef3a 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -299,10 +299,15 @@ void LayerChromium::setBounds(const IntSize& size)
     if (m_bounds == size)
         return;
 
+    bool firstResize = !m_bounds.width() && !m_bounds.height() && size.width() && size.height();
+
     m_bounds = size;
     m_backingStoreSize = size;
 
-    setNeedsCommit();
+    if (firstResize)
+        setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height()));
+    else
+        setNeedsCommit();
 }
 
 void LayerChromium::setFrame(const FloatRect& rect)
@@ -311,7 +316,7 @@ void LayerChromium::setFrame(const FloatRect& rect)
       return;
 
     m_frame = rect;
-    setNeedsCommit();
+    setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height()));
 }
 
 const LayerChromium* LayerChromium::rootLayer() const
@@ -353,7 +358,6 @@ void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
     m_contentsDirty = true;
 
     m_dirtyRect.unite(dirtyRect);
-
     setNeedsCommit();
 }
 
@@ -363,6 +367,12 @@ void LayerChromium::setNeedsDisplay()
     m_contentsDirty = true;
 }
 
+void LayerChromium::resetNeedsDisplay()
+{
+    m_dirtyRect = FloatRect();
+    m_contentsDirty = false;
+}
+
 void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m)
 {
     flattened[0] = m.m11();
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index ba15088..2d225da 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -112,6 +112,8 @@ public:
 
     void setNeedsDisplay(const FloatRect& dirtyRect);
     void setNeedsDisplay();
+    const FloatRect& dirtyRect() const { return m_dirtyRect; }
+    void resetNeedsDisplay();
 
     void setNeedsDisplayOnBoundsChange(bool needsDisplay) { m_needsDisplayOnBoundsChange = needsDisplay; }
 
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 4708310..8960841 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -156,8 +156,8 @@ void LayerRendererChromium::useShader(unsigned programId)
 
 // Updates the contents of the root layer texture that fall inside the updateRect
 // and re-composits all sublayers.
-void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect& visibleRect,
-                                       const IntRect& contentRect, const IntPoint& scrollPosition)
+void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, 
+                                                const IntPoint& scrollPosition)
 {
     ASSERT(m_hardwareCompositing);
 
@@ -197,14 +197,12 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
         m_scrollPosition = scrollPosition;
 
     IntPoint scrollDelta = toPoint(scrollPosition - m_scrollPosition);
-    // Scroll only when the updateRect contains pixels for the newly uncovered region to avoid flashing.
-    if ((scrollDelta.x() && updateRect.width() >= abs(scrollDelta.x()) && updateRect.height() >= contentRect.height())
-        || (scrollDelta.y() && updateRect.height() >= abs(scrollDelta.y()) && updateRect.width() >= contentRect.width())) {
+    // Scroll the backbuffer
+    if (scrollDelta.x() || scrollDelta.y()) {
         // Scrolling works as follows: We render a quad with the current root layer contents
         // translated by the amount the page has scrolled since the last update and then read the
         // pixels of the content area (visible area excluding the scroll bars) back into the
-        // root layer texture. The newly exposed area is subesquently filled as usual with
-        // the contents of the updateRect.
+        // root layer texture. The newly exposed area will be filled by a subsequent drawLayersIntoRect call
         TransformationMatrix scrolledLayerMatrix;
 #if PLATFORM(SKIA)
         float scaleFactor = 1.0f;
@@ -235,42 +233,65 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
         m_scrollPosition = scrollPosition;
     }
 
-    // FIXME: The following check should go away when the compositor renders independently from its own thread.
-    // Ignore a 1x1 update rect at (0, 0) as that's used a way to kick off a redraw for the compositor.
-    if (!(!updateRect.x() && !updateRect.y() && updateRect.width() == 1 && updateRect.height() == 1)) {
-        // Update the root layer texture.
-        ASSERT((updateRect.x() + updateRect.width() <= m_rootLayerTextureWidth)
-               && (updateRect.y() + updateRect.height() <= m_rootLayerTextureHeight));
+    // Translate all the composited layers by the scroll position.
+    TransformationMatrix matrix;
+    matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
+
+    // Traverse the layer tree and update the layer transforms.
+    float opacity = 1;
+    const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers();
+    size_t i;
+    for (i = 0; i < sublayers.size(); i++)
+        updateLayersRecursive(sublayers[i].get(), matrix, opacity);
+}
+
+void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect)
+{
+    ASSERT(m_hardwareCompositing);
+
+    if (!m_rootLayer)
+        return;
+
+    GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId));
+
+    // Update the root layer texture.
+    ASSERT((updateRect.right()  <= m_rootLayerTextureWidth)
+           && (updateRect.bottom() <= m_rootLayerTextureHeight));
 
 #if PLATFORM(SKIA)
-        // Get the contents of the updated rect.
-        const SkBitmap bitmap = m_rootLayerCanvas->getDevice()->accessBitmap(false);
-        int rootLayerWidth = bitmap.width();
-        int rootLayerHeight = bitmap.height();
-        ASSERT(rootLayerWidth == updateRect.width() && rootLayerHeight == updateRect.height());
-        void* pixels = bitmap.getPixels();
-
-        // Copy the contents of the updated rect to the root layer texture.
-        GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+    // Get the contents of the updated rect.
+    const SkBitmap bitmap = m_rootLayerCanvas->getDevice()->accessBitmap(false);
+    int bitmapWidth = bitmap.width();
+    int bitmapHeight = bitmap.height();
+    ASSERT(bitmapWidth == updateRect.width() && bitmapHeight == updateRect.height());
+    void* pixels = bitmap.getPixels();
+    // Copy the contents of the updated rect to the root layer texture.
+    GLC(glTexSubImage2D(GL_TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GL_RGBA, GL_UNSIGNED_BYTE, pixels));
 #elif PLATFORM(CG)
-        // Get the contents of the updated rect.
-        ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height());
-        void* pixels = m_rootLayerBackingStore.data();
-
-        // Copy the contents of the updated rect to the root layer texture.
-        // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
-        GLC(glTexSubImage2D(GL_TEXTURE_2D, 0,
-                            updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(),
-                            updateRect.width(), updateRect.height(),
-                            GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+    // Get the contents of the updated rect.
+    ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_rootLayerCGContext.get())) == updateRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_rootLayerCGContext.get())) == updateRect.height());
+    void* pixels = m_rootLayerBackingStore.data();
+
+    // Copy the contents of the updated rect to the root layer texture.
+    // The origin is at the lower left in Core Graphics' coordinate system. We need to correct for this here.
+    GLC(glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        updateRect.x(), m_rootLayerTextureHeight - updateRect.y() - updateRect.height(),
+                        updateRect.width(), updateRect.height(),
+                        GL_RGBA, GL_UNSIGNED_BYTE, pixels));
 #else
 #error "Need to implement for your platform."
 #endif
-    }
+}
+
+void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect)
+{
+    ASSERT(m_hardwareCompositing);
 
     glClearColor(0, 0, 1, 1);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
+    GLC(glBindTexture(GL_TEXTURE_2D, m_rootLayerTextureId));
+
     // Render the root layer using a quad that takes up the entire visible area of the window.
     // We reuse the shader program used by ContentLayerChromium.
     const ContentLayerChromium::SharedValues* contentLayerValues = contentLayerSharedValues();
@@ -294,6 +315,9 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
     GLC(glEnable(GL_BLEND));
     GLC(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
 
+    // Set the rootVisibleRect --- used by subsequent drawLayers calls
+    m_rootVisibleRect = visibleRect;
+
     // Translate all the composited layers by the scroll position.
     TransformationMatrix matrix;
     matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
@@ -305,11 +329,10 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
     for (i = 0; i < sublayers.size(); i++)
         updateLayersRecursive(sublayers[i].get(), matrix, opacity);
 
-    m_rootVisibleRect = visibleRect;
-
     // Enable scissoring to avoid rendering composited layers over the scrollbars.
     GLC(glEnable(GL_SCISSOR_TEST));
     FloatRect scissorRect(contentRect);
+
     // The scissorRect should not include the scroll offset.
     scissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y());
     scissorToRect(scissorRect);
@@ -320,13 +343,16 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
     GLC(glStencilMask(0));
 
     // Traverse the layer tree one more time to draw the layers.
-    for (i = 0; i < sublayers.size(); i++)
+    for (size_t i = 0; i < sublayers.size(); i++)
         drawLayersRecursive(sublayers[i].get(), scissorRect);
 
     GLC(glDisable(GL_SCISSOR_TEST));
+}
 
+void LayerRendererChromium::present()
+{
+    // We're done! Time to swapbuffers!
     m_gles2Context->swapBuffers();
-
     m_needsDisplay = false;
 }
 
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 8f44afe..274815f 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -61,9 +61,17 @@ public:
     LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context);
     ~LayerRendererChromium();
 
-    // Updates the contents of the root layer that fall inside the updateRect and recomposites
-    // all the layers.
-    void drawLayers(const IntRect& updateRect, const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition);
+    // updates size of root texture, if needed, and scrolls the backbuffer.
+    void prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition);
+
+    // updates a rectangle within the root layer texture
+    void updateRootLayerTextureRect(const IntRect& updateRect);
+
+    // draws the current layers onto the backbuffer
+    void drawLayers(const IntRect& visibleRect, const IntRect& contentRect);
+
+    // puts backbuffer onscreen
+    void present();
 
     void setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; }
     LayerChromium* rootLayer() { return m_rootLayer.get(); }
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 9d53d15..2b4b3db 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,46 @@
+2010-09-10  Nat Duca  <nduca at chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        [chromium] Accelerated Compositing: screen garbage when scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=45092
+
+        Introduce a new API on WebWidget for painting with accelerated
+        compositing that allows the compositor to properly distingiush
+        scrolling, invalidation and repainting from one another. The key
+        change is that in accelerated rendering case, invalidates and
+        scrolling pass directly to the compositor, rather than passing up
+        to the client as was the case in the software path. For
+        accelerated rendering, the previous paint() method is replaced by
+        composite().
+
+        * public/WebWidget.h:
+        * public/WebWidgetClient.h:
+        (WebKit::WebWidgetClient::scheduleComposite):
+        * src/ChromeClientImpl.cpp:
+        (WebKit::ChromeClientImpl::invalidateContentsAndWindow):
+        (WebKit::ChromeClientImpl::scroll):
+        * src/WebPopupMenuImpl.cpp:
+        (WebKit::WebPopupMenuImpl::themeChanged):
+        (WebKit::WebPopupMenuImpl::composite):
+        * src/WebPopupMenuImpl.h:
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::resize):
+        (WebKit::WebViewImpl::paint):
+        (WebKit::WebViewImpl::themeChanged):
+        (WebKit::WebViewImpl::composite):
+        (WebKit::WebViewImpl::setRootGraphicsLayer):
+        (WebKit::WebViewImpl::setRootLayerNeedsDisplay):
+        (WebKit::WebViewImpl::scrollRootLayerRect):
+        (WebKit::WebViewImpl::invalidateRootLayerRect):
+        (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+        (WebKit::WebViewImpl::updateRootLayerContents):
+        (WebKit::WebViewImpl::doComposite):
+        * src/WebViewImpl.h:
+        * tests/PopupMenuTest.cpp:
+        (WebKit::TestWebWidget::themeChanged):
+        (WebKit::TestWebWidget::composite):
+
 2010-09-10  David Holloway  <dhollowa at chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/WebKit/chromium/public/WebWidget.h b/WebKit/chromium/public/WebWidget.h
index 5c9f54e..d010270 100644
--- a/WebKit/chromium/public/WebWidget.h
+++ b/WebKit/chromium/public/WebWidget.h
@@ -60,13 +60,26 @@ public:
     // and it may result in calls to WebWidgetClient::didInvalidateRect.
     virtual void layout() = 0;
 
-    // Called to paint the specified region of the WebWidget onto the given
-    // canvas.  You MUST call Layout before calling this method.  It is
-    // okay to call paint multiple times once layout has been called,
-    // assuming no other changes are made to the WebWidget (e.g., once
-    // events are processed, it should be assumed that another call to
-    // layout is warranted before painting again).
-    virtual void paint(WebCanvas*, const WebRect&) = 0;
+    // Called to paint the rectangular region within the WebWidget 
+    // onto the specified canvas at (viewPort.x,viewPort.y). You MUST call
+    // Layout before calling this method.  It is okay to call paint
+    // multiple times once layout has been called, assuming no other
+    // changes are made to the WebWidget (e.g., once events are
+    // processed, it should be assumed that another call to layout is
+    // warranted before painting again).
+    virtual void paint(WebCanvas*, const WebRect& viewPort) = 0;
+
+    // Triggers compositing of the current layers onto the screen.
+    // The finish argument controls whether the compositor will wait for the
+    // GPU to finish rendering before returning. You MUST call Layout
+    // before calling this method, for the same reasons described in
+    // the paint method above.
+    virtual void composite(bool finish) = 0;
+
+    // Called to inform the WebWidget of a change in theme.
+    // Implementors that cache rendered copies of widgets need to re-render
+    // on receiving this message
+    virtual void themeChanged() = 0;
 
     // Called to inform the WebWidget of an input event.  Returns true if
     // the event has been processed, false otherwise.
diff --git a/WebKit/chromium/public/WebWidgetClient.h b/WebKit/chromium/public/WebWidgetClient.h
index bd7bd6a..9bd553f 100644
--- a/WebKit/chromium/public/WebWidgetClient.h
+++ b/WebKit/chromium/public/WebWidgetClient.h
@@ -50,6 +50,9 @@ public:
     // scrolled by the specified dx and dy amounts.
     virtual void didScrollRect(int dx, int dy, const WebRect& clipRect) { }
 
+    // Called when a call to WebWidget::composite is required
+    virtual void scheduleComposite() { }
+
     // Called when the widget acquires or loses focus, respectively.
     virtual void didFocus() { }
     virtual void didBlur() { }
diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp
index 8a3eda6..c662e60 100644
--- a/WebKit/chromium/src/ChromeClientImpl.cpp
+++ b/WebKit/chromium/src/ChromeClientImpl.cpp
@@ -493,8 +493,15 @@ void ChromeClientImpl::invalidateContentsAndWindow(const IntRect& updateRect, bo
 {
     if (updateRect.isEmpty())
         return;
-    if (m_webView->client())
-        m_webView->client()->didInvalidateRect(updateRect);
+#if USE(ACCELERATED_COMPOSITING)
+    if (!m_webView->isAcceleratedCompositingActive()) {
+#endif
+        if (m_webView->client())
+            m_webView->client()->didInvalidateRect(updateRect);
+#if USE(ACCELERATED_COMPOSITING)
+    } else
+        m_webView->invalidateRootLayerRect(updateRect);
+#endif
 }
 
 void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
@@ -508,11 +515,18 @@ void ChromeClientImpl::scroll(
     const IntRect& clipRect)
 {
     m_webView->hidePopups();
-    if (m_webView->client()) {
-        int dx = scrollDelta.width();
-        int dy = scrollDelta.height();
-        m_webView->client()->didScrollRect(dx, dy, clipRect);
-    }
+#if USE(ACCELERATED_COMPOSITING)
+    if (!m_webView->isAcceleratedCompositingActive()) {
+#endif
+        if (m_webView->client()) {
+            int dx = scrollDelta.width();
+            int dy = scrollDelta.height();
+            m_webView->client()->didScrollRect(dx, dy, clipRect);
+        }
+#if USE(ACCELERATED_COMPOSITING)
+    } else
+        m_webView->scrollRootLayerRect(scrollDelta, clipRect);
+#endif
 }
 
 IntPoint ChromeClientImpl::screenToWindow(const IntPoint&) const
diff --git a/WebKit/chromium/src/WebPopupMenuImpl.cpp b/WebKit/chromium/src/WebPopupMenuImpl.cpp
index 75d6cc1..085a157 100644
--- a/WebKit/chromium/src/WebPopupMenuImpl.cpp
+++ b/WebKit/chromium/src/WebPopupMenuImpl.cpp
@@ -174,6 +174,16 @@ void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect)
     }
 }
 
+void WebPopupMenuImpl::themeChanged()
+{
+    notImplemented();
+}
+
+void WebPopupMenuImpl::composite(bool finish)
+{
+    notImplemented();
+}
+
 bool WebPopupMenuImpl::handleInputEvent(const WebInputEvent& inputEvent)
 {
     if (!m_widget)
diff --git a/WebKit/chromium/src/WebPopupMenuImpl.h b/WebKit/chromium/src/WebPopupMenuImpl.h
index edbb4ab..221ba03 100644
--- a/WebKit/chromium/src/WebPopupMenuImpl.h
+++ b/WebKit/chromium/src/WebPopupMenuImpl.h
@@ -63,6 +63,8 @@ public:
     virtual void resize(const WebSize&);
     virtual void layout();
     virtual void paint(WebCanvas* canvas, const WebRect& rect);
+    virtual void themeChanged();
+    virtual void composite(bool finish);
     virtual bool handleInputEvent(const WebInputEvent&);
     virtual void mouseCaptureLost();
     virtual void setFocus(bool enable);
diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp
index 137bf06..349b62a 100644
--- a/WebKit/chromium/src/WebViewImpl.cpp
+++ b/WebKit/chromium/src/WebViewImpl.cpp
@@ -912,7 +912,12 @@ void WebViewImpl::resize(const WebSize& newSize)
 
     if (m_client) {
         WebRect damagedRect(0, 0, m_size.width, m_size.height);
-        m_client->didInvalidateRect(damagedRect);
+        if (isAcceleratedCompositingActive()) {
+#if USE(ACCELERATED_COMPOSITING)
+            invalidateRootLayerRect(damagedRect);
+#endif
+        } else
+            m_client->didInvalidateRect(damagedRect);
     }
 
 #if OS(DARWIN)
@@ -946,33 +951,44 @@ void WebViewImpl::layout()
 
 void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
 {
-
+    if (isAcceleratedCompositingActive()) {
 #if USE(ACCELERATED_COMPOSITING)
-    if (!isAcceleratedCompositingActive()) {
+        doComposite();
+
+        // Readback into the canvas
+        // FIXME Insert wjmaclean's readback code here for webkit bug 44127
+
+        // Temporarily present so the downstream Chromium renderwidget still renders.
+        // FIXME: remove this call once the changes to Chromium's renderwidget have landed.
+        m_layerRenderer->present();
 #endif
+    } else {
         WebFrameImpl* webframe = mainFrameImpl();
         if (webframe)
             webframe->paint(canvas, rect);
-#if USE(ACCELERATED_COMPOSITING)
-    } else {
-        // Draw the contents of the root layer.
-        updateRootLayerContents(rect);
+    }
+}
 
-        WebFrameImpl* webframe = mainFrameImpl();
-        if (!webframe)
-            return;
-        FrameView* view = webframe->frameView();
-        if (!view)
-            return;
+void WebViewImpl::themeChanged()
+{
+    if (!page())
+        return;
+    FrameView* view = page()->mainFrame()->view();
 
-        // The visibleRect includes scrollbars whereas the contentRect doesn't.
-        IntRect visibleRect = view->visibleContentRect(true);
-        IntRect contentRect = view->visibleContentRect(false);
+    WebRect damagedRect(0, 0, m_size.width, m_size.height);
+    view->invalidateRect(damagedRect);
+}
 
-        // Ask the layer compositor to redraw all the layers.
-        ASSERT(m_layerRenderer->hardwareCompositing());
-        m_layerRenderer->drawLayers(rect, visibleRect, contentRect, IntPoint(view->scrollX(), view->scrollY()));
-    }
+void WebViewImpl::composite(bool finish)
+{
+#if USE(ACCELERATED_COMPOSITING)
+    doComposite();
+
+    // Finish if requested.
+    // FIXME: handle finish flag.
+
+    // Put result onscreen.
+    m_layerRenderer->present();
 #endif
 }
 
@@ -2114,11 +2130,111 @@ bool WebViewImpl::allowsAcceleratedCompositing()
 
 void WebViewImpl::setRootGraphicsLayer(WebCore::PlatformLayer* layer)
 {
+    bool wasActive = m_isAcceleratedCompositingActive;
     setIsAcceleratedCompositingActive(layer ? true : false);
     if (m_layerRenderer)
         m_layerRenderer->setRootLayer(layer);
+    if (wasActive != m_isAcceleratedCompositingActive) {
+        IntRect damagedRect(0, 0, m_size.width, m_size.height);
+        if (m_isAcceleratedCompositingActive)
+            invalidateRootLayerRect(damagedRect);
+        else
+            m_client->didInvalidateRect(damagedRect);
+    }
+}
+
+void WebViewImpl::setRootLayerNeedsDisplay()
+{
+    if (m_layerRenderer)
+        m_layerRenderer->setNeedsDisplay();
+    m_client->scheduleComposite();
+    // FIXME: To avoid breaking the downstream Chrome render_widget while downstream
+    // changes land, we also have to pass a 1x1 invalidate up to the client
+    {
+        WebRect damageRect(0, 0, 1, 1);
+        m_client->didInvalidateRect(damageRect);
+    }
+}
+
+
+void WebViewImpl::scrollRootLayerRect(const IntSize& scrollDelta, const IntRect& clipRect)
+{
+    // FIXME: To avoid breaking the Chrome render_widget when the new compositor render
+    // path is not checked in, we must still pass scroll damage up to the client. This
+    // code will be backed out in a followup CL once the Chromium changes have landed.
+    m_client->didScrollRect(scrollDelta.width(), scrollDelta.height(), clipRect);
+
+    ASSERT(m_layerRenderer);
+    // Compute the damage rect in viewport space.
+    WebFrameImpl* webframe = mainFrameImpl();
+    if (!webframe)
+        return;
+    FrameView* view = webframe->frameView();
+    if (!view)
+        return;
+
+    IntRect contentRect = view->visibleContentRect(false);
+
+    // We support fast scrolling in one direction at a time.
+    if (scrollDelta.width() && scrollDelta.height()) {
+        invalidateRootLayerRect(WebRect(contentRect));
+        return;
+    }
+
+    // Compute the region we will expose by scrolling. We use the
+    // content rect for invalidation.  Using this space for damage
+    // rects allows us to intermix invalidates with scrolls.
+    IntRect damagedContentsRect;
+    if (scrollDelta.width()) {
+        float dx = static_cast<float>(scrollDelta.width());
+        damagedContentsRect.setY(contentRect.y());
+        damagedContentsRect.setHeight(contentRect.height());
+        if (dx > 0) {
+            damagedContentsRect.setX(contentRect.x());
+            damagedContentsRect.setWidth(dx);
+        } else {
+            damagedContentsRect.setX(contentRect.right() + dx);
+            damagedContentsRect.setWidth(-dx);
+        }
+    } else {
+        float dy = static_cast<float>(scrollDelta.height());
+        damagedContentsRect.setX(contentRect.x());
+        damagedContentsRect.setWidth(contentRect.width());
+        if (dy > 0) {
+            damagedContentsRect.setY(contentRect.y());
+            damagedContentsRect.setHeight(dy);
+        } else {
+            damagedContentsRect.setY(contentRect.bottom() + dy);
+            damagedContentsRect.setHeight(-dy);
+        }
+    }
+
+    m_scrollDamage.unite(damagedContentsRect);
+    setRootLayerNeedsDisplay();
+}
+
+void WebViewImpl::invalidateRootLayerRect(const IntRect& rect)
+{
+    // FIXME: To avoid breaking the Chrome render_widget when the new compositor render
+    // path is not checked in, we must still pass damage up to the client. This
+    // code will be backed out in a followup CL once the Chromium changes have landed.
+    m_client->didInvalidateRect(rect);
+
+    ASSERT(m_layerRenderer);
+
+    if (!page())
+        return;
+    FrameView* view = page()->mainFrame()->view();
+
+    // rect is in viewport space. Convert to content space
+    // so that invalidations and scroll invalidations play well with one-another.
+    FloatRect contentRect = view->windowToContents(rect);
+
+    // FIXME: add a smarter damage aggregation logic? Right now, LayerChromium does simple union-ing.
+    m_layerRenderer->rootLayer()->setNeedsDisplay(contentRect);
 }
 
+
 void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
 {
     if (m_isAcceleratedCompositingActive == active)
@@ -2128,10 +2244,6 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
         m_layerRenderer = LayerRendererChromium::create(getOnscreenGLES2Context());
         if (m_layerRenderer) {
             m_isAcceleratedCompositingActive = true;
-            
-            // Force a redraw the entire view so that the compositor gets the entire view,
-            // rather than just the currently-dirty subset.
-            m_client->didInvalidateRect(IntRect(0, 0, m_size.width, m_size.height));
         } else {
             m_isAcceleratedCompositingActive = false;
             m_compositorCreationFailed = true;
@@ -2142,17 +2254,11 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
     }
 }
 
-void WebViewImpl::updateRootLayerContents(const WebRect& rect)
+void WebViewImpl::updateRootLayerContents(const IntRect& rect)
 {
     if (!isAcceleratedCompositingActive())
         return;
 
-    // FIXME: The accelerated compositing path invalidates a 1x1 rect at (0, 0)
-    // in order to get the renderer to ask the compositor to redraw. This is only
-    // temporary until we get the compositor to render directly from its own thread.
-    if (!rect.x && !rect.y && rect.width == 1 && rect.height == 1)
-        return;
-
     WebFrameImpl* webframe = mainFrameImpl();
     if (!webframe)
         return;
@@ -2164,7 +2270,7 @@ void WebViewImpl::updateRootLayerContents(const WebRect& rect)
     if (rootLayer) {
         IntRect visibleRect = view->visibleContentRect(true);
 
-        m_layerRenderer->setRootLayerCanvasSize(IntSize(rect.width, rect.height));
+        m_layerRenderer->setRootLayerCanvasSize(IntSize(rect.width(), rect.height()));
         GraphicsContext* rootLayerContext = m_layerRenderer->rootLayerGraphicsContext();
 
 #if PLATFORM(SKIA)
@@ -2174,7 +2280,7 @@ void WebViewImpl::updateRootLayerContents(const WebRect& rect)
         platformCanvas->save();
 
         // Bring the canvas into the coordinate system of the paint rect.
-        platformCanvas->translate(static_cast<SkScalar>(-rect.x), static_cast<SkScalar>(-rect.y));
+        platformCanvas->translate(static_cast<SkScalar>(-rect.x()), static_cast<SkScalar>(-rect.y()));
 
         rootLayerContext->save();
 
@@ -2188,7 +2294,7 @@ void WebViewImpl::updateRootLayerContents(const WebRect& rect)
         CGContextSaveGState(cgContext);
 
         // Bring the CoreGraphics context into the coordinate system of the paint rect.
-        CGContextTranslateCTM(cgContext, -rect.x, -rect.y);
+        CGContextTranslateCTM(cgContext, -rect.x(), -rect.y());
 
         rootLayerContext->save();
 
@@ -2202,22 +2308,48 @@ void WebViewImpl::updateRootLayerContents(const WebRect& rect)
     }
 }
 
-void WebViewImpl::setRootLayerNeedsDisplay()
+void WebViewImpl::doComposite()
 {
-    // FIXME: For now we're posting a repaint event for the entire page which is an overkill.
-    if (WebFrameImpl* webframe = mainFrameImpl()) {
-        if (FrameView* view = webframe->frameView()) {
-            // FIXME: Temporary hack to invalidate part of the page so that we get called to render
-            //        again.
-            IntRect visibleRect = view->visibleContentRect(true);
-            m_client->didInvalidateRect(IntRect(0, 0, 1, 1));
+    ASSERT(isAcceleratedCompositingActive());
+    if (!page())
+        return;
+    FrameView* view = page()->mainFrame()->view();
+
+    // The visibleRect includes scrollbars whereas the contentRect doesn't.
+    IntRect visibleRect = view->visibleContentRect(true);
+    IntRect contentRect = view->visibleContentRect(false);
+    IntRect viewPort = IntRect(0, 0, m_size.width, m_size.height);
+
+    // Give the compositor a chance to setup/resize the root texture handle and perform scrolling.
+    m_layerRenderer->prepareToDrawLayers(visibleRect, contentRect, IntPoint(view->scrollX(), view->scrollY()));
+
+    // Draw the contents of the root layer.
+    Vector<FloatRect> damageRects;
+    damageRects.append(m_scrollDamage);
+    damageRects.append(m_layerRenderer->rootLayer()->dirtyRect());
+    for (size_t i = 0; i < damageRects.size(); ++i) {
+        // The damage rect for the root layer is in content space [e.g. unscrolled].
+        // Convert from content space to viewPort space.
+        const FloatRect damagedContentRect = damageRects[i];
+        IntRect damagedRect = view->contentsToWindow(IntRect(damagedContentRect));
+
+        // Intersect this rectangle with the viewPort.
+        damagedRect.intersect(viewPort);
+
+        // Now render it.
+        if (damagedRect.width() && damagedRect.height()) {
+            updateRootLayerContents(damagedRect);
+            m_layerRenderer->updateRootLayerTextureRect(damagedRect);
         }
     }
+    m_layerRenderer->rootLayer()->resetNeedsDisplay();
+    m_scrollDamage = WebRect();
 
-    if (m_layerRenderer)
-        m_layerRenderer->setNeedsDisplay();
+    // Draw the actual layers...
+    m_layerRenderer->drawLayers(visibleRect, contentRect);
 }
-#endif // USE(ACCELERATED_COMPOSITING)
+#endif
+
 
 PassOwnPtr<GLES2Context> WebViewImpl::getOnscreenGLES2Context()
 {
diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h
index a42099c..cb7da95 100644
--- a/WebKit/chromium/src/WebViewImpl.h
+++ b/WebKit/chromium/src/WebViewImpl.h
@@ -34,6 +34,7 @@
 #include "WebGLES2Context.h"
 #include "WebNavigationPolicy.h"
 #include "WebPoint.h"
+#include "WebRect.h"
 #include "WebSize.h"
 #include "WebString.h"
 #include "WebView.h"
@@ -92,6 +93,8 @@ public:
     virtual void resize(const WebSize&);
     virtual void layout();
     virtual void paint(WebCanvas*, const WebRect&);
+    virtual void themeChanged();
+    virtual void composite(bool finish);
     virtual bool handleInputEvent(const WebInputEvent&);
     virtual void mouseCaptureLost();
     virtual void setFocus(bool enable);
@@ -322,9 +325,11 @@ public:
     }
 
 #if USE(ACCELERATED_COMPOSITING)
-    void setRootLayerNeedsDisplay();
-    void setRootGraphicsLayer(WebCore::PlatformLayer*);
     bool allowsAcceleratedCompositing();
+    void setRootGraphicsLayer(WebCore::PlatformLayer*);
+    void setRootLayerNeedsDisplay();
+    void scrollRootLayerRect(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& clipRect);
+    void invalidateRootLayerRect(const WebCore::IntRect&);
 #endif
     // Onscreen contexts display to the screen associated with this view.
     // Offscreen contexts render offscreen but can share resources with the
@@ -386,7 +391,8 @@ private:
 
 #if USE(ACCELERATED_COMPOSITING)
     void setIsAcceleratedCompositingActive(bool);
-    void updateRootLayerContents(const WebRect&);
+    void updateRootLayerContents(const WebCore::IntRect&);
+    void doComposite();
 #endif
 
     WebViewClient* m_client;
@@ -511,6 +517,7 @@ private:
     RefPtr<WebCore::Node> m_mouseCaptureNode;
 
 #if USE(ACCELERATED_COMPOSITING)
+    WebCore::IntRect m_scrollDamage;
     OwnPtr<WebCore::LayerRendererChromium> m_layerRenderer;
     bool m_isAcceleratedCompositingActive;
     bool m_compositorCreationFailed;
diff --git a/WebKit/chromium/tests/PopupMenuTest.cpp b/WebKit/chromium/tests/PopupMenuTest.cpp
index 50319af..aef29cf 100644
--- a/WebKit/chromium/tests/PopupMenuTest.cpp
+++ b/WebKit/chromium/tests/PopupMenuTest.cpp
@@ -128,6 +128,8 @@ public:
     virtual void resize(const WebSize&) { }
     virtual void layout() { }
     virtual void paint(WebCanvas*, const WebRect&) { }
+    virtual void themeChanged() { }
+    virtual void composite(bool finish) { }
     virtual bool handleInputEvent(const WebInputEvent&) { return true; }
     virtual void mouseCaptureLost() { }
     virtual void setFocus(bool) { }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list