diff options
5 files changed, 74 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 0ab28d7..1aefd86 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -54,6 +54,12 @@ #endif // DEBUG +// TODO: dynamically determine based on DPI +#define PREFETCH_SCALE_MODIFIER 0.3 +#define PREFETCH_OPACITY 1 +#define PREFETCH_X_DIST 1 +#define PREFETCH_Y_DIST 2 + namespace WebCore { using namespace android; @@ -116,6 +122,49 @@ void BaseLayerAndroid::drawCanvas(SkCanvas* canvas) } #if USE(ACCELERATED_COMPOSITING) + +void BaseLayerAndroid::prefetchBasePicture(SkRect& viewport, float currentScale, + TiledPage* prefetchTiledPage) +{ + SkIRect bounds; + float prefetchScale = currentScale * PREFETCH_SCALE_MODIFIER; + + float invTileWidth = (prefetchScale) + / TilesManager::instance()->tileWidth(); + float invTileHeight = (prefetchScale) + / TilesManager::instance()->tileHeight(); + bool goingDown = m_glWebViewState->goingDown(); + bool goingLeft = m_glWebViewState->goingLeft(); + + + XLOG("fetch rect %f %f %f %f, scale %f", + viewport.fLeft, + viewport.fTop, + viewport.fRight, + viewport.fBottom, + scale); + + bounds.fLeft = static_cast<int>(floorf(viewport.fLeft * invTileWidth)) - PREFETCH_X_DIST; + bounds.fTop = static_cast<int>(floorf(viewport.fTop * invTileHeight)) - PREFETCH_Y_DIST; + bounds.fRight = static_cast<int>(ceilf(viewport.fRight * invTileWidth)) + PREFETCH_X_DIST; + bounds.fBottom = static_cast<int>(ceilf(viewport.fBottom * invTileHeight)) + PREFETCH_Y_DIST; + + XLOG("prefetch rect %d %d %d %d, scale %f, preparing page %p", + bounds.fLeft, bounds.fTop, + bounds.fRight, bounds.fBottom, + scale * PREFETCH_SCALE, + prefetchTiledPage); + + prefetchTiledPage->setScale(prefetchScale); + prefetchTiledPage->updateTileDirtiness(bounds); + prefetchTiledPage->prepare(goingDown, goingLeft, bounds, + TiledPage::ExpandedBounds); + prefetchTiledPage->swapBuffersIfReady(bounds, + prefetchScale, + TiledPage::SwapWhateverIsReady); + prefetchTiledPage->draw(PREFETCH_OPACITY, bounds); +} + bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double currentTime, bool* buffersSwappedPtr) { @@ -183,6 +232,13 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, bool scrolling = m_scrollState != NotScrolling; bool zooming = ZoomManager::kNoScaleRequest != zoomManager->scaleRequestState(); + // prefetch in the nextTiledPage if unused by zooming (even if not scrolling + // since we want the tiles to be ready before they're needed) + bool usePrefetchPage = !zooming; + nextTiledPage->setIsPrefetchPage(usePrefetchPage); + if (usePrefetchPage) + prefetchBasePicture(viewport, scale, nextTiledPage); + // When we aren't zooming, we should TRY and swap tile buffers if they're // ready. When scrolling, we swap whatever's ready. Otherwise, buffer until // the entire page is ready and then swap. diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h index a42a372..26fd158 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -66,6 +66,8 @@ public: void swapExtra(BaseLayerAndroid* base) { m_extra.swap(base->m_extra); } private: #if USE(ACCELERATED_COMPOSITING) + void prefetchBasePicture(SkRect& viewport, float currentScale, + TiledPage* prefetchTiledPage); bool drawBasePictureInGL(SkRect& viewport, float scale, double currentTime, bool* buffersSwappedPtr); diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp index aa3f320..19b49f1 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp @@ -81,6 +81,10 @@ int PaintTileOperation::priority() unsigned long long drawDelta = currentDraw - m_tile->drawCount(); int priority = 100000 * (int)std::min(drawDelta, (unsigned long long)1000); + // prioritize the prefetch page, if it exists + if (!m_tile->page() || !m_tile->page()->isPrefetchPage()) + priority += 200000; + // prioritize unpainted tiles, within the same drawCount if (m_tile->frontTexture()) priority += 50000; diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp index ede7d1b..2b8ebcc 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.cpp +++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp @@ -31,6 +31,8 @@ #include "GLUtils.h" #include "IntRect.h" #include "PaintTileOperation.h" +#include "SkPaint.h" +#include "SkPaintFlagsDrawFilter.h" #include "TilesManager.h" #include <cutils/log.h> @@ -65,6 +67,7 @@ TiledPage::TiledPage(int id, GLWebViewState* state) , m_glWebViewState(state) , m_latestPictureInval(0) , m_prepare(false) + , m_isPrefetchPage(false) { m_baseTiles = new BaseTile[TilesManager::getMaxTextureAllocation() + 1]; #ifdef DEBUG_COUNT @@ -366,9 +369,15 @@ void TiledPage::draw(float transparency, const SkIRect& tileBounds) bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) { + // TODO: consider other flags so the pre-rendered tiles aren't so ugly + static SkPaintFlagsDrawFilter prefetchFilter(SkPaint::kAllFlags, 0); + if (!m_glWebViewState) return false; + if (isPrefetchPage()) + canvas->setDrawFilter(&prefetchFilter); + *pictureUsed = m_glWebViewState->paintBaseLayerContent(canvas); return true; } diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h index 946421c..c903abc 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.h +++ b/Source/WebCore/platform/graphics/android/TiledPage.h @@ -98,6 +98,8 @@ public: void updateBaseTileSize(); bool scrollingDown() { return m_scrollingDown; } SkIRect* expandedTileBounds() { return &m_expandedTileBounds; } + bool isPrefetchPage() { return m_isPrefetchPage; } + void setIsPrefetchPage(bool isPrefetch) { m_isPrefetchPage = isPrefetch; } private: void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds); @@ -127,6 +129,7 @@ private: bool m_prepare; bool m_scrollingDown; SkIRect m_expandedTileBounds; + bool m_isPrefetchPage; }; } // namespace WebCore |