diff options
4 files changed, 67 insertions, 56 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 05b3a3d..98eb623 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -190,13 +190,14 @@ void BaseTile::markAsDirty(int unsigned pictureCount, // current paint m_state = Unpainted; } else if (m_state != Unpainted) { - // layer tiles and prefetch page tiles are potentially marked dirty - // while in the process of painting, due to not using an update lock - // TODO: fix it so that they can paint while deferring the markAsDirty // call (or block updates) XLOG("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d, page %p", this, m_x, m_y, isLayerTile(), m_state, m_page); + + // prefetch tiles can be marked dirty while in the process of painting, + // due to not using an update lock. force them to fail validate step. + m_state = Unpainted; } } @@ -510,6 +511,8 @@ void BaseTile::discardBackTexture() { m_backTexture->release(this); m_backTexture = 0; } + m_state = Unpainted; + m_dirty = true; } bool BaseTile::swapTexturesIfNeeded() { @@ -548,6 +551,7 @@ void BaseTile::backTextureTransferFail() { // retransferred. android::AutoMutex lock(m_atomicSync); m_state = Unpainted; + m_dirty = true; // whether validatePaint is called before or after, it won't do anything } @@ -563,9 +567,11 @@ void BaseTile::validatePaint() { else if (m_state == TransferredUnvalidated) m_state = ReadyToSwap; else { - // shouldn't have just finished painting in any other state, log XLOG("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d", this, m_x, m_y, m_state); + // failed transferring, in which case mark dirty (since + // paintBitmap() may have cleared m_dirty) + m_dirty = true; } if (m_deferredDirty) { diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 300573c..dbd4612 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -71,9 +71,9 @@ using namespace android; GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) : m_zoomManager(this) - , m_baseLayer(0) + , m_paintingBaseLayer(0) , m_currentBaseLayer(0) - , m_previouslyUsedRoot(0) + , m_currentBaseLayerRoot(0) , m_currentPictureCounter(0) , m_usePageA(true) , m_frameworkInval(0, 0, 0, 0) @@ -109,8 +109,8 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) GLWebViewState::~GLWebViewState() { // Unref the existing tree/PaintedSurfaces - if (m_previouslyUsedRoot) - TilesManager::instance()->swapLayersTextures(m_previouslyUsedRoot, 0); + if (m_currentBaseLayerRoot) + TilesManager::instance()->swapLayersTextures(m_currentBaseLayerRoot, 0); // Take care of the transfer queue such that Tex Gen thread will not stuck TilesManager::instance()->unregisterGLWebViewState(this); @@ -118,17 +118,17 @@ GLWebViewState::~GLWebViewState() // We have to destroy the two tiled pages first as their destructor // may depend on the existence of this GLWebViewState and some of its // instance variables in order to complete. - // Explicitely, currently we need to have the m_currentBaseLayer around + // Explicitely, currently we need to have the m_paintingBaseLayer around // in order to complete any pending paint operations (the tiled pages // will remove any pending operations, and wait if one is underway). delete m_tiledPageA; delete m_tiledPageB; - SkSafeUnref(m_previouslyUsedRoot); + SkSafeUnref(m_paintingBaseLayer); SkSafeUnref(m_currentBaseLayer); - SkSafeUnref(m_baseLayer); - m_previouslyUsedRoot = 0; - m_baseLayer = 0; + SkSafeUnref(m_currentBaseLayerRoot); + m_paintingBaseLayer = 0; m_currentBaseLayer = 0; + m_currentBaseLayerRoot = 0; #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("GLWebViewState"); #endif @@ -147,21 +147,34 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval m_baseLayerUpdate = true; m_invalidateRegion.setEmpty(); } - if (m_baseLayer && layer) - m_baseLayer->swapExtra(layer); + if (m_currentBaseLayer && layer) + m_currentBaseLayer->swapExtra(layer); SkSafeRef(layer); - SkSafeUnref(m_baseLayer); - m_baseLayer = layer; - if (m_baseLayer) - m_baseLayer->setGLWebViewState(this); + SkSafeUnref(m_currentBaseLayer); + m_currentBaseLayer = layer; + + + // copy content from old composited root to new + LayerAndroid* oldRoot = m_currentBaseLayerRoot; + if (layer) { + layer->setGLWebViewState(this); + m_currentBaseLayerRoot = static_cast<LayerAndroid*>(layer->getChild(0)); + SkSafeRef(m_currentBaseLayerRoot); + } else { + m_currentBaseLayerRoot = 0; + } + if (m_currentBaseLayerRoot && oldRoot) + TilesManager::instance()->swapLayersTextures(oldRoot, m_currentBaseLayerRoot); + SkSafeUnref(oldRoot); + - // We only update the layers if we are not currently + // We only update the base layer if we are not currently // waiting for a tiledPage to be painted if (m_baseLayerUpdate) { SkSafeRef(layer); - SkSafeUnref(m_currentBaseLayer); - m_currentBaseLayer = layer; + SkSafeUnref(m_paintingBaseLayer); + m_paintingBaseLayer = layer; } m_glExtras.setDrawExtra(0); invalRegion(inval); @@ -192,9 +205,9 @@ void GLWebViewState::unlockBaseLayerUpdate() { m_baseLayerUpdate = true; android::Mutex::Autolock lock(m_baseLayerLock); - SkSafeRef(m_baseLayer); - SkSafeUnref(m_currentBaseLayer); - m_currentBaseLayer = m_baseLayer; + SkSafeRef(m_currentBaseLayer); + SkSafeUnref(m_paintingBaseLayer); + m_paintingBaseLayer = m_currentBaseLayer; invalRegion(m_invalidateRegion); m_invalidateRegion.setEmpty(); @@ -227,9 +240,9 @@ void GLWebViewState::inval(const IntRect& rect) unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) { android::Mutex::Autolock lock(m_baseLayerLock); - if (m_currentBaseLayer) { + if (m_paintingBaseLayer) { m_globalButtonMutex->lock(); - m_currentBaseLayer->drawCanvas(canvas); + m_paintingBaseLayer->drawCanvas(canvas); m_globalButtonMutex->unlock(); } return m_currentPictureCounter; @@ -263,11 +276,11 @@ void GLWebViewState::swapPages() int GLWebViewState::baseContentWidth() { - return m_currentBaseLayer ? m_currentBaseLayer->content()->width() : 0; + return m_paintingBaseLayer ? m_paintingBaseLayer->content()->width() : 0; } int GLWebViewState::baseContentHeight() { - return m_currentBaseLayer ? m_currentBaseLayer->content()->height() : 0; + return m_paintingBaseLayer ? m_paintingBaseLayer->content()->height() : 0; } void GLWebViewState::setViewport(SkRect& viewport, float scale) @@ -408,15 +421,11 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, #endif m_baseLayerLock.lock(); - BaseLayerAndroid* baseLayer = m_currentBaseLayer; + BaseLayerAndroid* baseLayer = m_paintingBaseLayer; SkSafeRef(baseLayer); - BaseLayerAndroid* baseForComposited = m_baseLayer; - SkSafeRef(baseForComposited); m_baseLayerLock.unlock(); - if (!baseLayer) { - SkSafeUnref(baseForComposited); - return false; - } + if (!baseLayer) + return false; float viewWidth = (viewport.fRight - viewport.fLeft) * TILE_PREFETCH_RATIO; float viewHeight = (viewport.fBottom - viewport.fTop) * TILE_PREFETCH_RATIO; @@ -431,16 +440,17 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, resetLayersDirtyArea(); - if (!baseForComposited || - (baseForComposited && !baseForComposited->countChildren())) { - SkSafeRef(baseLayer); - SkSafeUnref(baseForComposited); - baseForComposited = baseLayer; - } + LayerAndroid* compositedRoot = m_currentBaseLayerRoot; + LayerAndroid* paintingBaseLayerRoot = 0; + if (baseLayer && baseLayer->countChildren() >= 1) + paintingBaseLayerRoot = static_cast<LayerAndroid*>(baseLayer->getChild(0)); - LayerAndroid* compositedRoot = 0; - if (baseForComposited && baseForComposited->countChildren() >= 1) - compositedRoot = static_cast<LayerAndroid*>(baseForComposited->getChild(0)); + // when adding or removing layers, use the the paintingBaseLayer's tree so + // that content that moves to the base layer from a layer is synchronized + bool paintingHasLayers = (paintingBaseLayerRoot == 0); + bool currentHasLayers = (m_currentBaseLayerRoot == 0); + if (paintingHasLayers != currentHasLayers) + compositedRoot = paintingBaseLayerRoot; if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) XLOGC("WARNING, scale seems corrupted before update: %e", scale); @@ -461,9 +471,6 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, // gather the textures we can use TilesManager::instance()->gatherLayerTextures(); - if (compositedRoot != m_previouslyUsedRoot) - TilesManager::instance()->swapLayersTextures(m_previouslyUsedRoot, compositedRoot); - // set up zoom manager, shaders, etc. m_backgroundColor = baseLayer->getBackgroundColor(); double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale); @@ -473,10 +480,6 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, glBindBuffer(GL_ARRAY_BUFFER, 0); - SkSafeRef(compositedRoot); - SkSafeUnref(m_previouslyUsedRoot); - m_previouslyUsedRoot = compositedRoot; - ret |= TilesManager::instance()->invertedScreenSwitch(); if (ret) { @@ -532,7 +535,6 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, } #endif - SkSafeUnref(baseForComposited); SkSafeUnref(baseLayer); #ifdef DEBUG TilesManager::instance()->getTilesTracker()->showTrackTextures(); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 0bc1209..b2aab88 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -219,7 +219,6 @@ public: void resetFrameworkInval(); void addDirtyArea(const IntRect& rect); void resetLayersDirtyArea(); - LayerAndroid* previouslyUsedRoot() { return m_previouslyUsedRoot; } bool goingDown() { return m_goingDown; } bool goingLeft() { return m_goingLeft; } @@ -244,9 +243,9 @@ private: SkIRect m_futureViewportTileBounds; SkIRect m_preZoomBounds; android::Mutex m_baseLayerLock; - BaseLayerAndroid* m_baseLayer; + BaseLayerAndroid* m_paintingBaseLayer; BaseLayerAndroid* m_currentBaseLayer; - LayerAndroid* m_previouslyUsedRoot; + LayerAndroid* m_currentBaseLayerRoot; unsigned int m_currentPictureCounter; bool m_usePageA; diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index f35f768..d7a61aa 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -3367,6 +3367,10 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node if (!fake) { RenderTextControl* rtc = static_cast<RenderTextControl*> (renderer); + // Force an update of the navcache as this will fire off a + // message to WebView that *must* have an updated focus. + m_frameCacheOutOfDate = true; + updateFrameCache(); requestKeyboardWithSelection(focusNode, rtc->selectionStart(), rtc->selectionEnd()); } |