Title: [109638] trunk/Source/WebKit/blackberry
Revision
109638
Author
[email protected]
Date
2012-03-02 17:22:24 -0800 (Fri, 02 Mar 2012)

Log Message

Accelerated compositing: Checkerboard never goes away
https://bugs.webkit.org/show_bug.cgi?id=79020
RIM PR #134164

Patch by Arvid Nilsson <[email protected]> on 2012-03-02
Reviewed by Adam Treat.

Checkerboard appears in accelerated compositing layers when there's no
texture for (part of) a layer. The layer renderer queues up some render
jobs and schedules a commit to make the WebKit thread process those
jobs. Render jobs performed during commit cause texture upload jobs to
be scheduled on the UI thread. Texture uploads are performed when next
drawing the layers.

Unfortunately, sometimes commit operation happens without a subsequent
call draw the layers.

In order to implement one-shot drawing sync, I added a call to
commitRootLayerIfNeeded() in BackingStore::renderContents(), and
I was lucky that most of the time, renderContents() is followed by
blit(Visible)Contents() which in turn draws the layers.
However, render is not always followed by a blit, for example when
rendering offscreen tiles in BackingStore::renderOnIdle(), and in
direct rendering mode.

Fixed by making sure that every call to commitRootLayerIfNeeded() that
returns true is followed by a call to drawLayersOnCommit(), unless a
blit was requested already.

Also tweak the logic for one-shot drawing sync to make the code in
drawLayersOnCommit() reusable outside of rootLayerCommitTimerFired().

* Api/BackingStore.cpp:
(BlackBerry::WebKit::BackingStorePrivate::BackingStorePrivate):
(BlackBerry::WebKit::BackingStorePrivate::renderOnTimer):
(BlackBerry::WebKit::BackingStorePrivate::renderOnIdle):
(BlackBerry::WebKit::BackingStorePrivate::willFireTimer):
(BlackBerry::WebKit::BackingStorePrivate::renderDirectToWindow):
(BlackBerry::WebKit::BackingStorePrivate::render):
(BlackBerry::WebKit::BackingStorePrivate::blitVisibleContents):
(BlackBerry::WebKit::BackingStorePrivate::blitContents):
(BlackBerry::WebKit::BackingStorePrivate::renderContents):
(WebKit):
(BlackBerry::WebKit::BackingStorePrivate::drawLayersOnCommitIfNeeded):
* Api/BackingStore_p.h:
(BackingStorePrivate):
(BlackBerry::WebKit::BackingStorePrivate::willDrawLayersOnCommit):

Modified Paths

Diff

Modified: trunk/Source/WebKit/blackberry/Api/BackingStore.cpp (109637 => 109638)


--- trunk/Source/WebKit/blackberry/Api/BackingStore.cpp	2012-03-03 01:03:33 UTC (rev 109637)
+++ trunk/Source/WebKit/blackberry/Api/BackingStore.cpp	2012-03-03 01:22:24 UTC (rev 109638)
@@ -201,6 +201,9 @@
     , m_currentWindowBackBuffer(0)
     , m_preferredTileMatrixDimension(Vertical)
     , m_blitGeneration(-1)
+#if USE(ACCELERATED_COMPOSITING)
+    , m_needsDrawLayersOnCommit(false)
+#endif
 {
     m_frontState = reinterpret_cast<unsigned>(new BackingStoreGeometry);
     m_backState = reinterpret_cast<unsigned>(new BackingStoreGeometry);
@@ -464,10 +467,12 @@
     while (m_renderQueue->hasCurrentVisibleZoomJob() || m_renderQueue->hasCurrentVisibleScrollJob())
         m_renderQueue->render(!m_suspendRegularRenderJobs);
 
-    if (!shouldPerformRegularRenderJobs() || !m_renderQueue->hasCurrentRegularRenderJob())
-        return;
+    if (shouldPerformRegularRenderJobs() && m_renderQueue->hasCurrentRegularRenderJob())
+        m_renderQueue->renderAllCurrentRegularRenderJobs();
 
-    m_renderQueue->renderAllCurrentRegularRenderJobs();
+#if USE(ACCELERATED_COMPOSITING)
+    drawLayersOnCommitIfNeeded();
+#endif
 }
 
 void BackingStorePrivate::renderOnIdle()
@@ -483,6 +488,10 @@
 #endif
 
     m_renderQueue->render(!m_suspendRegularRenderJobs);
