From: Chris Craik Date: Tue, 23 Aug 2011 20:36:18 +0000 (-0700) Subject: better locking while scrolling, but disables double buffering X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=f51a51f6ea307f4311a04aa865a42b233269540b;p=android-x86%2Fexternal-webkit.git better locking while scrolling, but disables double buffering 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 --- diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index e3e41bc1f..ca679fb92 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -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(); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 3cc192fe7..e07c86fe8 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -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)", diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 9182af30b..9bda481a9 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -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; diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp index a69f9d1ab..c9c776c8d 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.cpp +++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp @@ -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; diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h index 4b0936422..56a34f475 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.h +++ b/Source/WebCore/platform/graphics/android/TiledPage.h @@ -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 diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 3af55a3c8..5bc7f48de 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -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 }, diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 4b18b626d..577b7c689 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -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",