[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