+
+#if USE(ACCELERATED_COMPOSITING)
+    drawLayersOnCommitIfNeeded();
+#endif
 }
 
 bool BackingStorePrivate::willFireTimer()
@@ -512,6 +521,10 @@
     if (m_renderQueue->hasCurrentRegularRenderJob())
         m_renderQueue->renderAllCurrentRegularRenderJobs();
 
+#if USE(ACCELERATED_COMPOSITING)
+    drawLayersOnCommitIfNeeded();
+#endif
+
     // Let the caller yield and reschedule the timer.
     return false;
 }
@@ -941,12 +954,15 @@
     renderContents(0, origin, dirtyRect);
     windowBackBufferState()->addBlittedRegion(screenRect);
 
-#if USE(ACCELERATED_COMPOSITING) && ENABLE_COMPOSITING_SURFACE
+#if USE(ACCELERATED_COMPOSITING)
+    drawLayersOnCommitIfNeeded();
+#if ENABLE_COMPOSITING_SURFACE
     if (m_webPage->d->m_client->window()->windowUsage() != BlackBerry::Platform::Graphics::Window::GLES2Usage) {
         Platform::IntRect clippedRect = intersection(dirtyRect, visibleContentsRect());
         blendCompositingSurface(clippedRect);
     }
 #endif
+#endif
 
     invalidateWindow(screenRect);
     return true;
@@ -979,8 +995,6 @@
     TileMap currentMap = currentState->tileMap();
 
     Platform::IntRect dirtyContentsRect;
-    const Platform::IntRect contentsRect = Platform::IntRect(Platform::IntPoint(0, 0), m_client->transformedContentsSize());
-    const Platform::IntRect viewportRect = Platform::IntRect(Platform::IntPoint(0, 0), m_client->transformedViewportSize());
 
     for (size_t i = 0; i < tileRectList.size(); ++i) {
         TileRect tileRect = tileRectList[i];
@@ -1106,6 +1120,11 @@
     }
 
     if (!BlackBerry::Platform::userInterfaceThreadMessageClient()->isCurrentThread()) {
+#if USE(ACCELERATED_COMPOSITING)
+        // The blit will call drawSubLayers if necessary
+        m_needsDrawLayersOnCommit = false;
+#endif
+
         BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchMessage(
             BlackBerry::Platform::createMethodCallMessage(
                 &BackingStorePrivate::blitVisibleContents, this, force));
@@ -1196,6 +1215,11 @@
     }
 
     if (!BlackBerry::Platform::userInterfaceThreadMessageClient()->isCurrentThread()) {
+#if USE(ACCELERATED_COMPOSITING)
+        // The blit will call drawSubLayers if necessary
+        m_needsDrawLayersOnCommit = false;
+#endif
+
         BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchMessage(
             BlackBerry::Platform::createMethodCallMessage(
                 &BackingStorePrivate::blitContents, this, dstRect, srcRect, force));
@@ -2131,7 +2155,15 @@
         return;
 
 #if USE(ACCELERATED_COMPOSITING)
-    m_webPage->d->commitRootLayerIfNeeded();
+    // When committing the pending accelerated compositing layer changes, it's
+    // necessary to draw the new layer appearance. This is normally done as
+    // part of a blit, but if no blit happens because of this rendering, for
+    // example because we're rendering an offscreen rectangle, someone needs to
+    // catch this flag and make sure those layers get drawn.
+    // This is just a complicated way to do
+    // "if (commitRootLayerIfNeeded()) drawLayersOnCommit();"
+    if (m_webPage->d->commitRootLayerIfNeeded())
+        m_needsDrawLayersOnCommit = true;
 #endif
 
     BlackBerry::Platform::Graphics::Drawable* bufferDrawable =
@@ -2483,6 +2515,18 @@
         WebCore::FloatRect(WebCore::IntRect(src)));
     return m_webPage->d->drawSubLayers(dst, contentsRect);
 }
+
+bool BackingStorePrivate::drawLayersOnCommitIfNeeded()
+{
+    // Check if rendering caused a commit and we need to redraw the layers
+    if (!m_needsDrawLayersOnCommit)
+        return false;
+
+    m_needsDrawLayersOnCommit = false;
+    m_webPage->d->drawLayersOnCommit();
+
+    return true;
+}
 #endif
 
 bool BackingStorePrivate::isActive() const

