OSDN Git Service

better locking while scrolling, but disables double buffering
authorChris Craik <ccraik@google.com>
Tue, 23 Aug 2011 20:36:18 +0000 (13:36 -0700)
committerChris Craik <ccraik@google.com>
Thu, 25 Aug 2011 22:08:33 +0000 (15:08 -0700)
don't detect scrolling, query from java
removes double buffering

depends on CL in frameworks/base: https://android-git.corp.google.com/g/#/c/130213/

bug:5106313
Change-Id: Ibfa7f305874f4209fed001c030bb94e752d479b9

Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
Source/WebCore/platform/graphics/android/GLWebViewState.cpp
Source/WebCore/platform/graphics/android/GLWebViewState.h
Source/WebCore/platform/graphics/android/TiledPage.cpp
Source/WebCore/platform/graphics/android/TiledPage.h
Source/WebKit/android/jni/WebViewCore.cpp
Source/WebKit/android/nav/WebView.cpp

index e3e41bc..ca679fb 100644 (file)
@@ -135,11 +135,10 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
 
     // Let's prepare the page if needed
     if (prepareNextTiledPage) {
-        TiledPage* nextTiledPage = m_glWebViewState->backPage();
         nextTiledPage->setScale(scale);
         m_glWebViewState->setFutureViewport(viewportTileBounds);
         m_glWebViewState->lockBaseLayerUpdate();
-        nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds);
+        nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds, TiledPage::kVisibleBounds);
         // Cancel pending paints for the foreground page
         TilesManager::instance()->removePaintOperationsForPage(tiledPage, false);
     }
@@ -159,7 +158,6 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
         float nextTiledPageTransparency = 1;
         zoomManager->processTransition(currentTime, scale, &doSwap,
                                        &nextTiledPageTransparency, &transparency);
-
         nextTiledPage->draw(nextTiledPageTransparency, viewportTileBounds);
     }
 
@@ -167,38 +165,39 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
 
     bool needsRedraw = false;
 
