diff options
Diffstat (limited to 'Source')
37 files changed, 455 insertions, 266 deletions
diff --git a/Source/JavaScriptCore/wtf/HashTraits.h b/Source/JavaScriptCore/wtf/HashTraits.h index fba5afe..7deeb3a 100644 --- a/Source/JavaScriptCore/wtf/HashTraits.h +++ b/Source/JavaScriptCore/wtf/HashTraits.h @@ -28,6 +28,8 @@ namespace WTF { + class String; + using std::pair; using std::make_pair; @@ -88,6 +90,7 @@ namespace WTF { }; template<typename P> struct HashTraits<RefPtr<P> > : SimpleClassHashTraits<RefPtr<P> > { }; + template<> struct HashTraits<String> : SimpleClassHashTraits<String> { }; // special traits for pairs, helpful for their use in HashMap implementation diff --git a/Source/JavaScriptCore/wtf/text/StringHash.h b/Source/JavaScriptCore/wtf/text/StringHash.h index c47c1d8..497184d 100644 --- a/Source/JavaScriptCore/wtf/text/StringHash.h +++ b/Source/JavaScriptCore/wtf/text/StringHash.h @@ -179,8 +179,6 @@ namespace WTF { } }; - template<> struct HashTraits<String> : SimpleClassHashTraits<String> { }; - } using WTF::StringHash; diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp index 91c0629..fe25a93 100644 --- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp +++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp @@ -293,6 +293,8 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url } #if ENABLE(LINK_PREFETCH) case CachedResource::LinkResource: + if (!m_document->settings()->linkPrefetchEnabled()) + return false; break; #endif } diff --git a/Source/WebCore/page/Settings.cpp b/Source/WebCore/page/Settings.cpp index c26a0fc..f668f3e 100644 --- a/Source/WebCore/page/Settings.cpp +++ b/Source/WebCore/page/Settings.cpp @@ -149,6 +149,9 @@ Settings::Settings(Page* page) // they can't use by. Leaving enabled for now to not change existing behavior. , m_downloadableBinaryFontsEnabled(true) , m_xssAuditorEnabled(false) +#if ENABLE(LINK_PREFETCH) + , m_linkPrefetchEnabled(true) +#endif , m_acceleratedCompositingEnabled(true) , m_acceleratedCompositingFor3DTransformsEnabled(true) , m_acceleratedCompositingForVideoEnabled(true) @@ -823,6 +826,13 @@ void Settings::setXSSAuditorEnabled(bool xssAuditorEnabled) m_xssAuditorEnabled = xssAuditorEnabled; } +#if ENABLE(LINK_PREFETCH) +void Settings::setLinkPrefetchEnabled(bool linkPrefetchEnabled) +{ + m_linkPrefetchEnabled = linkPrefetchEnabled; +} +#endif + void Settings::setAcceleratedCompositingEnabled(bool enabled) { if (m_acceleratedCompositingEnabled == enabled) diff --git a/Source/WebCore/page/Settings.h b/Source/WebCore/page/Settings.h index 2bb222d..2cf7715 100644 --- a/Source/WebCore/page/Settings.h +++ b/Source/WebCore/page/Settings.h @@ -352,6 +352,11 @@ namespace WebCore { void setXSSAuditorEnabled(bool); bool xssAuditorEnabled() const { return m_xssAuditorEnabled; } +#if ENABLE(LINK_PREFETCH) + void setLinkPrefetchEnabled(bool); + bool linkPrefetchEnabled() const { return m_linkPrefetchEnabled; } +#endif + void setCanvasUsesAcceleratedDrawing(bool); bool canvasUsesAcceleratedDrawing() const { return m_canvasUsesAcceleratedDrawing; } @@ -567,6 +572,9 @@ namespace WebCore { bool m_acceleratedDrawingEnabled : 1; bool m_downloadableBinaryFontsEnabled : 1; bool m_xssAuditorEnabled : 1; +#if ENABLE(LINK_PREFETCH) + bool m_linkPrefetchEnabled : 1; +#endif bool m_acceleratedCompositingEnabled : 1; bool m_acceleratedCompositingFor3DTransformsEnabled : 1; bool m_acceleratedCompositingForVideoEnabled : 1; diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 7243031..ddaf181 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -82,7 +82,7 @@ BaseTile::~BaseTile() // All the following functions must be called from the main GL thread. -void BaseTile::setContents(int x, int y, float scale) +void BaseTile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile) { // TODO: investigate whether below check/discard is necessary if ((m_x != x) @@ -97,6 +97,8 @@ void BaseTile::setContents(int x, int y, float scale) m_y = y; m_scale = scale; m_drawCount = TilesManager::instance()->getDrawGLCount(); + if (isExpandedPrefetchTile) + m_drawCount--; // deprioritize expanded painting region } void BaseTile::reserveTexture() @@ -154,17 +156,11 @@ void BaseTile::markAsDirty(const SkRegion& dirtyArea) // Check if we actually intersect with the area bool intersect = false; SkRegion::Iterator cliperator(dirtyArea); - int tileWidth = TilesManager::instance()->tileWidth(); - int tileHeight = TilesManager::instance()->tileHeight(); - if (m_isLayerTile) { - tileWidth = TilesManager::instance()->layerTileWidth(); - tileHeight = TilesManager::instance()->layerTileHeight(); - } SkRect realTileRect; SkRect dirtyRect; while (!cliperator.done()) { dirtyRect.set(cliperator.rect()); - if (intersectWithRect(m_x, m_y, tileWidth, tileHeight, + if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(), m_scale, dirtyRect, realTileRect)) { intersect = true; break; @@ -211,16 +207,16 @@ void BaseTile::setRepaintPending(bool pending) m_repaintPending = pending; } -void BaseTile::drawGL(float opacity, const SkRect& rect, float scale, +bool BaseTile::drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform) { if (m_x < 0 || m_y < 0 || m_scale != scale) - return; + return false; // No need to mutex protect reads of m_backTexture as it is only written to by // the consumer thread. if (!m_frontTexture) - return; + return false; // Early return if set to un-usable in purpose! m_atomicSync.lock(); @@ -228,9 +224,10 @@ void BaseTile::drawGL(float opacity, const SkRect& rect, float scale, m_atomicSync.unlock(); if (!isTexturePainted) - return; + return false; m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform); + return true; } bool BaseTile::isTileReady() diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h index afb1db2..93ec287 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.h +++ b/Source/WebCore/platform/graphics/android/BaseTile.h @@ -93,13 +93,14 @@ public: bool isLayerTile() { return m_isLayerTile; } - void setContents(int x, int y, float scale); + void setContents(int x, int y, float scale, bool isExpandedPrefetchTile); void reserveTexture(); bool isTileReady(); - void drawGL(float opacity, const SkRect& rect, float scale, + // Return false when real draw didn't happen for any reason. + bool drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform); // the only thread-safe function called by the background thread diff --git a/Source/WebCore/platform/graphics/android/CanvasLayer.cpp b/Source/WebCore/platform/graphics/android/CanvasLayer.cpp index fea429f..5409fef 100644 --- a/Source/WebCore/platform/graphics/android/CanvasLayer.cpp +++ b/Source/WebCore/platform/graphics/android/CanvasLayer.cpp @@ -132,8 +132,8 @@ void CanvasLayer::canvasResized(HTMLCanvasElement*) const IntSize& size = m_canvas->size(); m_dirtyCanvas.setRect(0, 0, size.width(), size.height()); // If we are smaller than one tile, don't bother using a surface texture - if (size.width() <= TilesManager::layerTileWidth() - && size.height() <= TilesManager::layerTileHeight()) + if (size.width() <= TilesManager::tileWidth() + && size.height() <= TilesManager::tileHeight()) m_texture->setSize(IntSize()); else m_texture->setSize(size); diff --git a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp index c6dd174..88822df 100644 --- a/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/FontDataAndroid.cpp @@ -56,8 +56,12 @@ void SimpleFontData::platformInit() m_fontMetrics.setAscent(a); m_fontMetrics.setDescent(d); m_fontMetrics.setXHeight(SkScalarToFloat(-skiaFontMetrics.fAscent) * 0.56f); // hack I stole from the window's port - m_fontMetrics.setLineSpacing(a + d); - m_fontMetrics.setLineGap(SkScalarToFloat(skiaFontMetrics.fLeading)); + float lineGap = SkScalarToFloat(skiaFontMetrics.fLeading); + if (platformData().orientation() == Vertical && lineGap == 0) { + lineGap = skiaFontMetrics.fAvgCharWidth * 0.56f; + } + m_fontMetrics.setLineGap(lineGap); + m_fontMetrics.setLineSpacing(a + d + lineGap); if (platformData().orientation() == Vertical && !isTextOrientationFallback()) { static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a'); diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp index fb69deb..beb62db 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.cpp +++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp @@ -644,19 +644,21 @@ void GLUtils::convertToTransformationMatrix(const float* matrix, TransformationM matrix[12], matrix[13], matrix[14], matrix[15]); } -void GLUtils::drawBackground(const Color* backgroundColor) +void GLUtils::clearBackgroundIfOpaque(const Color* backgroundColor) { - if (TilesManager::instance()->invertedScreen()) { - float color = 1.0 - ((((float) backgroundColor->red() / 255.0) + - ((float) backgroundColor->green() / 255.0) + - ((float) backgroundColor->blue() / 255.0)) / 3.0); - glClearColor(color, color, color, 1); - } else { - glClearColor((float)backgroundColor->red() / 255.0, - (float)backgroundColor->green() / 255.0, - (float)backgroundColor->blue() / 255.0, 1); + if (!backgroundColor->hasAlpha()) { + if (TilesManager::instance()->invertedScreen()) { + float color = 1.0 - ((((float) backgroundColor->red() / 255.0) + + ((float) backgroundColor->green() / 255.0) + + ((float) backgroundColor->blue() / 255.0)) / 3.0); + glClearColor(color, color, color, 1); + } else { + glClearColor((float)backgroundColor->red() / 255.0, + (float)backgroundColor->green() / 255.0, + (float)backgroundColor->blue() / 255.0, 1); + } + glClear(GL_COLOR_BUFFER_BIT); } - glClear(GL_COLOR_BUFFER_BIT); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/GLUtils.h b/Source/WebCore/platform/graphics/android/GLUtils.h index 70ebbd6..f24ea0d 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.h +++ b/Source/WebCore/platform/graphics/android/GLUtils.h @@ -86,7 +86,7 @@ public: static bool isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor); static bool skipTransferForPureColor(const TileRenderInfo* renderInfo, const SkBitmap& bitmap); - static void drawBackground(const Color* backgroundColor); + static void clearBackgroundIfOpaque(const Color* backgroundColor); static bool allowGLLog(); static double m_previousLogTime; static int m_currentLogCounter; diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index b7458e8..4c4ca3d 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -37,6 +37,7 @@ #include "GLUtils.h" #include "ImagesManager.h" #include "LayerAndroid.h" +#include "private/hwui/DrawGlInfo.h" #include "ScrollableLayerAndroid.h" #include "SkPath.h" #include "TilesManager.h" @@ -156,10 +157,9 @@ void GLWebViewState::setViewport(const SkRect& viewport, float scale) m_isViewportScrolling = m_viewport != viewport && SkRect::Intersects(m_viewport, viewport); m_viewport = viewport; - ALOGV("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f currentScale: %.2f futureScale: %.2f)", + ALOGV("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f )", m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom, - m_viewport.width(), m_viewport.height(), scale, - zoomManager()->currentScale(), zoomManager()->futureScale()); + m_viewport.width(), m_viewport.height(), scale); } #ifdef MEASURES_PERF @@ -302,10 +302,11 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded) return (m_layersRenderingMode != layersRenderingMode && invalBase); } -bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, - IntRect& webViewRect, int titleBarHeight, - IntRect& clip, float scale, - bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr) +int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, + IntRect& webViewRect, int titleBarHeight, + IntRect& clip, float scale, + bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, + bool shouldDraw) { TilesManager* tilesManager = TilesManager::instance(); tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop, @@ -336,7 +337,9 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, // Upload any pending ImageTexture // Return true if we still have some images to upload. // TODO: upload as many textures as possible within a certain time limit - bool ret = ImagesManager::instance()->prepareTextures(this); + int returnFlags = 0; + if (ImagesManager::instance()->prepareTextures(this)) + returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) { ALOGW("WARNING, scale seems corrupted after update: %e", scale); @@ -348,14 +351,13 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale); - TexturesResult nbTexturesNeeded; bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering; m_glExtras.setViewport(viewport); - ret |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport, - scale, fastSwap, - collectionsSwappedPtr, newCollectionHasAnimPtr, - &nbTexturesNeeded); + returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport, + scale, fastSwap, + collectionsSwappedPtr, newCollectionHasAnimPtr, + &nbTexturesNeeded, shouldDraw); int nbTexturesForImages = ImagesManager::instance()->nbTextures(); ALOGV("*** We have %d textures for images, %d full, %d clipped, total %d / %d", @@ -364,15 +366,17 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, nbTexturesNeeded.clipped + nbTexturesForImages); nbTexturesNeeded.full += nbTexturesForImages; nbTexturesNeeded.clipped += nbTexturesForImages; - ret |= setLayersRenderingMode(nbTexturesNeeded); + + if (setLayersRenderingMode(nbTexturesNeeded)) + returnFlags |= uirenderer::DrawGlInfo::kStatusDraw | uirenderer::DrawGlInfo::kStatusInvoke; glBindBuffer(GL_ARRAY_BUFFER, 0); // Clean up GL textures for video layer. tilesManager->videoLayerManager()->deleteUnusedTextures(); - if (ret) { - // ret==true && empty inval region means we've inval'd everything, + if (returnFlags & uirenderer::DrawGlInfo::kStatusDraw) { + // returnFlags & kStatusDraw && empty inval region means we've inval'd everything, // but don't have new content. Keep redrawing full view (0,0,0,0) // until tile generation catches up and we swap pages. bool fullScreenInval = m_frameworkLayersInval.isEmpty(); @@ -402,9 +406,10 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, } } - showFrameInfo(rect, *collectionsSwappedPtr); + if (shouldDraw) + showFrameInfo(rect, *collectionsSwappedPtr); - return ret; + return returnFlags; } void GLWebViewState::showFrameInfo(const IntRect& rect, bool collectionsSwapped) diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 85c90fd..82ef16e 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -49,9 +49,6 @@ // HW limit or save further in the GPU memory consumption. #define TILE_PREFETCH_DISTANCE 1 -// ratio of content to view required for prefetching to enable -#define TILE_PREFETCH_RATIO 1.2 - namespace WebCore { class BaseLayerAndroid; @@ -180,10 +177,11 @@ public: bool setLayersRenderingMode(TexturesResult&); - bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, - IntRect& webViewRect, int titleBarHeight, - IntRect& clip, float scale, - bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr); + int drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, + IntRect& webViewRect, int titleBarHeight, + IntRect& clip, float scale, + bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, + bool shouldDraw); #ifdef MEASURES_PERF void dumpMeasures(); diff --git a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp index bdc8005..7d6c809 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp @@ -108,11 +108,15 @@ void GraphicsContext::platformDestroy() void GraphicsContext::savePlatformState() { + if (paintingDisabled()) + return; platformContext()->save(); } void GraphicsContext::restorePlatformState() { + if (paintingDisabled()) + return; platformContext()->restore(); } @@ -301,36 +305,50 @@ void GraphicsContext::endTransparencyLayer() void GraphicsContext::setupFillPaint(SkPaint* paint) { + if (paintingDisabled()) + return; platformContext()->setupPaintFill(paint); } void GraphicsContext::setupStrokePaint(SkPaint* paint) { + if (paintingDisabled()) + return; platformContext()->setupPaintStroke(paint, 0); } bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset) { + if (paintingDisabled()) + return false; return platformContext()->setupPaintShadow(paint, offset); } void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace) { + if (paintingDisabled()) + return; platformContext()->setStrokeColor(c); } void GraphicsContext::setPlatformStrokeThickness(float f) { + if (paintingDisabled()) + return; platformContext()->setStrokeThickness(f); } void GraphicsContext::setPlatformStrokeStyle(StrokeStyle style) { + if (paintingDisabled()) + return; platformContext()->setStrokeStyle(style); } void GraphicsContext::setPlatformFillColor(const Color& c, ColorSpace) { + if (paintingDisabled()) + return; platformContext()->setFillColor(c); } @@ -501,30 +519,40 @@ void GraphicsContext::setPlatformShouldAntialias(bool useAA) void GraphicsContext::setPlatformFillGradient(Gradient* fillGradient) { + if (paintingDisabled()) + return; SkShader* shader = extractShader(0, fillGradient); platformContext()->setFillShader(shader); } void GraphicsContext::setPlatformFillPattern(Pattern* fillPattern) { + if (paintingDisabled()) + return; SkShader* shader = extractShader(fillPattern, 0); platformContext()->setFillShader(shader); } void GraphicsContext::setPlatformStrokeGradient(Gradient* strokeGradient) { + if (paintingDisabled()) + return; SkShader* shader = extractShader(0, strokeGradient); platformContext()->setStrokeShader(shader); } void GraphicsContext::setPlatformStrokePattern(Pattern* strokePattern) { + if (paintingDisabled()) + return; SkShader* shader = extractShader(strokePattern, 0); platformContext()->setStrokeShader(shader); } AffineTransform GraphicsContext::getCTM() const { + if (paintingDisabled()) + return AffineTransform(); const SkMatrix& m = platformContext()->getTotalMatrix(); return AffineTransform(SkScalarToDouble(m.getScaleX()), // a SkScalarToDouble(m.getSkewY()), // b diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp index 11a449a..7d3f2b8 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp +++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp @@ -183,8 +183,8 @@ bool ImageTexture::prepareGL(GLWebViewState* state) if (!m_texture) return false; - IntRect visibleArea(0, 0, m_image->width(), m_image->height()); - m_texture->prepareGL(state, 1.0, visibleArea, this); + IntRect unclippedArea(0, 0, m_image->width(), m_image->height()); + m_texture->prepareGL(state, 1.0, unclippedArea, unclippedArea, this); if (m_texture->isReady()) { m_texture->swapTiles(); return false; diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index 167f7e7..b40e00a 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -909,10 +909,10 @@ void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style) canvas->drawLine(0, 0, w, h, paint); canvas->drawLine(0, h, w, 0, paint); - canvas->drawLine(0, 0, 0, h, paint); - canvas->drawLine(0, h, w, h, paint); - canvas->drawLine(w, h, w, 0, paint); - canvas->drawLine(w, 0, 0, 0, paint); + canvas->drawLine(0, 0, 0, h-1, paint); + canvas->drawLine(0, h-1, w-1, h-1, paint); + canvas->drawLine(w-1, h-1, w-1, 0, paint); + canvas->drawLine(w-1, 0, 0, 0, paint); } if (m_fixedPosition) diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/LayerGroup.cpp index 5d8b726..05180a4 100644 --- a/Source/WebCore/platform/graphics/android/LayerGroup.cpp +++ b/Source/WebCore/platform/graphics/android/LayerGroup.cpp @@ -156,6 +156,23 @@ IntRect LayerGroup::visibleArea() return rect; } +IntRect LayerGroup::unclippedArea() +{ + if (singleLayer()) + return getFirstLayer()->unclippedArea(); + return m_unclippedArea; +} + +bool LayerGroup::useAggressiveRendering() +{ + // When the background is translucent, 0 < alpha < 255, we had to turn off + // low res to avoid artifacts from double drawing. + // TODO: avoid double drawing for low res tiles. + return isBase() + && (!m_background.alpha() + || !m_background.hasAlpha()); +} + void LayerGroup::prepareGL(bool layerTilesDisabled) { bool tilesDisabled = layerTilesDisabled && !isBase(); @@ -174,11 +191,14 @@ void LayerGroup::prepareGL(bool layerTilesDisabled) } else { bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors IntRect prepareArea = computePrepareArea(); + IntRect fullArea = unclippedArea(); ALOGV("prepareGL on LG %p with DTT %p, %d layers", this, m_dualTiledTexture, m_layers.size()); + m_dualTiledTexture->prepareGL(getFirstLayer()->state(), allowZoom, - prepareArea, this); + prepareArea, fullArea, + this, useAggressiveRendering()); } } @@ -199,8 +219,10 @@ bool LayerGroup::drawGL(bool layerTilesDisabled) if (m_dualTiledTexture && !tilesDisabled) { ALOGV("drawGL on LG %p with DTT %p", this, m_dualTiledTexture); + // TODO: why this visibleArea is different from visibleRect at zooming for base? IntRect drawArea = visibleArea(); - askRedraw |= m_dualTiledTexture->drawGL(drawArea, opacity(), drawTransform()); + m_dualTiledTexture->drawGL(drawArea, opacity(), drawTransform(), + useAggressiveRendering(), background()); } // draw member layers (draws image textures, glextras) @@ -233,7 +255,7 @@ IntRect LayerGroup::computePrepareArea() { && !isBase() && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { - area = singleLayer() ? getFirstLayer()->unclippedArea() : m_unclippedArea; + area = unclippedArea(); double total = ((double) area.width()) * ((double) area.height()); if (total > MAX_UNCLIPPED_AREA) @@ -301,6 +323,13 @@ float LayerGroup::opacity() return 1.0; } +Color* LayerGroup::background() +{ + if (!isBase() || !m_background.isValid()) + return 0; + return &m_background; +} + const TransformationMatrix* LayerGroup::drawTransform() { // single layer groups query the layer's draw transform, while multi-layer diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.h b/Source/WebCore/platform/graphics/android/LayerGroup.h index edfb30d..8e9608d 100644 --- a/Source/WebCore/platform/graphics/android/LayerGroup.h +++ b/Source/WebCore/platform/graphics/android/LayerGroup.h @@ -26,6 +26,7 @@ #ifndef LayerGroup_h #define LayerGroup_h +#include "Color.h" #include "IntRect.h" #include "TilePainter.h" #include "Vector.h" @@ -48,25 +49,32 @@ public: bool tryUpdateLayerGroup(LayerGroup* oldLayerGroup); void addLayer(LayerAndroid* layer, const TransformationMatrix& transform); - IntRect visibleArea(); void prepareGL(bool layerTilesDisabled); bool drawGL(bool layerTilesDisabled); void swapTiles(); bool isReady(); - IntRect computePrepareArea(); void computeTexturesAmount(TexturesResult* result); LayerAndroid* getFirstLayer() { return m_layers[0]; } - bool singleLayer() { return m_layers.size() == 1; } bool needsTexture() { return m_needsTexture; } bool hasText() { return m_hasText; } bool isBase(); + void setBackground(Color background) { m_background = background; } // TilePainter methods virtual bool paint(BaseTile* tile, SkCanvas* canvas); virtual float opacity(); + virtual Color* background(); + private: + IntRect computePrepareArea(); + IntRect visibleArea(); + IntRect unclippedArea(); + bool singleLayer() { return m_layers.size() == 1; } + void updateBackground(const Color& background); + bool useAggressiveRendering(); + const TransformationMatrix* drawTransform(); IntRect m_unclippedArea; TransformationMatrix m_drawTransform; @@ -75,6 +83,8 @@ private: bool m_needsTexture; bool m_hasText; Vector<LayerAndroid*> m_layers; + + Color m_background; }; class LayerMergeState { diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp index 910ba21..4ae1f31 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp @@ -37,10 +37,12 @@ namespace WebCore { -PaintTileOperation::PaintTileOperation(BaseTile* tile, TilePainter* painter, GLWebViewState* state) +PaintTileOperation::PaintTileOperation(BaseTile* tile, TilePainter* painter, + GLWebViewState* state, bool isLowResPrefetch) : m_tile(tile) , m_painter(painter) , m_state(state) + , m_isLowResPrefetch(isLowResPrefetch) { if (m_tile) m_tile->setRepaintPending(true); @@ -84,6 +86,10 @@ int PaintTileOperation::priority() int priority = 200000; + // prioritize low res while scrolling + if (m_isLowResPrefetch) + priority = m_state->isScrolling() ? 0 : 400000; + // prioritize higher draw count unsigned long long currentDraw = TilesManager::instance()->getDrawGLCount(); unsigned long long drawDelta = currentDraw - m_tile->drawCount(); diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/PaintTileOperation.h index 468f6d2..afd2fc1 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h @@ -38,7 +38,8 @@ class ImageTexture; class PaintTileOperation : public QueuedOperation { public: - PaintTileOperation(BaseTile* tile, TilePainter* painter, GLWebViewState* state); + PaintTileOperation(BaseTile* tile, TilePainter* painter, + GLWebViewState* state, bool isLowResPrefetch); virtual ~PaintTileOperation(); virtual bool operator==(const QueuedOperation* operation); virtual void run(); @@ -51,6 +52,7 @@ private: BaseTile* m_tile; TilePainter* m_painter; GLWebViewState* m_state; + bool m_isLowResPrefetch; }; class ScaleFilter : public OperationFilter { diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp index 6beed16..4398146 100644 --- a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp +++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp @@ -91,6 +91,8 @@ void PictureLayerContent::draw(SkCanvas* canvas) return; android::Mutex::Autolock lock(m_drawLock); + SkRect r = SkRect::MakeWH(width(), height()); + canvas->clipRect(r); canvas->drawPicture(*m_picture); } diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp index c2c008b..8b72b0a 100644 --- a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp +++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp @@ -1,6 +1,7 @@ #include "config.h" #include "PictureSetLayerContent.h" +#include "SkCanvas.h" #include "SkPicture.h" namespace WebCore { @@ -21,6 +22,8 @@ void PictureSetLayerContent::draw(SkCanvas* canvas) return; android::Mutex::Autolock lock(m_drawLock); + SkRect r = SkRect::MakeWH(width(), height()); + canvas->clipRect(r); m_pictureSet.draw(canvas); } diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp index bcfe7d8..a012c8b 100644 --- a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp @@ -23,11 +23,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define LOG_TAG "RasterRenderer" +#define LOG_NDEBUG 1 + #include "config.h" #include "RasterRenderer.h" #if USE(ACCELERATED_COMPOSITING) +#include "AndroidLog.h" #include "GLUtils.h" #include "SkBitmap.h" #include "SkBitmapRef.h" @@ -66,8 +70,16 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can g_bitmap->setIsOpaque(false); g_bitmap->eraseARGB(0, 0, 0, 0); } else { - g_bitmap->setIsOpaque(true); - g_bitmap->eraseARGB(255, 255, 255, 255); + Color defaultBackground = Color::white; + Color* background = renderInfo.tilePainter->background(); + if (!background) { + ALOGV("No background color for base layer!"); + background = &defaultBackground; + } + ALOGV("setupCanvas use background on Base Layer %x", background->rgb()); + g_bitmap->setIsOpaque(!background->hasAlpha()); + g_bitmap->eraseARGB(background->alpha(), background->red(), + background->green(), background->blue()); } SkDevice* device = new SkDevice(*g_bitmap); diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp index d1b70f7..257e68f 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -502,7 +502,7 @@ void ShaderProgram::drawQuad(const SkRect& geometry, int textureId, float opacit setProjectionMatrix(geometry, projectionMatrix); finalMatrix = projectionMatrix; } - setBlendingState(opacity < 1.0); + setBlendingState(opacity < 1.0 || pureColor.hasAlpha()); drawQuadInternal(type, finalMatrix, textureId, opacity, textureTarget, texFilter, pureColor); } diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp index 1ea192c..78c3fbb 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp @@ -63,8 +63,11 @@ SurfaceCollection::SurfaceCollection(LayerAndroid* layer) // set the layergroups' and tiledpages' update count, to be drawn on painted tiles unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates(); - for (unsigned int i = 0; i < m_layerGroups.size(); i++) + for (unsigned int i = 0; i < m_layerGroups.size(); i++) { m_layerGroups[i]->setUpdateCount(updateCount); + if (m_layerGroups[i]->isBase()) + m_layerGroups[i]->setBackground(getBackground()); + } #ifdef DEBUG_COUNT ClassTracker::instance()->increment("SurfaceCollection"); diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp index 52bcaf0..91dba3c 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp +++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp @@ -31,6 +31,7 @@ #include "AndroidLog.h" #include "LayerGroup.h" +#include "private/hwui/DrawGlInfo.h" #include "TilesManager.h" #include "SurfaceCollection.h" @@ -147,7 +148,7 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne m_paintingCollection = newCollection; m_paintingCollection->setIsPainting(m_drawingCollection); } - return m_paintingCollection && TilesManager::instance()->useDoubleBuffering(); + return m_drawingCollection && TilesManager::instance()->useDoubleBuffering(); } void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y) @@ -160,18 +161,18 @@ void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y) m_drawingCollection->updateScrollableLayer(layerId, x, y); } -bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, +int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, SkRect& visibleRect, float scale, bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, - TexturesResult* texturesResultPtr) + TexturesResult* texturesResultPtr, bool shouldDraw) { m_fastSwapMode |= enterFastSwapMode; - ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d", - m_drawingCollection, m_paintingCollection, m_queuedCollection, m_fastSwapMode); + ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d shouldDraw %d", + m_drawingCollection, m_paintingCollection, + m_queuedCollection, m_fastSwapMode, shouldDraw); - bool ret = false; bool didCollectionSwap = false; if (m_paintingCollection) { ALOGV("preparing painting collection %p", m_paintingCollection); @@ -197,6 +198,23 @@ bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, m_drawingCollection->computeTexturesAmount(texturesResultPtr); } + // ask for kStatusInvoke while painting, kStatusDraw if we have content to be redrawn next frame + // returning 0 indicates all painting complete, no framework inval needed. + int returnFlags = 0; + + if (m_paintingCollection) + returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; + + if (!shouldDraw) { + if (didCollectionSwap) { + m_drawingCollection->swapTiles(); + returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; + } + + return returnFlags; + } + + // =========================================================================== // Don't have a drawing collection, draw white background Color background = Color::white; if (m_drawingCollection) { @@ -214,7 +232,7 @@ bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, m_fastSwapMode = false; } else { // drawing isn't ready, must redraw - ret = true; + returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; } m_drawingCollection->evaluateAnimations(currentTime); @@ -227,16 +245,15 @@ bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, } // Start doing the actual GL drawing. - GLUtils::drawBackground(&background); - if (m_drawingCollection) - ret |= m_drawingCollection->drawGL(visibleRect); - - if (m_paintingCollection) { - ALOGV("still have painting collection %p", m_paintingCollection); - return true; - } - - return ret; + ALOGV("background is %x", background.rgb()); + // If background is opaque, we can safely and efficiently clear it here. + // Otherwise, we have to calculate all the missing tiles and blend the background. + GLUtils::clearBackgroundIfOpaque(&background); + if (m_drawingCollection && m_drawingCollection->drawGL(visibleRect)) + returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; + + ALOGV("returnFlags %d, m_paintingCollection %d ", returnFlags, m_paintingCollection); + return returnFlags; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h index 304d57f..cc98899 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h +++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h @@ -49,10 +49,10 @@ public: void updateScrollableLayer(int layerId, int x, int y); - bool drawGL(double currentTime, IntRect& viewRect, + int drawGL(double currentTime, IntRect& viewRect, SkRect& visibleRect, float scale, bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, - TexturesResult* texturesResultPtr); + TexturesResult* texturesResultPtr, bool shouldDraw); private: void swap(); diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index 34e877e..a5dafa9 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -34,6 +34,7 @@ class SkCanvas; namespace WebCore { class BaseTile; +class Color; class TilePainter : public SkRefCnt { // TODO: investigate webkit threadsafe ref counting @@ -43,6 +44,7 @@ public: virtual float opacity() { return 1.0; } enum SurfaceType { Painted, Image }; virtual SurfaceType type() { return Painted; } + virtual Color* background() { return 0; } unsigned int getUpdateCount() { return m_updateCount; } void setUpdateCount(unsigned int updateCount) { m_updateCount = updateCount; } diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index 51e9b35..7087dc7 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -37,6 +37,10 @@ #include <wtf/CurrentTime.h> +#define LOW_RES_PREFETCH_SCALE_MODIFIER 0.3f +#define EXPANDED_BOUNDS_INFLATE 1 +#define EXPANDED_PREFETCH_BOUNDS_Y_INFLATE 1 + namespace WebCore { TiledTexture::~TiledTexture() @@ -73,6 +77,14 @@ bool TiledTexture::isReady() || !tilesVisible || tilesAllReady; } +bool TiledTexture::isMissingContent() +{ + for (unsigned int i = 0; i < m_tiles.size(); i++) + if (m_tiles[i]->isTileVisible(m_area) && !m_tiles[i]->frontTexture()) + return true; + return false; +} + void TiledTexture::swapTiles() { int swaps = 0; @@ -98,8 +110,8 @@ IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale) return computedArea; } - int tileWidth = TilesManager::instance()->layerTileWidth(); - int tileHeight = TilesManager::instance()->layerTileHeight(); + int tileWidth = TilesManager::tileWidth(); + int tileHeight = TilesManager::tileHeight(); computedArea.setX(area.x() / tileWidth); computedArea.setY(area.y() / tileHeight); @@ -111,7 +123,8 @@ IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale) } void TiledTexture::prepareGL(GLWebViewState* state, float scale, - const IntRect& prepareArea, TilePainter* painter) + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool isLowResPrefetch, bool useExpandPrefetch) { // first, how many tiles do we need m_area = computeTilesArea(prepareArea, scale); @@ -151,15 +164,36 @@ void TiledTexture::prepareGL(GLWebViewState* state, float scale, m_dirtyRegion.setEmpty(); } + // prepare standard bounds (clearing ExpandPrefetch flag) for (int i = 0; i < m_area.width(); i++) { if (goingDown) { for (int j = 0; j < m_area.height(); j++) - prepareTile(m_area.x() + i, m_area.y() + j, painter, state); + prepareTile(m_area.x() + i, m_area.y() + j, + painter, state, isLowResPrefetch, false); } else { for (int j = m_area.height() - 1; j >= 0; j--) - prepareTile(m_area.x() + i, m_area.y() + j, painter, state); + prepareTile(m_area.x() + i, m_area.y() + j, + painter, state, isLowResPrefetch, false); } } + + // prepare expanded bounds + if (useExpandPrefetch) { + IntRect fullArea = computeTilesArea(unclippedArea, scale); + IntRect expandedArea = m_area; + expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); + + if (isLowResPrefetch) + expandedArea.inflate(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); + + // clip painting area to content + expandedArea.intersect(fullArea); + + for (int i = expandedArea.x(); i < expandedArea.maxX(); i++) + for (int j = expandedArea.y(); j < expandedArea.maxY(); j++) + if (!m_area.contains(i, j)) + prepareTile(i, j, painter, state, isLowResPrefetch, true); + } } void TiledTexture::markAsDirty(const SkRegion& invalRegion) @@ -169,7 +203,8 @@ void TiledTexture::markAsDirty(const SkRegion& invalRegion) m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); } -void TiledTexture::prepareTile(int x, int y, TilePainter* painter, GLWebViewState* state) +void TiledTexture::prepareTile(int x, int y, TilePainter* painter, + GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch) { BaseTile* tile = getTile(x, y); if (!tile) { @@ -179,7 +214,8 @@ void TiledTexture::prepareTile(int x, int y, TilePainter* painter, GLWebViewStat } ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter); - tile->setContents(x, y, m_scale); + + tile->setContents(x, y, m_scale, isExpandPrefetch); // TODO: move below (which is largely the same for layers / tiled page) into // prepareGL() function @@ -189,7 +225,8 @@ void TiledTexture::prepareTile(int x, int y, TilePainter* painter, GLWebViewStat if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) { ALOGV("painting TT %p's tile %d %d for LG %p", this, x, y, painter); - PaintTileOperation *operation = new PaintTileOperation(tile, painter, state); + PaintTileOperation *operation = new PaintTileOperation(tile, painter, + state, isLowResPrefetch); TilesManager::instance()->scheduleOperation(operation); } } @@ -221,25 +258,34 @@ int TiledTexture::nbTextures(IntRect& area, float scale) return numberTextures; } -bool TiledTexture::drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform) +void TiledTexture::drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, + const Color* background) { m_area = computeTilesArea(visibleArea, m_scale); if (m_area.width() == 0 || m_area.height() == 0) - return false; + return; - float m_invScale = 1 / m_scale; - const float tileWidth = TilesManager::layerTileWidth() * m_invScale; - const float tileHeight = TilesManager::layerTileHeight() * m_invScale; + float invScale = 1 / m_scale; + const float tileWidth = TilesManager::tileWidth() * invScale; + const float tileHeight = TilesManager::tileHeight() * invScale; int drawn = 0; - bool askRedraw = false; + + SkRegion missingRegion; + bool translucentBaseSurface = + background ? (background->hasAlpha() && background->alpha() > 0) : false; + if (translucentBaseSurface) { + SkIRect totalArea = SkIRect::MakeXYWH(m_area.x(), m_area.y(), + m_area.width(), m_area.height()); + missingRegion = SkRegion(totalArea); + } + for (unsigned int i = 0; i < m_tiles.size(); i++) { BaseTile* tile = m_tiles[i]; bool tileInView = tile->isTileVisible(m_area); if (tileInView) { - askRedraw |= !tile->isTileReady(); SkRect rect; rect.fLeft = tile->x() * tileWidth; rect.fTop = tile->y() * tileHeight; @@ -248,19 +294,53 @@ bool TiledTexture::drawGL(const IntRect& visibleArea, float opacity, ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d", tile, tile->isLayerTile(), tile->x(), tile->y(), tile->scale(), m_scale, tile->isTileReady(), tile->isDirty()); - tile->drawGL(opacity, rect, m_scale, transform); + + bool success = tile->drawGL(opacity, rect, m_scale, transform); + if (translucentBaseSurface && success) { + // Cut the successful drawn tile area from the missing region. + missingRegion.op(SkIRect::MakeXYWH(tile->x(), tile->y(), 1, 1), + SkRegion::kDifference_Op); + } if (tile->frontTexture()) drawn++; } - if (m_isBaseSurface) - TilesManager::instance()->getProfiler()->nextTile(tile, m_invScale, tileInView); + if (translucentBaseSurface) + TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView); } - ALOGV("TT %p drew %d tiles, redraw due to notready %d, scale %f", - this, drawn, askRedraw, m_scale); - // need to redraw if some visible tile wasn't ready - return askRedraw; + // Draw missing Regions with blend turned on + if (translucentBaseSurface) + drawMissingRegion(missingRegion, opacity, background); + + ALOGV("TT %p drew %d tiles, scale %f", + this, drawn, m_scale); +} + +void TiledTexture::drawMissingRegion(const SkRegion& region, float opacity, + const Color* background) +{ + SkRegion::Iterator iterator(region); + const float tileWidth = TilesManager::tileWidth() / m_scale; + const float tileHeight = TilesManager::tileHeight() / m_scale; + ShaderProgram* shader = TilesManager::instance()->shader(); + while (!iterator.done()) { + SkIRect r = iterator.rect(); + SkRect rect; + rect.fLeft = r.x() * tileWidth; + rect.fTop = r.y() * tileHeight; + rect.fRight = rect.fLeft + tileWidth * r.width(); + rect.fBottom = rect.fTop + tileHeight * r.height(); + ALOGV("draw tile x y, %d %d (%d %d) opacity %f", r.x(), r.y(), + r.width(), r.height(), opacity); + // Skia is using pre-multiplied color. + Color postAlpha = Color(background->red() * background->alpha() / 255, + background->green() * background->alpha() / 255, + background->blue() * background->alpha() / 255, + background->alpha() ); + shader->drawQuad(rect, 0, opacity, postAlpha); + iterator.next(); + } } void TiledTexture::removeTiles() @@ -278,24 +358,10 @@ void TiledTexture::discardTextures() m_tiles[i]->discardTextures(); } -bool TiledTexture::owns(BaseTileTexture* texture) -{ - for (unsigned int i = 0; i < m_tiles.size(); i++) { - BaseTile* tile = m_tiles[i]; - if (tile->frontTexture() == texture) - return true; - if (tile->backTexture() == texture) - return true; - } - return false; -} - DualTiledTexture::DualTiledTexture(bool isBaseSurface) { - m_textureA = new TiledTexture(isBaseSurface); - m_textureB = new TiledTexture(isBaseSurface); - m_frontTexture = m_textureA; - m_backTexture = m_textureB; + m_frontTexture = new TiledTexture(isBaseSurface); + m_backTexture = new TiledTexture(isBaseSurface); m_scale = -1; m_futureScale = -1; m_zooming = false; @@ -303,18 +369,14 @@ DualTiledTexture::DualTiledTexture(bool isBaseSurface) DualTiledTexture::~DualTiledTexture() { - delete m_textureA; - delete m_textureB; + delete m_frontTexture; + delete m_backTexture; } void DualTiledTexture::prepareGL(GLWebViewState* state, bool allowZoom, - const IntRect& prepareArea, TilePainter* painter) + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool aggressiveRendering) { - // If we are zooming, we will use the previously used area, to prevent the - // frontTexture to try to allocate more tiles than what it has already - if (!m_zooming) - m_preZoomPrepareArea = prepareArea; - float scale = state->scale(); if (scale > 1 && !allowZoom) scale = 1; @@ -330,39 +392,46 @@ void DualTiledTexture::prepareGL(GLWebViewState* state, bool allowZoom, m_zooming = true; } + bool useExpandPrefetch = aggressiveRendering; ALOGV("Prepare DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d, f %p, b %p", this, scale, m_scale, m_futureScale, m_zooming, m_frontTexture, m_backTexture); - if (m_scale > 0 && !m_zooming) - m_frontTexture->prepareGL(state, m_scale, m_preZoomPrepareArea, painter); - - // If we had a scheduled update - if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) { - m_backTexture->prepareGL(state, m_futureScale, prepareArea, painter); - if (m_backTexture->isReady()) { + if (!m_zooming) { + m_frontTexture->prepareGL(state, m_scale, + prepareArea, unclippedArea, painter, false, useExpandPrefetch); + if (aggressiveRendering) { + // prepare the back tiled texture to render content in low res + float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER; + m_backTexture->prepareGL(state, lowResPrefetchScale, + prepareArea, unclippedArea, painter, true, useExpandPrefetch); m_backTexture->swapTiles(); - swap(); + } + } else if (m_zoomUpdateTime < WTF::currentTime()) { + m_backTexture->prepareGL(state, m_futureScale, + prepareArea, unclippedArea, painter, false, useExpandPrefetch); + if (m_backTexture->isReady()) { + // zooming completed, swap the textures and new front tiles + swapTiledTextures(); + + m_frontTexture->swapTiles(); + m_backTexture->discardTextures(); + + m_scale = m_futureScale; m_zooming = false; } } } -void DualTiledTexture::swap() +void DualTiledTexture::drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, + bool aggressiveRendering, const Color* background) { - m_frontTexture = m_frontTexture == m_textureA ? m_textureB : m_textureA; - m_backTexture = m_backTexture == m_textureA ? m_textureB : m_textureA; - m_scale = m_futureScale; - m_backTexture->discardTextures(); -} + // draw low res prefetch page, if needed + if (aggressiveRendering && !m_zooming && m_frontTexture->isMissingContent()) + m_backTexture->drawGL(visibleArea, opacity, transform); -bool DualTiledTexture::drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform) -{ - bool needsRepaint = m_frontTexture->drawGL(visibleArea, opacity, transform); - needsRepaint |= m_zooming; - needsRepaint |= (m_scale <= 0); - return needsRepaint; + m_frontTexture->drawGL(visibleArea, opacity, transform, background); } void DualTiledTexture::markAsDirty(const SkRegion& dirtyArea) @@ -377,13 +446,6 @@ void DualTiledTexture::swapTiles() m_frontTexture->swapTiles(); } -bool DualTiledTexture::owns(BaseTileTexture* texture) -{ - bool owns = m_textureA->owns(texture); - owns |= m_textureB->owns(texture); - return owns; -} - void DualTiledTexture::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer) { // TODO: shouldn't use layer, as this DTT may paint multiple layers @@ -419,4 +481,11 @@ void DualTiledTexture::computeTexturesAmount(TexturesResult* result, LayerAndroi result->full += nbTexturesUnclipped; } +void DualTiledTexture::swapTiledTextures() +{ + TiledTexture* temp = m_frontTexture; + m_frontTexture = m_backTexture; + m_backTexture = temp; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h index b879d54..7a6c499 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.h +++ b/Source/WebCore/platform/graphics/android/TiledTexture.h @@ -43,8 +43,7 @@ namespace WebCore { class TiledTexture { public: TiledTexture(bool isBaseSurface) - : m_prevTileX(0) - , m_prevTileY(0) + : m_prevTileY(0) , m_scale(1) , m_isBaseSurface(isBaseSurface) { @@ -56,38 +55,38 @@ public: virtual ~TiledTexture(); - IntRect computeTilesArea(const IntRect& contentArea, float scale); + static IntRect computeTilesArea(const IntRect& contentArea, float scale); void prepareGL(GLWebViewState* state, float scale, - const IntRect& prepareArea, TilePainter* painter); + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool isLowResPrefetch = false, + bool useExpandPrefetch = false); void swapTiles(); - bool drawGL(const IntRect& visibleArea, float opacity, const TransformationMatrix* transform); + void drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, const Color* background = 0); - void prepareTile(int x, int y, TilePainter* painter, GLWebViewState* state); + void prepareTile(int x, int y, TilePainter* painter, + GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch); void markAsDirty(const SkRegion& dirtyArea); BaseTile* getTile(int x, int y); void removeTiles(); void discardTextures(); - bool owns(BaseTileTexture* texture); - float scale() { return m_scale; } bool isReady(); + bool isMissingContent(); int nbTextures(IntRect& area, float scale); private: - bool tileIsVisible(BaseTile* tile); - + void drawMissingRegion(const SkRegion& region, float opacity, const Color* tileBackground); Vector<BaseTile*> m_tiles; - // tile coordinates in viewport, set in prepareGL() IntRect m_area; SkRegion m_dirtyRegion; - int m_prevTileX; int m_prevTileY; float m_scale; @@ -100,21 +99,22 @@ public: DualTiledTexture(bool isBaseSurface); ~DualTiledTexture(); void prepareGL(GLWebViewState* state, bool allowZoom, - const IntRect& prepareArea, TilePainter* painter); + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool aggressiveRendering); void swapTiles(); - void swap(); - bool drawGL(const IntRect& visibleArea, float opacity, const TransformationMatrix* transform); + void drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, bool aggressiveRendering, + const Color* background); void markAsDirty(const SkRegion& dirtyArea); - bool owns(BaseTileTexture* texture); void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer); void discardTextures() { - m_textureA->discardTextures(); - m_textureB->discardTextures(); + m_frontTexture->discardTextures(); + m_backTexture->discardTextures(); } bool isReady() { - return !m_zooming && m_frontTexture->isReady(); + return !m_zooming && m_frontTexture->isReady() && m_scale > 0; } int nbTextures(IntRect& area, float scale) @@ -126,18 +126,17 @@ public: } private: + void swapTiledTextures(); + // Delay before we schedule a new tile at the new scale factor static const double s_zoomUpdateDelay = 0.2; // 200 ms TiledTexture* m_frontTexture; TiledTexture* m_backTexture; - TiledTexture* m_textureA; - TiledTexture* m_textureB; float m_scale; float m_futureScale; double m_zoomUpdateTime; bool m_zooming; - IntRect m_preZoomPrepareArea; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index 1e9aee4..eeedc07 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -56,8 +56,6 @@ #define MAX_TEXTURE_ALLOCATION ((6+TILE_PREFETCH_DISTANCE*2)*(5+TILE_PREFETCH_DISTANCE*2)*4) #define TILE_WIDTH 256 #define TILE_HEIGHT 256 -#define LAYER_TILE_WIDTH 256 -#define LAYER_TILE_HEIGHT 256 #define BYTES_PER_PIXEL 4 // 8888 config @@ -127,7 +125,7 @@ void TilesManager::allocateTiles() int nbLayersTexturesAllocated = 0; for (int i = 0; i < nbLayersTexturesToAllocate; i++) { BaseTileTexture* texture = new BaseTileTexture( - layerTileWidth(), layerTileHeight()); + tileWidth(), tileHeight()); // the atomic load ensures that the texture has been fully initialized // before we pass a pointer for other threads to operate on BaseTileTexture* loadedTexture = @@ -140,7 +138,7 @@ void TilesManager::allocateTiles() nbTexturesAllocated, m_textures.size(), m_textures.size() * TILE_WIDTH * TILE_HEIGHT * 4 / 1024 / 1024, nbLayersTexturesAllocated, m_tilesTextures.size(), - m_tilesTextures.size() * LAYER_TILE_WIDTH * LAYER_TILE_HEIGHT * 4 / 1024 / 1024); + m_tilesTextures.size() * tileWidth() * tileHeight() * 4 / 1024 / 1024); } void TilesManager::discardTextures(bool allTextures, bool glTextures) @@ -432,16 +430,6 @@ float TilesManager::tileHeight() return TILE_HEIGHT; } -float TilesManager::layerTileWidth() -{ - return LAYER_TILE_WIDTH; -} - -float TilesManager::layerTileHeight() -{ - return LAYER_TILE_HEIGHT; -} - TilesManager* TilesManager::instance() { if (!gInstance) { diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h index eed99c2..05fc1af 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/TilesManager.h @@ -88,8 +88,6 @@ public: void setMaxLayerTextureCount(int max); static float tileWidth(); static float tileHeight(); - static float layerTileWidth(); - static float layerTileHeight(); void allocateTiles(); diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index 5e16152..207fe9a 100644 --- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -238,11 +238,7 @@ void ChromeClientAndroid::addMessageToConsole(MessageSource, MessageType, Messag android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->addMessageToConsole(message, lineNumber, sourceID, msgLevel); } -void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) -{ - android::WebViewCore::getWebViewCore(m_webFrame->page()->mainFrame()->view())->formDidBlur(node); -} - +void ChromeClientAndroid::formDidBlur(const WebCore::Node* node) { notImplemented(); } bool ChromeClientAndroid::canRunBeforeUnloadConfirmPanel() { return true; } bool ChromeClientAndroid::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) { String url = frame->document()->documentURI(); diff --git a/Source/WebKit/android/jni/WebSettings.cpp b/Source/WebKit/android/jni/WebSettings.cpp index 65ac360..cec44c1 100644 --- a/Source/WebKit/android/jni/WebSettings.cpp +++ b/Source/WebKit/android/jni/WebSettings.cpp @@ -118,6 +118,9 @@ struct FieldIds { mGeolocationEnabled = env->GetFieldID(clazz, "mGeolocationEnabled", "Z"); mGeolocationDatabasePath = env->GetFieldID(clazz, "mGeolocationDatabasePath", "Ljava/lang/String;"); mXSSAuditorEnabled = env->GetFieldID(clazz, "mXSSAuditorEnabled", "Z"); +#if ENABLE(LINK_PREFETCH) + mLinkPrefetchEnabled = env->GetFieldID(clazz, "mLinkPrefetchEnabled", "Z"); +#endif mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, "mJavaScriptCanOpenWindowsAutomatically", "Z"); mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); @@ -245,6 +248,9 @@ struct FieldIds { jfieldID mGeolocationEnabled; jfieldID mGeolocationDatabasePath; jfieldID mXSSAuditorEnabled; +#if ENABLE(LINK_PREFETCH) + jfieldID mLinkPrefetchEnabled; +#endif #if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) jfieldID mDatabasePath; jfieldID mDatabasePathHasBeenSet; @@ -545,6 +551,11 @@ public: flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled); s->setXSSAuditorEnabled(flag); +#if ENABLE(LINK_PREFETCH) + flag = env->GetBooleanField(obj, gFieldIds->mLinkPrefetchEnabled); + s->setLinkPrefetchEnabled(flag); +#endif + size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity); if (size > 0) { s->setUsesPageCache(true); diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 3fc17e3..540b1dd 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -351,7 +351,6 @@ struct WebViewCore::JavaGlue { jmethodID m_getDeviceMotionService; jmethodID m_getDeviceOrientationService; jmethodID m_addMessageToConsole; - jmethodID m_formDidBlur; jmethodID m_focusNodeChanged; jmethodID m_getPluginClass; jmethodID m_showFullScreenPlugin; @@ -421,7 +420,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m , m_textFieldInitDataGlue(new TextFieldInitDataGlue) , m_mainFrame(mainframe) , m_popupReply(0) - , m_blurringNodePointer(0) , m_blockTextfieldUpdates(false) , m_focusBoundsChanged(false) , m_skipContentDraw(false) @@ -487,7 +485,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_getDeviceMotionService = GetJMethod(env, clazz, "getDeviceMotionService", "()Landroid/webkit/DeviceMotionService;"); m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;"); m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V"); - m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V"); m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(ILandroid/webkit/WebViewCore$WebKitHitTest;)V"); m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;"); m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;II)V"); @@ -874,16 +871,25 @@ BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region) #if USE(ACCELERATED_COMPOSITING) // We set the background color + Color background = Color::white; if (m_mainFrame && m_mainFrame->document() && m_mainFrame->document()->body()) { + bool hasCSSBackground = false; + Document* document = m_mainFrame->document(); RefPtr<RenderStyle> style = document->styleForElementIgnoringPendingStylesheets(document->body()); if (style->hasBackground()) { - Color color = style->visitedDependentColor(CSSPropertyBackgroundColor); - if (color.isValid() && color.alpha() > 0) - base->setBackgroundColor(color); + background = style->visitedDependentColor(CSSPropertyBackgroundColor); + hasCSSBackground = true; + } + + WebCore::FrameView* view = m_mainFrame->view(); + if (view) { + Color viewBackground = view->baseBackgroundColor(); + background = hasCSSBackground ? viewBackground.blend(background) : viewBackground; } } + base->setBackgroundColor(background); // We update the layers ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client()); @@ -3476,15 +3482,6 @@ void WebViewCore::popupReply(const int* array, int count) } } -void WebViewCore::formDidBlur(const WebCore::Node* node) -{ - // If the blur is on a text input, keep track of the node so we can - // hide the soft keyboard when the new focus is set, if it is not a - // text input. - if (isTextInput(node)) - m_blurringNodePointer = reinterpret_cast<int>(node); -} - // This is a slightly modified Node::nextNodeConsideringAtomicNodes() with the // extra constraint of limiting the search to inside a containing parent WebCore::Node* nextNodeWithinParent(WebCore::Node* parent, WebCore::Node* start) @@ -3508,6 +3505,7 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) { if (node) { if (isTextInput(node)) { + bool showKeyboard = true; initEditField(node); WebCore::RenderTextControl* rtc = toRenderTextControl(node); if (rtc && node->hasTagName(HTMLNames::inputTag)) { @@ -3524,10 +3522,11 @@ void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) autoFill->formFieldFocused(inputElement); } #endif - } else if (!fake) { - requestKeyboard(false); - } + } else + showKeyboard = false; } + if (!fake) + requestKeyboard(showKeyboard); } else if (!fake && !nodeIsPlugin(node)) { // not a text entry field, put away the keyboard. clearTextEntry(); @@ -3545,12 +3544,7 @@ void WebViewCore::focusNodeChanged(WebCore::Node* newFocus) if (!javaObject.get()) return; if (isTextInput(newFocus)) - initializeTextInput(newFocus); - else if (m_blurringNodePointer) { - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_formDidBlur, m_blurringNodePointer); - checkException(env); - m_blurringNodePointer = 0; - } + initializeTextInput(newFocus, true); HitTestResult focusHitResult; focusHitResult.setInnerNode(newFocus); focusHitResult.setInnerNonSharedNode(newFocus); diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index 5926991..23568bb 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -135,12 +135,6 @@ namespace android { // Followings are called from native WebCore to Java - /** - * Notification that a form was blurred. Pass a message to hide the - * keyboard if it was showing for that Node. - * @param Node The Node that blurred. - */ - void formDidBlur(const WebCore::Node*); void focusNodeChanged(WebCore::Node*); /** @@ -701,7 +695,7 @@ namespace android { * it is a text input field then initEditField is called and * auto-fill information is requested for HTML form input fields. */ - void initializeTextInput(WebCore::Node* node, bool fake = false); + void initializeTextInput(WebCore::Node* node, bool fake); /** * Gets the input type a Node. NONE is returned if it isn't an @@ -766,7 +760,6 @@ namespace android { struct TextFieldInitDataGlue* m_textFieldInitDataGlue; WebCore::Frame* m_mainFrame; WebCoreReply* m_popupReply; - int m_blurringNodePointer; PictureSet m_content; // the set of pictures to draw SkRegion m_addInval; // the accumulated inval region (not yet drawn) SkRegion m_rebuildInval; // the accumulated region for rebuilt pictures diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 37291de..9907e6f 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -248,13 +248,13 @@ void scrollRectOnScreen(const IntRect& rect) viewInvalidate(); } -bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, +int drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::IntRect& webViewRect, int titleBarHeight, - WebCore::IntRect& clip, float scale, int extras) + WebCore::IntRect& clip, float scale, int extras, bool shouldDraw) { #if USE(ACCELERATED_COMPOSITING) if (!m_baseLayer) - return false; + return 0; if (!m_glWebViewState) { TilesManager::instance()->setHighEndGfx(m_isHighEndGfx); @@ -270,12 +270,12 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, // if the zoom manager is still initializing. We will be redrawn // once the correct scale is set if (!m_visibleRect.isFinite()) - return false; + return 0; bool treesSwapped = false; bool newTreeHasAnim = false; - bool ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect, + int ret = m_glWebViewState->drawGL(viewRect, m_visibleRect, invalRect, webViewRect, titleBarHeight, clip, scale, - &treesSwapped, &newTreeHasAnim); + &treesSwapped, &newTreeHasAnim, shouldDraw); if (treesSwapped) { ALOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!"); JNIEnv* env = JSC::Bindings::getJNIEnv(); @@ -285,10 +285,9 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, checkException(env); } } - if (ret) - return !m_isDrawingPaused; + return m_isDrawingPaused ? 0 : ret; #endif - return false; + return 0; } PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool split) @@ -688,8 +687,8 @@ private: // local state for WebView class GLDrawFunctor : Functor { public: GLDrawFunctor(WebView* _wvInstance, - bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, - WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint), + int (WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, + WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint, bool), WebCore::IntRect _viewRect, float _scale, int _extras) { wvInstance = _wvInstance; funcPtr = _funcPtr; @@ -714,16 +713,15 @@ class GLDrawFunctor : Functor { WebCore::IntRect clip(info->clipLeft, info->clipTop, info->clipRight - info->clipLeft, info->clipBottom - info->clipTop); + bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw); TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer); - - bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, - titlebarHeight, clip, scale, extras); - if (retVal) { + int returnFlags = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, + titlebarHeight, clip, scale, extras, shouldDraw); + if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) { IntRect finalInval; - if (inval.isEmpty()) { + if (inval.isEmpty()) finalInval = webViewRect; - retVal = true; - } else { + else { finalInval.setX(webViewRect.x() + inval.x()); finalInval.setY(webViewRect.y() + titlebarHeight + inval.y()); finalInval.setWidth(inval.width()); @@ -734,8 +732,9 @@ class GLDrawFunctor : Functor { info->dirtyRight = finalInval.maxX(); info->dirtyBottom = finalInval.maxY(); } - // return 1 if invalidation needed, 0 otherwise - return retVal ? 1 : 0; + // return 1 if invalidation needed, 2 to request non-drawing functor callback, 0 otherwise + ALOGV("returnFlags are %d, shouldDraw %d", returnFlags, shouldDraw); + return returnFlags; } void updateRect(WebCore::IntRect& _viewRect) { viewRect = _viewRect; @@ -748,8 +747,8 @@ class GLDrawFunctor : Functor { } private: WebView* wvInstance; - bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, - WebCore::IntRect&, int, WebCore::IntRect&, float, int); + int (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, + WebCore::IntRect&, int, WebCore::IntRect&, float, int, bool); WebCore::IntRect viewRect; WebCore::IntRect webViewRect; jfloat scale; |