diff options
Diffstat (limited to 'WebCore')
7 files changed, 95 insertions, 10 deletions
diff --git a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp index 3462975..6d9fe04 100644 --- a/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp +++ b/WebCore/platform/graphics/android/BackedDoubleBufferedTexture.cpp @@ -137,7 +137,7 @@ bool BackedDoubleBufferedTexture::setOwner(TextureOwner* owner) // can't change the owner out from underneath that texture android::Mutex::Autolock lock(m_busyLock); if (!m_busy) { - if (m_owner) + if (m_owner && m_owner != owner) m_owner->removeTexture(this); m_owner = owner; return true; diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 1e7e209..57a53ab 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -174,6 +174,10 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale) nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds); } + bool zooming = false; + if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest) + zooming = true; + float transparency = 1; bool doSwap = false; @@ -209,8 +213,30 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale) TiledPage* tiledPage = m_glWebViewState->frontPage(); tiledPage->setScale(m_glWebViewState->currentScale()); const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds(); - tiledPage->prepare(goingDown, goingLeft, preZoomBounds); - tiledPage->draw(transparency, preZoomBounds); + + TiledPage* nextTiledPage = m_glWebViewState->backPage(); + + // We are now using an hybrid model -- during zooming or 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 (!zooming && !m_glWebViewState->moving()) { + if (!tiledPage->ready(preZoomBounds)) { + nextTiledPage->setScale(m_glWebViewState->currentScale()); + nextTiledPage->prepare(goingDown, goingLeft, preZoomBounds); + } + if (nextTiledPage->ready(preZoomBounds)) { + nextTiledPage->draw(transparency, preZoomBounds); + doSwap = true; + } else { + tiledPage->draw(transparency, preZoomBounds); + } + } else { + // Ask for the tiles and draw -- tiles may be out of date. + tiledPage->prepare(goingDown, goingLeft, preZoomBounds); + tiledPage->draw(transparency, preZoomBounds); + } bool ret = false; if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp index 35de698..c45b138 100644 --- a/WebCore/platform/graphics/android/BaseTile.cpp +++ b/WebCore/platform/graphics/android/BaseTile.cpp @@ -117,7 +117,7 @@ void BaseTile::reserveTexture() void BaseTile::removeTexture(BackedDoubleBufferedTexture* texture) { - XLOG("%x removeTexture res: %x...", this, m_texture); + XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page); // We update atomically, so paintBitmap() can see the correct value android::AutoMutex lock(m_atomicSync); if (m_texture == texture) @@ -164,7 +164,7 @@ void BaseTile::draw(float transparency, SkRect& rect) // No need to mutex protect reads of m_texture as it is only written to by // the consumer thread. if (!m_texture) { - XLOG("%x (%d, %d) trying to draw, but no m_texture!", this, x(), y()); + XLOG("%x on page %x (%d, %d) trying to draw, but no m_texture!", this, m_page, x(), y()); return; } diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index 45915e5..326f360 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -70,11 +70,14 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) , m_updateTime(-1) , m_transitionTime(-1) , m_baseLayer(0) + , m_currentBaseLayer(0) , m_currentPictureCounter(0) , m_usePageA(true) , m_globalButtonMutex(buttonMutex) + , m_baseLayerUpdate(true) { m_viewport.setEmpty(); + m_previousViewport.setEmpty(); m_futureViewportTileBounds.setEmpty(); m_viewportTileBounds.setEmpty(); m_preZoomBounds.setEmpty(); @@ -88,6 +91,7 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) GLWebViewState::~GLWebViewState() { + m_currentBaseLayer->safeUnref(); delete m_tiledPageA; delete m_tiledPageB; #ifdef DEBUG_COUNT @@ -107,10 +111,30 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const IntRect& rect) m_baseLayer = layer; if (m_baseLayer) { m_baseLayer->setGLWebViewState(this); + } + // We only update the layers if we are not currently + // waiting for a tiledPage to be painted + if (m_baseLayerUpdate) { + m_currentBaseLayer->safeUnref(); + m_currentBaseLayer = layer; + m_currentBaseLayer->safeRef(); inval(rect); + } else { + m_invalidateRect.unite(rect); } } +void GLWebViewState::unlockBaseLayerUpdate() { + m_baseLayerUpdate = true; + android::Mutex::Autolock lock(m_baseLayerLock); + m_currentBaseLayer->safeUnref(); + m_currentBaseLayer = m_baseLayer; + m_currentBaseLayer->safeRef(); + inval(m_invalidateRect); + IntRect empty; + m_invalidateRect = empty; +} + void GLWebViewState::setExtra(BaseLayerAndroid* layer, SkPicture& picture, const IntRect& rect) { @@ -136,9 +160,9 @@ void GLWebViewState::inval(const IntRect& rect) unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) { android::Mutex::Autolock lock(m_baseLayerLock); - if (m_baseLayer) { + if (m_currentBaseLayer) { m_globalButtonMutex->lock(); - m_baseLayer->drawCanvas(canvas); + m_currentBaseLayer->drawCanvas(canvas); m_globalButtonMutex->unlock(); } return m_currentPictureCounter; @@ -189,6 +213,11 @@ float GLWebViewState::transparency(double currentTime) return fmin(1, fmax(0, t)); } +TiledPage* GLWebViewState::sibling(TiledPage* page) +{ + return (page == m_tiledPageA) ? m_tiledPageB : m_tiledPageA; +} + TiledPage* GLWebViewState::frontPage() { android::Mutex::Autolock lock(m_tiledPageLock); @@ -213,16 +242,17 @@ void GLWebViewState::swapPages() int GLWebViewState::baseContentWidth() { - return m_baseLayer ? m_baseLayer->getWidth() : 0; + return m_currentBaseLayer ? m_currentBaseLayer->getWidth() : 0; } int GLWebViewState::baseContentHeight() { - return m_baseLayer ? m_baseLayer->getHeight() : 0; + return m_currentBaseLayer ? m_currentBaseLayer->getHeight() : 0; } void GLWebViewState::setViewport(SkRect& viewport, float scale) { + m_previousViewport = m_viewport; if (m_viewport == viewport) return; diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h index 8d2216e..3f933ca 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ b/WebCore/platform/graphics/android/GLWebViewState.h @@ -173,6 +173,7 @@ public: void setExtra(BaseLayerAndroid*, SkPicture&, const IntRect&); void scheduleUpdate(const double& currentTime, const SkIRect& viewport, float scale); + TiledPage* sibling(TiledPage* page); TiledPage* frontPage(); TiledPage* backPage(); void swapPages(); @@ -191,6 +192,20 @@ public: unsigned int currentPictureCounter() const { return m_currentPictureCounter; } + 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; + } + private: void inval(const IntRect& rect); // caller must hold m_baseLayerLock @@ -212,17 +227,22 @@ private: double m_transitionTime; android::Mutex m_tiledPageLock; SkRect m_viewport; + SkRect m_previousViewport; SkIRect m_viewportTileBounds; SkIRect m_futureViewportTileBounds; SkIRect m_preZoomBounds; android::Mutex m_baseLayerLock; BaseLayerAndroid* m_baseLayer; + BaseLayerAndroid* m_currentBaseLayer; unsigned int m_currentPictureCounter; bool m_usePageA; TiledPage* m_tiledPageA; TiledPage* m_tiledPageB; SkIRect m_lastInval; android::Mutex* m_globalButtonMutex; + + bool m_baseLayerUpdate; + IntRect m_invalidateRect; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp index 868a870..79509dd 100644 --- a/WebCore/platform/graphics/android/TiledPage.cpp +++ b/WebCore/platform/graphics/android/TiledPage.cpp @@ -67,6 +67,7 @@ TiledPage::TiledPage(int id, GLWebViewState* state) , m_invScale(1) , m_glWebViewState(state) , m_latestPictureInval(0) + , m_prepare(false) { // This value must be at least 1 greater than the max number of allowed // textures. This is because prepare() asks for a tile before it reserves @@ -231,6 +232,8 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound // update the tiles distance from the viewport updateTileState(tileBounds); + m_prepare = true; + m_glWebViewState->lockBaseLayerUpdate(); int firstTileX = tileBounds.fLeft; int firstTileY = tileBounds.fTop; @@ -291,6 +294,9 @@ bool TiledPage::ready(const SkIRect& tileBounds) if (!m_glWebViewState) return false; + if (!m_invalRegion.isEmpty() && !m_prepare) + return false; + for (int x = tileBounds.fLeft; x < tileBounds.fRight; x++) { for (int y = tileBounds.fTop; y < tileBounds.fBottom; y++) { BaseTile* t = getBaseTile(x, y); @@ -298,6 +304,8 @@ bool TiledPage::ready(const SkIRect& tileBounds) return false; } } + m_prepare = false; + m_glWebViewState->unlockBaseLayerUpdate(); return true; } @@ -341,7 +349,7 @@ TiledPage* TiledPage::sibling() { if (!m_glWebViewState) return 0; - return (m_glWebViewState->frontPage() == this) ? m_glWebViewState->backPage() : this; + return m_glWebViewState->sibling(this); } } // namespace WebCore diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h index 72e20cd..a194ba5 100644 --- a/WebCore/platform/graphics/android/TiledPage.h +++ b/WebCore/platform/graphics/android/TiledPage.h @@ -99,6 +99,7 @@ private: // within the page, not in content/view pixel coordinates. SkRegion m_invalRegion; unsigned int m_latestPictureInval; + bool m_prepare; }; } // namespace WebCore |