From d30efeae4fa6b64029cfa478fe80981232f502e5 Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 3 May 2012 19:55:39 -0700 Subject: Broaden fast inval path Bug: 6445600 Clip fast partial invals to the screen instead of an arbitrary size limit Change-Id: Iafcbcb427566db87420b8bfc54eb9148530913ce --- .../graphics/android/layers/LayerAndroid.cpp | 5 ++- .../graphics/android/rendering/Surface.cpp | 23 +++++------ Source/WebKit/android/jni/WebViewCore.cpp | 45 ++++++++++++---------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp index 535d211..a0cf61d 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp @@ -529,7 +529,10 @@ bool LayerAndroid::canUpdateWithBlit() { if (!m_content || !m_scale) return false; - PrerenderedInval* prerendered = m_content->prerenderForRect(m_dirtyRegion.getBounds()); + IntRect clip = clippedRect(); + IntRect dirty = m_dirtyRegion.getBounds(); + dirty.intersect(clip); + PrerenderedInval* prerendered = m_content->prerenderForRect(dirty); if (!prerendered) return false; // Check that the scales are "close enough" to produce the same rects diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index 437b8ff..c8dfd13 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp @@ -216,13 +216,11 @@ void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit) m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom, prepareArea, fullArea, this, useAggressiveRendering(), updateWithBlit); - if (updateWithBlit) { - for (size_t i = 0; i < m_layers.size(); i++) { - LayerContent* content = m_layers[i]->content(); - if (content) - content->clearPrerenders(); - } - } + } + for (size_t i = 0; i < m_layers.size(); i++) { + LayerContent* content = m_layers[i]->content(); + if (content) + content->clearPrerenders(); } } @@ -397,6 +395,13 @@ bool Surface::blitFromContents(Tile* tile) // Extract the dirty rect from the region. Note that this is *NOT* constrained // to this tile IntRect dirtyRect = tile->dirtyArea().getBounds(); + IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(), + tile->y() * TilesManager::tileHeight(), + TilesManager::tileWidth(), + TilesManager::tileHeight()); + FloatRect tileRectInDoc = tileRect; + tileRectInDoc.scale(1 / tile->scale()); + dirtyRect.intersect(enclosingIntRect(tileRectInDoc)); PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect); if (!prerenderedInval || prerenderedInval->bitmap.isNull()) return false; @@ -406,10 +411,6 @@ bool Surface::blitFromContents(Tile* tile) FloatRect screenDirty = dirtyRect; screenDirty.scale(tile->scale()); IntRect enclosingScreenDirty = enclosingIntRect(screenDirty); - IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(), - tile->y() * TilesManager::tileHeight(), - TilesManager::tileWidth(), - TilesManager::tileHeight()); enclosingScreenDirty.intersect(tileRect); if (enclosingScreenDirty.isEmpty()) return false; diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 34740a8..58341bb 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -123,6 +123,7 @@ #include "SkUtils.h" #include "Text.h" #include "TextIterator.h" +#include "TilesManager.h" #include "TypingCommand.h" #include "WebCache.h" #include "WebCoreFrameBridge.h" @@ -732,38 +733,42 @@ void WebViewCore::paintContents(WebCore::GraphicsContext* gc, WebCore::IntRect& SkCanvas* WebViewCore::createPrerenderCanvas(PrerenderedInval* prerendered) { - IntRect screen(m_scrollOffsetX, m_scrollOffsetY, m_screenWidth, m_screenHeight); - if (prerendered->area.isEmpty() || !prerendered->area.intersects(screen)) + if (prerendered->area.isEmpty()) return 0; + FloatRect scaleTemp(m_scrollOffsetX, m_scrollOffsetY, m_screenWidth, m_screenHeight); + scaleTemp.scale(m_scale); + IntRect visibleTileClip = enclosingIntRect(scaleTemp); FloatRect scaledArea = prerendered->area; scaledArea.scale(m_scale); IntRect enclosingScaledArea = enclosingIntRect(scaledArea); if (enclosingScaledArea.isEmpty()) return 0; + // "round out" the screen to tile boundaries so that we can clip yet still + // cover any visible tiles with the prerender + int tw = TilesManager::tileWidth(); + int th = TilesManager::tileHeight(); + float left = tw * (int) (visibleTileClip.x() / tw); + float top = th * (int) (visibleTileClip.y() / th); + float right = tw * (int) ceilf(visibleTileClip.maxX() / (float) tw); + float bottom = th * (int) ceilf(visibleTileClip.maxY() / (float) th); + visibleTileClip = IntRect(left, top, right - left, bottom - top); + enclosingScaledArea.intersect(visibleTileClip); + if (enclosingScaledArea.isEmpty()) + return 0; prerendered->screenArea = enclosingScaledArea; FloatRect enclosingDocArea(enclosingScaledArea); enclosingDocArea.scale(1 / m_scale); prerendered->area = enclosingIntRect(enclosingDocArea); if (prerendered->area.isEmpty()) return 0; - // TODO: We need a better heuristic for this. We should change this to: - // 1) Limit by area, not width/height (as we care more about the RAM than size) - // 2) Clip by the screen, but "round out" to make sure we cover partially - // visible tiles - int maxWidth = ceilf(m_screenWidth * m_scale); - int maxHeight = ceilf(m_screenHeight * m_scale); - if (enclosingScaledArea.width() <= maxWidth - && enclosingScaledArea.height() <= maxHeight) { - prerendered->bitmap.setConfig(SkBitmap::kARGB_8888_Config, - enclosingScaledArea.width(), - enclosingScaledArea.height()); - prerendered->bitmap.allocPixels(); - SkCanvas* bitmapCanvas = new SkCanvas(prerendered->bitmap); - bitmapCanvas->scale(m_scale, m_scale); - bitmapCanvas->translate(-enclosingDocArea.x(), -enclosingDocArea.y()); - return bitmapCanvas; - } - return 0; + prerendered->bitmap.setConfig(SkBitmap::kARGB_8888_Config, + enclosingScaledArea.width(), + enclosingScaledArea.height()); + prerendered->bitmap.allocPixels(); + SkCanvas* bitmapCanvas = new SkCanvas(prerendered->bitmap); + bitmapCanvas->scale(m_scale, m_scale); + bitmapCanvas->translate(-enclosingDocArea.x(), -enclosingDocArea.y()); + return bitmapCanvas; } void WebViewCore::notifyAnimationStarted() -- cgit v1.1