summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2011-09-21 11:32:15 -0700
committerChris Craik <ccraik@google.com>2011-09-21 15:46:36 -0700
commit176a19c613e0c025ecd5f82730a24c0ff128edef (patch)
treed3d3d3bafc7cb60c7ec0955eefdbd519e553cb6b /Source
parentb0d9f9482ecf8cde08d50e4dff6a2f16d2148966 (diff)
downloadexternal_webkit-176a19c613e0c025ecd5f82730a24c0ff128edef.zip
external_webkit-176a19c613e0c025ecd5f82730a24c0ff128edef.tar.gz
external_webkit-176a19c613e0c025ecd5f82730a24c0ff128edef.tar.bz2
Prefetch browser content with tiled page
bug:5262519 Use the tiled page not used by content rendering to render much fewer tiles for the same content, at an inflated scale. These prefetched tiles are prioritized for painting above all others, so that content is (almost) always visible on the base layer. Change-Id: I598b7925cb68beef632f828df3ae522a0b21e2b4
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp56
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.h3
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