Modified: trunk/Source/WebKit/blackberry/Api/BackingStore_p.h (109637 => 109638)


--- trunk/Source/WebKit/blackberry/Api/BackingStore_p.h	2012-03-03 01:03:33 UTC (rev 109637)
+++ trunk/Source/WebKit/blackberry/Api/BackingStore_p.h	2012-03-03 01:22:24 UTC (rev 109638)
@@ -196,6 +196,9 @@
     void blendCompositingSurface(const Platform::IntRect& dstRect);
     void clearCompositingSurface();
     bool drawSubLayers();
+    bool drawLayersOnCommitIfNeeded();
+    // WebPage will call this when drawing layers to tell us we don't need to
+    void willDrawLayersOnCommit() { m_needsDrawLayersOnCommit = false; }
 #endif
 
     void blitHorizontalScrollbar(const Platform::IntPoint&);
@@ -347,6 +350,10 @@
     pthread_mutex_t m_blitGenerationLock;
     pthread_cond_t m_blitGenerationCond;
     struct timespec m_currentBlitEnd;
+
+#if USE(ACCELERATED_COMPOSITING)
+    mutable bool m_needsDrawLayersOnCommit; // Not thread safe, WebKit thread only
+#endif
 };
 } // namespace WebKit
 } // namespace BlackBerry

Modified: trunk/Source/WebKit/blackberry/ChangeLog (109637 => 109638)


--- trunk/Source/WebKit/blackberry/ChangeLog	2012-03-03 01:03:33 UTC (rev 109637)
+++ trunk/Source/WebKit/blackberry/ChangeLog	2012-03-03 01:22:24 UTC (rev 109638)
@@ -1,3 +1,52 @@
+2012-03-02  Arvid Nilsson  <[email protected]>
+
+        Accelerated compositing: Checkerboard never goes away
+        https://bugs.webkit.org/show_bug.cgi?id=79020
+        RIM PR #134164
+
+        Reviewed by Adam Treat.
+
+        Checkerboard appears in accelerated compositing layers when there's no
+        texture for (part of) a layer. The layer renderer queues up some render
+        jobs and schedules a commit to make the WebKit thread process those
+        jobs. Render jobs performed during commit cause texture upload jobs to
+        be scheduled on the UI thread. Texture uploads are performed when next
+        drawing the layers.
+
+        Unfortunately, sometimes commit operation happens without a subsequent
+        call draw the layers.
+
+        In order to implement one-shot drawing sync, I added a call to
+        commitRootLayerIfNeeded() in BackingStore::renderContents(), and
+        I was lucky that most of the time, renderContents() is followed by
+        blit(Visible)Contents() which in turn draws the layers.
+        However, render is not always followed by a blit, for example when
+        rendering offscreen tiles in BackingStore::renderOnIdle(), and in
+        direct rendering mode.
+
+        Fixed by making sure that every call to commitRootLayerIfNeeded() that
+        returns true is followed by a call to drawLayersOnCommit(), unless a
+        blit was requested already.
+
+        Also tweak the logic for one-shot drawing sync to make the code in
+        drawLayersOnCommit() reusable outside of rootLayerCommitTimerFired().
+
+        * Api/BackingStore.cpp:
+        (BlackBerry::WebKit::BackingStorePrivate::BackingStorePrivate):
+        (BlackBerry::WebKit::BackingStorePrivate::renderOnTimer):
+        (BlackBerry::WebKit::BackingStorePrivate::renderOnIdle):
+        (BlackBerry::WebKit::BackingStorePrivate::willFireTimer):
+        (BlackBerry::WebKit::BackingStorePrivate::renderDirectToWindow):
+        (BlackBerry::WebKit::BackingStorePrivate::render):
+        (BlackBerry::WebKit::BackingStorePrivate::blitVisibleContents):
+        (BlackBerry::WebKit::BackingStorePrivate::blitContents):
+        (BlackBerry::WebKit::BackingStorePrivate::renderContents):
+        (WebKit):
+        (BlackBerry::WebKit::BackingStorePrivate::drawLayersOnCommitIfNeeded):
+        * Api/BackingStore_p.h:
+        (BackingStorePrivate):
+        (BlackBerry::WebKit::BackingStorePrivate::willDrawLayersOnCommit):
+
 2012-03-02  Adam Treat  <[email protected]>
 
         https://bugs.webkit.org/show_bug.cgi?id=80161
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to