-    // We are now using an hybrid model -- during scrolling,
-    // we will display the current tiledPage even if some tiles are
-    // out of date. When standing still on the other hand, we wait until
-    // the back page is ready before swapping the pages, ensuring that the
-    // displayed content is in sync.
-    if (!doSwap && !zooming && !m_glWebViewState->moving()) {
-        if (!tiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
+    static bool waitOnScrollFinish = false;
+
+    if (m_glWebViewState->isScrolling()) {
+        if (!waitOnScrollFinish) {
+            waitOnScrollFinish = true;
+
+            //started scrolling, lock updates
             m_glWebViewState->lockBaseLayerUpdate();
-            nextTiledPage->setScale(zoomManager->currentScale());
-            nextTiledPage->prepare(goingDown, goingLeft, preZoomBounds);
-        }
-        if (nextTiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
-            nextTiledPage->draw(transparency, preZoomBounds);
-            m_glWebViewState->resetFrameworkInval();
-            m_glWebViewState->unlockBaseLayerUpdate();
-            doSwap = true;
-        } else {
-            tiledPage->draw(transparency, preZoomBounds);
         }
     } else {
-        if (tiledPage->ready(preZoomBounds, zoomManager->currentScale()))
-           m_glWebViewState->resetFrameworkInval();
-
-        // Ask for the tiles and draw -- tiles may be out of date.
-        if (!zooming)
-           m_glWebViewState->unlockBaseLayerUpdate();
+        // wait until all tiles are rendered before anything else
+        if (waitOnScrollFinish) {
+            //wait for the page to finish rendering, then go into swap mode
+            if (tiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
+                m_glWebViewState->resetFrameworkInval();
+                m_glWebViewState->unlockBaseLayerUpdate();
+                waitOnScrollFinish = false;
+            }
+            //should be prepared, simply draw
+        }
 
-        if (!prepareNextTiledPage)
-            tiledPage->prepare(goingDown, goingLeft, preZoomBounds);
-        tiledPage->draw(transparency, preZoomBounds);
+        if (!waitOnScrollFinish) {
+            //completed page post-scroll
+            if (!tiledPage->ready(preZoomBounds, zoomManager->currentScale())) {
+                m_glWebViewState->lockBaseLayerUpdate();
+            }
+        }
     }
 
+    if (!prepareNextTiledPage || tiledPage->ready(preZoomBounds, zoomManager->currentScale()))
+        tiledPage->prepare(goingDown, goingLeft, preZoomBounds, TiledPage::kExpandedBounds);
+    tiledPage->draw(transparency, preZoomBounds);
+
     if (zoomManager->scaleRequestState() != ZoomManager::kNoScaleRequest
         || !tiledPage->ready(preZoomBounds, zoomManager->currentScale()))
         needsRedraw = true;
@@ -206,14 +205,13 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale,
     if (doSwap) {
         zoomManager->setCurrentScale(scale);
         m_glWebViewState->swapPages();
-        m_glWebViewState->unlockBaseLayerUpdate();
         if (pagesSwapped)
             *pagesSwapped = true;
     }
 
     // if no longer trailing behind invalidates, unlock (so invalidates can
     // go directly to the the TiledPages without deferral)
-    if (!needsRedraw)
+    if (!needsRedraw && !waitOnScrollFinish)
         m_glWebViewState->unlockBaseLayerUpdate();
 
     m_glWebViewState->paintExtras();
index 3cc192f..e07c86f 100644 (file)
@@ -64,7 +64,8 @@ namespace WebCore {
 using namespace android;
 
 GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
-    : m_baseLayer(0)
+    : m_zoomManager(this)
+    , m_baseLayer(0)
     , m_currentBaseLayer(0)
     , m_previouslyUsedRoot(0)
     , m_currentPictureCounter(0)
@@ -76,14 +77,13 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex)
     , m_backgroundColor(SK_ColorWHITE)
     , m_displayRings(false)
     , m_focusRingTexture(-1)
+    , m_isScrolling(false)
     , m_goingDown(true)
     , m_goingLeft(false)
     , m_expandedTileBoundsX(0)
     , m_expandedTileBoundsY(0)
-    , m_zoomManager(this)
 {
     m_viewport.setEmpty();
-    m_previousViewport.setEmpty();
     m_futureViewportTileBounds.setEmpty();
     m_viewportTileBounds.setEmpty();
     m_preZoomBounds.setEmpty();
@@ -226,8 +226,7 @@ void GLWebViewState::inval(const IntRect& rect)
         m_currentPictureCounter++;
         if (!rect.isEmpty()) {
             // find which tiles fall within the invalRect and mark them as dirty
-            m_tiledPageA->invalidateRect(rect, m_currentPictureCounter);
-            m_tiledPageB->invalidateRect(rect, m_currentPictureCounter);
+            frontPage()->invalidateRect(rect, m_currentPictureCounter);
             if (m_frameworkInval.isEmpty())
                 m_frameworkInval = rect;
             else
@@ -372,13 +371,12 @@ int GLWebViewState::baseContentHeight()
 
 void GLWebViewState::setViewport(SkRect& viewport, float scale)
 {
-    m_previousViewport = m_viewport;
     if ((m_viewport == viewport) &&
         (zoomManager()->futureScale() == scale))
         return;
 
-    m_goingDown = m_previousViewport.fTop - viewport.fTop <= 0;
-    m_goingLeft = m_previousViewport.fLeft - viewport.fLeft >= 0;
+    m_goingDown = m_viewport.fTop - viewport.fTop <= 0;
+    m_goingLeft = m_viewport.fLeft - viewport.fLeft >= 0;
     m_viewport = viewport;
 
     XLOG("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)",
index 9182af3..9bda481 100644 (file)
@@ -203,16 +203,8 @@ public:
     void lockBaseLayerUpdate() { m_baseLayerUpdate = false; }
     void unlockBaseLayerUpdate();
 
-    bool moving() {
-        // This will only works if we are not zooming -- we check
-        // for this in BaseLayerAndroid::drawBasePictureInGL()
-        if ((m_viewport.fLeft != m_previousViewport.fLeft ||
-            m_viewport.fTop != m_previousViewport.fTop) &&
-            m_viewport.width() == m_previousViewport.width() &&
-            m_viewport.height() == m_previousViewport.height())
-            return true;
-        return false;
-    }
+    void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; }
+    bool isScrolling() { return m_isScrolling; }
 
     double setupDrawing(IntRect& rect, SkRect& viewport, IntRect& webViewRect,
                 int titleBarHeight, IntRect& screenClip,
@@ -248,7 +240,6 @@ private:
     ZoomManager m_zoomManager;
     android::Mutex m_tiledPageLock;
     SkRect m_viewport;
-    SkRect m_previousViewport;
     SkIRect m_viewportTileBounds;
     SkIRect m_futureViewportTileBounds;
     SkIRect m_preZoomBounds;
@@ -282,6 +273,7 @@ private:
     bool m_ringsIsPressed;
     int m_focusRingTexture;
 
+    bool m_isScrolling;
     bool m_goingDown;
     bool m_goingLeft;
 
index a69f9d1..c9c776c 100644 (file)
@@ -240,7 +240,7 @@ void TiledPage::updateTileState(const SkIRect& tileBounds)
     m_invalTilesRegion.setEmpty();
 }
 
-void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds)
+void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds)
 {
     if (!m_glWebViewState)
         return;
@@ -263,16 +263,20 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
     // smoother scrolling.
     int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
     int nMaxTilesPerPage = m_baseTileSize / 2;
-    int expandX = m_glWebViewState->expandedTileBoundsX();
-    int expandY = m_glWebViewState->expandedTileBoundsY();
 
-    firstTileX -= expandX;
-    lastTileX += expandX;
-    nbTilesWidth += expandX * 2;
+    if (bounds == kExpandedBounds) {
+        // prepare tiles outside of the visible bounds
+        int expandX = m_glWebViewState->expandedTileBoundsX();
+        int expandY = m_glWebViewState->expandedTileBoundsY();
 
-    firstTileY -= expandY;
-    lastTileY += expandY;
-    nbTilesHeight += expandY * 2;
+        firstTileX -= expandX;
+        lastTileX += expandX;
+        nbTilesWidth += expandX * 2;
+
+        firstTileY -= expandY;
+        lastTileY += expandY;
+        nbTilesHeight += expandY * 2;
+    }
 
     m_expandedTileBounds.fLeft = firstTileX;
     m_expandedTileBounds.fTop = firstTileY;
index 4b09364..56a34f4 100644 (file)
@@ -51,6 +51,11 @@ class IntRect;
  */
 class TiledPage : public TilePainter {
 public:
+    enum PrepareBounds {
+        kExpandedBounds = 0,
+        kVisibleBounds = 1
+    };
+
     TiledPage(int id, GLWebViewState* state);
     ~TiledPage();
 
@@ -58,7 +63,7 @@ public:
     TiledPage* sibling();
 
     // prepare the page for display on the screen
-    void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds);
+    void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds);
     // check to see if the page is ready for display
     bool ready(const SkIRect& tileBounds, float scale);
     // draw the page on the screen
index 3af55a3..5bc7f48 100644 (file)
@@ -3842,11 +3842,10 @@ void WebViewCore::setWebTextViewAutoFillable(int queryId, const string16& previe
 
 bool WebViewCore::drawIsPaused() const
 {
-    JNIEnv* env = JSC::Bindings::getJNIEnv();
-    AutoJObject javaObject = m_javaGlue->object(env);
-    if (!javaObject.get())
-        return false;
-    return env->GetBooleanField(javaObject.get(), gWebViewCoreFields.m_drawIsPaused);
+    // returning true says scrollview should be offscreen, which pauses
+    // gifs. because this is not again queried when we stop scrolling, we don't
+    // use the stopping currently.
+    return false;
 }
 
 #if USE(CHROME_NETWORK_STACK)
@@ -4438,6 +4437,14 @@ static bool FocusBoundsChanged(JNIEnv* env, jobject obj)
     return GET_NATIVE_VIEW(env, obj)->focusBoundsChanged();
 }
 
+static void SetIsPaused(JNIEnv* env, jobject obj, jboolean isPaused)
+{
+    // tell the webcore thread to stop thinking while we do other work
+    // (selection and scrolling). This has nothing to do with the lifecycle
+    // pause and resume.
+    GET_NATIVE_VIEW(env, obj)->setIsPaused(isPaused);
+}
+
 static void Pause(JNIEnv* env, jobject obj)
 {
     // This is called for the foreground tab when the browser is put to the
@@ -4685,6 +4692,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
         (void*) SetNewStorageLimit },
     { "nativeGeolocationPermissionsProvide", "(Ljava/lang/String;ZZ)V",
         (void*) GeolocationPermissionsProvide },
+    { "nativeSetIsPaused", "(Z)V", (void*) SetIsPaused },
     { "nativePause", "()V", (void*) Pause },
     { "nativeResume", "()V", (void*) Resume },
     { "nativeFreeMemory", "()V", (void*) FreeMemory },
index 4b18b62..577b7c6 100644 (file)
@@ -1330,6 +1330,11 @@ bool scrollBy(int dx, int dy)
     return result;
 }
 
+void setIsScrolling(bool isScrolling)
+{
+    m_glWebViewState->setIsScrolling(isScrolling);
+}
+
 bool hasCursorNode()
 {
     CachedRoot* root = getFrameCache(DontAllowNewer);
@@ -2611,6 +2616,13 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x,
     return false;
 }
 
+static void nativeSetIsScrolling(JNIEnv* env, jobject jwebview, jboolean isScrolling)
+{
+    WebView* view = GET_NATIVE_VIEW(env, jwebview);
+    LOG_ASSERT(view, "view not set in %s", __FUNCTION__);
+    view->setIsScrolling(isScrolling);
+}
+
 static void nativeUseHardwareAccelSkia(JNIEnv*, jobject, jboolean enabled)
 {
     BaseRenderer::setCurrentRendererType(enabled ? BaseRenderer::Ganesh : BaseRenderer::Raster);
@@ -2825,6 +2837,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
         (void*) nativeScrollableLayer },
     { "nativeScrollLayer", "(III)Z",
         (void*) nativeScrollLayer },
+    { "nativeSetIsScrolling", "(Z)V",
+        (void*) nativeSetIsScrolling },
     { "nativeUseHardwareAccelSkia", "(Z)V",
         (void*) nativeUseHardwareAccelSkia },
     { "nativeGetBackgroundColor", "()I",