From d8be9016b7fda67a91b4ee17b3b2e7ba692ee553 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Thu, 23 Feb 2012 13:10:41 -0800 Subject: layer rendering cleanup/rewrite * added 'LayerGroup' class separate the painting/tiled features of a layer (eventually multiple layers) tiled drawing/preparing/counting details are abstracted out of LayerAndroid * added 'SurfaceCollection' class incorporates both the BaseLayerAndroid/LayerAndroid tree, as well as the vector of tiled LayerGroup * renamed 'TreeManager' to 'SurfaceManager' * Removes PaintedSurface was mostly a thin wrapper around DualTiledTexture * Combines TilePainter/SurfacePainter * Simplified ref counting Change-Id: I92c5c75f48d92e0e28812c56de00102399fc02ee --- Source/WebCore/Android.mk | 5 +- .../platform/graphics/android/BaseLayerAndroid.cpp | 103 +------ .../platform/graphics/android/BaseLayerAndroid.h | 19 +- .../WebCore/platform/graphics/android/BaseTile.cpp | 3 +- .../platform/graphics/android/BaseTileTexture.cpp | 4 +- .../platform/graphics/android/GLWebViewState.cpp | 51 ++-- .../platform/graphics/android/GLWebViewState.h | 8 +- .../platform/graphics/android/ImageTexture.cpp | 25 +- .../platform/graphics/android/ImageTexture.h | 7 +- Source/WebCore/platform/graphics/android/Layer.h | 21 -- .../platform/graphics/android/LayerAndroid.cpp | 221 +++++--------- .../platform/graphics/android/LayerAndroid.h | 24 +- .../platform/graphics/android/LayerGroup.cpp | 203 +++++++++++++ .../WebCore/platform/graphics/android/LayerGroup.h | 71 +++++ .../platform/graphics/android/MediaLayer.cpp | 5 +- .../WebCore/platform/graphics/android/MediaLayer.h | 2 +- .../graphics/android/PaintTileOperation.cpp | 15 +- .../platform/graphics/android/PaintTileOperation.h | 10 +- .../platform/graphics/android/PaintedSurface.cpp | 226 -------------- .../platform/graphics/android/PaintedSurface.h | 94 ------ .../graphics/android/SurfaceCollection.cpp | 254 ++++++++++++++++ .../platform/graphics/android/SurfaceCollection.h | 77 +++++ .../graphics/android/SurfaceCollectionManager.cpp | 287 +++++++++++++++++ .../graphics/android/SurfaceCollectionManager.h | 79 +++++ .../platform/graphics/android/TilePainter.h | 21 +- .../platform/graphics/android/TiledTexture.cpp | 178 +++++------ .../platform/graphics/android/TiledTexture.h | 57 ++-- .../platform/graphics/android/TilesManager.cpp | 64 +--- .../platform/graphics/android/TilesManager.h | 21 +- .../platform/graphics/android/TransferQueue.cpp | 3 +- .../platform/graphics/android/TreeManager.cpp | 338 --------------------- .../platform/graphics/android/TreeManager.h | 86 ------ .../graphics/android/VideoLayerAndroid.cpp | 5 +- .../platform/graphics/android/VideoLayerAndroid.h | 2 +- 34 files changed, 1287 insertions(+), 1302 deletions(-) create mode 100644 Source/WebCore/platform/graphics/android/LayerGroup.cpp create mode 100644 Source/WebCore/platform/graphics/android/LayerGroup.h delete mode 100644 Source/WebCore/platform/graphics/android/PaintedSurface.cpp delete mode 100644 Source/WebCore/platform/graphics/android/PaintedSurface.h create mode 100644 Source/WebCore/platform/graphics/android/SurfaceCollection.cpp create mode 100644 Source/WebCore/platform/graphics/android/SurfaceCollection.h create mode 100644 Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp create mode 100644 Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h delete mode 100644 Source/WebCore/platform/graphics/android/TreeManager.cpp delete mode 100644 Source/WebCore/platform/graphics/android/TreeManager.h (limited to 'Source/WebCore') diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index af56e7e..bae08c1 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -662,10 +662,10 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/InspectorCanvas.cpp \ platform/graphics/android/Layer.cpp \ platform/graphics/android/LayerAndroid.cpp \ + platform/graphics/android/LayerGroup.cpp \ platform/graphics/android/MediaLayer.cpp \ platform/graphics/android/MediaTexture.cpp \ platform/graphics/android/PaintTileOperation.cpp \ - platform/graphics/android/PaintedSurface.cpp \ platform/graphics/android/PathAndroid.cpp \ platform/graphics/android/PatternAndroid.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ @@ -681,7 +681,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/TiledPage.cpp \ platform/graphics/android/TiledTexture.cpp \ platform/graphics/android/TransferQueue.cpp \ - platform/graphics/android/TreeManager.cpp \ + platform/graphics/android/SurfaceCollection.cpp \ + platform/graphics/android/SurfaceCollectionManager.cpp \ platform/graphics/android/VerticalTextMap.cpp \ platform/graphics/android/VideoLayerAndroid.cpp \ platform/graphics/android/VideoLayerManager.cpp \ diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 524f986..fee94d3 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -29,6 +29,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "ClassTracker.h" #include "GLUtils.h" +#include "LayerGroup.h" #include "ShaderProgram.h" #include "SkCanvas.h" #include "TilesManager.h" @@ -112,7 +113,7 @@ bool BaseLayerAndroid::drawCanvas(SkCanvas* canvas) #if USE(ACCELERATED_COMPOSITING) -void BaseLayerAndroid::prefetchBasePicture(SkRect& viewport, float currentScale, +void BaseLayerAndroid::prefetchBasePicture(const SkRect& viewport, float currentScale, TiledPage* prefetchTiledPage, bool draw) { SkIRect bounds; @@ -167,20 +168,11 @@ bool BaseLayerAndroid::isReady() return false; } - LayerAndroid* compositedRoot = static_cast(getChild(0)); - if (compositedRoot) { - XLOG("base layer is ready, how about children?"); - return compositedRoot->isReady(); - } - return true; } void BaseLayerAndroid::swapTiles() { - if (countChildren()) - getChild(0)->swapTiles(); // TODO: move to parent impl - m_state->frontPage()->swapBuffersIfReady(m_state->preZoomBounds(), m_state->zoomManager()->currentScale()); @@ -188,37 +180,22 @@ void BaseLayerAndroid::swapTiles() m_state->zoomManager()->currentScale()); } -void BaseLayerAndroid::setIsDrawing(bool isDrawing) +void BaseLayerAndroid::setIsPainting() { - if (countChildren()) - getChild(0)->setIsDrawing(isDrawing); // TODO: move to parent impl -} - -void BaseLayerAndroid::setIsPainting(Layer* drawingTree) -{ - XLOG("BLA %p painting, dirty %d", this, isDirty()); - if (drawingTree) - drawingTree = drawingTree->getChild(0); - - if (countChildren()) - getChild(0)->setIsPainting(drawingTree); // TODO: move to parent impl - + XLOG("BLA %p setIsPainting, dirty %d", this, isDirty()); m_state->invalRegion(m_dirtyRegion); m_dirtyRegion.setEmpty(); } -void BaseLayerAndroid::mergeInvalsInto(Layer* replacementTree) +void BaseLayerAndroid::mergeInvalsInto(BaseLayerAndroid* replacementLayer) { - XLOG("merging invals (empty=%d) from BLA %p to %p", m_dirtyRegion.isEmpty(), this, replacementTree); - if (countChildren() && replacementTree->countChildren()) - getChild(0)->mergeInvalsInto(replacementTree->getChild(0)); - - replacementTree->markAsDirty(m_dirtyRegion); + replacementLayer->markAsDirty(m_dirtyRegion); } -bool BaseLayerAndroid::prepareBasePictureInGL(SkRect& viewport, float scale, - double currentTime) +void BaseLayerAndroid::prepareGL(const SkRect& viewport, float scale, double currentTime) { + XLOG("prepareGL BLA %p, m_state %p", this, m_state); + ZoomManager* zoomManager = m_state->zoomManager(); bool goingDown = m_state->goingDown(); @@ -279,10 +256,7 @@ bool BaseLayerAndroid::prepareBasePictureInGL(SkRect& viewport, float scale, m_state->swapPages(); } - bool needsRedraw = zooming; - - // if applied invals mark tiles dirty, need to redraw - needsRedraw |= tiledPage->updateTileDirtiness(preZoomBounds); + tiledPage->updateTileDirtiness(preZoomBounds); // paint what's needed unless we're zooming, since the new tiles won't // be relevant soon anyway @@ -290,8 +264,7 @@ bool BaseLayerAndroid::prepareBasePictureInGL(SkRect& viewport, float scale, tiledPage->prepare(goingDown, goingLeft, preZoomBounds, TiledPage::ExpandedBounds); - XLOG("scrollState %d, zooming %d, needsRedraw %d", - m_scrollState, zooming, needsRedraw); + XLOG("scrollState %d, zooming %d", m_scrollState, zooming); // prefetch in the nextTiledPage if unused by zooming (even if not scrolling // since we want the tiles to be ready before they're needed) @@ -305,8 +278,6 @@ bool BaseLayerAndroid::prepareBasePictureInGL(SkRect& viewport, float scale, } tiledPage->prepareForDrawGL(transparency, preZoomBounds); - - return needsRedraw; } void BaseLayerAndroid::drawBasePictureInGL() @@ -315,9 +286,7 @@ void BaseLayerAndroid::drawBasePictureInGL() m_state->frontPage()->drawGL(); } -#endif // USE(ACCELERATED_COMPOSITING) - -void BaseLayerAndroid::updateLayerPositions(SkRect& visibleRect) +void BaseLayerAndroid::updateLayerPositions(const SkRect& visibleRect) { LayerAndroid* compositedRoot = static_cast(getChild(0)); if (!compositedRoot) @@ -336,58 +305,16 @@ void BaseLayerAndroid::updateLayerPositions(SkRect& visibleRect) #endif } -bool BaseLayerAndroid::prepare(double currentTime, IntRect& viewRect, - SkRect& visibleRect, float scale) -{ - XLOG("preparing BLA %p", this); - - // base layer is simply drawn in prepare, since there is always a base layer it doesn't matter - bool needsRedraw = prepareBasePictureInGL(visibleRect, scale, currentTime); - - LayerAndroid* compositedRoot = static_cast(getChild(0)); - if (compositedRoot) { - updateLayerPositions(visibleRect); - - XLOG("preparing BLA %p, root %p", this, compositedRoot); - compositedRoot->prepare(); - } - - return needsRedraw; -} +#endif // USE(ACCELERATED_COMPOSITING) -bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, - float scale) +void BaseLayerAndroid::drawGL(float scale) { - XLOG("drawing BLA %p", this); + XLOG("drawGL BLA %p", this); // TODO: consider moving drawBackground outside of prepare (into tree manager) m_state->drawBackground(m_color); drawBasePictureInGL(); m_state->glExtras()->drawGL(0); - - bool needsRedraw = false; - -#if USE(ACCELERATED_COMPOSITING) - - LayerAndroid* compositedRoot = static_cast(getChild(0)); - if (compositedRoot) { - updateLayerPositions(visibleRect); - // For now, we render layers only if the rendering mode - // is kAllTextures or kClippedTextures - if (compositedRoot->drawGL()) { - if (TilesManager::instance()->layerTexturesRemain()) { - // only try redrawing for layers if layer textures remain, - // otherwise we'll repaint without getting anything done - needsRedraw = true; - } - } - } - -#endif // USE(ACCELERATED_COMPOSITING) -#ifdef DEBUG - ClassTracker::instance()->show(); -#endif - return needsRedraw; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h index c5ce52f..e7d0471 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -27,14 +27,13 @@ #define BaseLayerAndroid_h #include "Color.h" -#include "GLWebViewState.h" -#include "IntRect.h" #include "Layer.h" #include "PictureSet.h" -#include "SkPicture.h" namespace WebCore { +class TiledPage; + class BaseLayerAndroid : public Layer { public: @@ -59,23 +58,21 @@ public: // we are running in different threads. virtual bool drawCanvas(SkCanvas* canvas); - void updateLayerPositions(SkRect& visibleRect); - bool prepare(double currentTime, IntRect& viewRect, - SkRect& visibleRect, float scale); - bool drawGL(IntRect& viewRect, SkRect& visibleRect, float scale); + void updateLayerPositions(const SkRect& visibleRect); + void prepareGL(const SkRect& visibleRect, float scale, double currentTime); + void drawGL(float scale); // rendering asset management void swapTiles(); void setIsDrawing(bool isDrawing); - void setIsPainting(Layer* drawingTree); - void mergeInvalsInto(Layer* replacementTree); + void setIsPainting(); + void mergeInvalsInto(BaseLayerAndroid* replacementLayer); bool isReady(); private: #if USE(ACCELERATED_COMPOSITING) - void prefetchBasePicture(SkRect& viewport, float currentScale, + void prefetchBasePicture(const SkRect& viewport, float currentScale, TiledPage* prefetchTiledPage, bool draw); - bool prepareBasePictureInGL(SkRect& viewport, float scale, double currentTime); void drawBasePictureInGL(); android::Mutex m_drawLock; diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 42d02a5..0990d03 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -105,7 +105,8 @@ BaseTile::~BaseTile() void BaseTile::setContents(TilePainter* painter, int x, int y, float scale) { - if ((m_painter != painter) + // TODO: investigate whether below check/discard is necessary + if (!painter || (m_x != x) || (m_y != y) || (m_scale != scale)) { diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp index 04d0fc9..5e0668e 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp @@ -154,11 +154,13 @@ bool BaseTileTexture::readyFor(BaseTile* baseTile) return true; } + if (!info->m_painter || !baseTile->painter()) + return false; + if (info && (info->m_x == baseTile->x()) && (info->m_y == baseTile->y()) && (info->m_scale == baseTile->scale()) && - (info->m_painter == baseTile->painter()) && (info->m_inverted == TilesManager::instance()->invertedScreen())) return true; diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 86f33e0..93e5c78 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -37,7 +37,8 @@ #include "SkPath.h" #include "TilesManager.h" #include "TilesTracker.h" -#include "TreeManager.h" +#include "SurfaceCollection.h" +#include "SurfaceCollectionManager.h" #include #include @@ -74,7 +75,7 @@ #define FPS_INDICATOR_HEIGHT 10 #define MAX_FPS_VALUE 60 -#define TREE_SWAPPED_COUNTER_MODULE 10 +#define COLLECTION_SWAPPED_COUNTER_MODULE 10 namespace WebCore { @@ -94,7 +95,7 @@ GLWebViewState::GLWebViewState() , m_expandedTileBoundsY(0) , m_scale(1) , m_layersRenderingMode(kAllTextures) - , m_treeManager(this) + , m_surfaceCollectionManager(this) { m_viewport.setEmpty(); m_futureViewportTileBounds.setEmpty(); @@ -134,7 +135,7 @@ bool GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndica bool isPictureAfterFirstLayout) { if (!layer || isPictureAfterFirstLayout) { - // TODO: move this into TreeManager + // TODO: move this into SurfaceCollectionManager m_zoomManager.swapPages(); // reset zoom state m_tiledPageA->discardTextures(); m_tiledPageB->discardTextures(); @@ -144,7 +145,8 @@ bool GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndica XLOG("new base layer %p, with child %p", layer, layer->getChild(0)); layer->setState(this); } - bool queueFull = m_treeManager.updateWithTree(layer, isPictureAfterFirstLayout); + bool queueFull = m_surfaceCollectionManager.updateWithSurfaceCollection( + new SurfaceCollection(layer), isPictureAfterFirstLayout); m_glExtras.setDrawExtra(0); #ifdef MEASURES_PERF @@ -159,7 +161,7 @@ bool GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndica void GLWebViewState::scrollLayer(int layerId, int x, int y) { - m_treeManager.updateScrollableLayer(layerId, x, y); + m_surfaceCollectionManager.updateScrollableLayer(layerId, x, y); // TODO: only inval the area of the scrolled layer instead of // doing a fullInval() @@ -170,7 +172,7 @@ void GLWebViewState::scrollLayer(int layerId, int x, int y) void GLWebViewState::invalRegion(const SkRegion& region) { if (m_layersRenderingMode == kSingleSurfaceRendering) { - // TODO: do the union of both layers tree to compute + // TODO: do the union of both layer trees to compute //the minimum inval instead of doing a fullInval() fullInval(); return; @@ -204,7 +206,7 @@ void GLWebViewState::inval(const IntRect& rect) unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) { - m_treeManager.drawCanvas(canvas, m_layersRenderingMode == kSingleSurfaceRendering); + m_surfaceCollectionManager.drawCanvas(canvas, m_layersRenderingMode == kSingleSurfaceRendering); return m_currentPictureCounter; } @@ -236,11 +238,11 @@ void GLWebViewState::swapPages() int GLWebViewState::baseContentWidth() { - return m_treeManager.baseContentWidth(); + return m_surfaceCollectionManager.baseContentWidth(); } int GLWebViewState::baseContentHeight() { - return m_treeManager.baseContentHeight(); + return m_surfaceCollectionManager.baseContentHeight(); } void GLWebViewState::setViewport(const SkRect& viewport, float scale) @@ -469,7 +471,7 @@ void GLWebViewState::fullInval() bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, IntRect& webViewRect, int titleBarHeight, IntRect& clip, float scale, - bool* treesSwappedPtr, bool* newTreeHasAnimPtr) + bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr) { TilesManager* tilesManager = TilesManager::instance(); m_scale = scale; @@ -498,9 +500,6 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, resetLayersDirtyArea(); - // when adding or removing layers, use the the paintingBaseLayer's tree so - // that content that moves to the base layer from a layer is synchronized - if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) XLOGC("WARNING, scale seems corrupted before update: %e", scale); @@ -528,10 +527,10 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, TexturesResult nbTexturesNeeded; bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering; m_glExtras.setViewport(viewport); - ret |= m_treeManager.drawGL(currentTime, rect, viewport, - scale, fastSwap, - treesSwappedPtr, newTreeHasAnimPtr, - &nbTexturesNeeded); + ret |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport, + scale, fastSwap, + collectionsSwappedPtr, newCollectionHasAnimPtr, + &nbTexturesNeeded); if (!ret) resetFrameworkInval(); @@ -577,7 +576,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, invalRect->setHeight(inval.height()); XLOG("invalRect(%d, %d, %d, %d)", inval.x(), - inval.y(), inval.width(), inval.height()); + inval.y(), inval.width(), inval.height()); if (!invalRect->intersects(rect)) { // invalidate is occurring offscreen, do full inval to guarantee redraw @@ -595,7 +594,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, resetFrameworkInval(); } - showFrameInfo(rect, *treesSwappedPtr); + showFrameInfo(rect, *collectionsSwappedPtr); #ifdef DEBUG tilesManager->getTilesTracker()->showTrackTextures(); @@ -604,7 +603,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, return ret; } -void GLWebViewState::showFrameInfo(const IntRect& rect, bool treesSwapped) +void GLWebViewState::showFrameInfo(const IntRect& rect, bool collectionsSwapped) { bool showVisualIndicator = TilesManager::instance()->getShowVisualIndicator(); @@ -635,18 +634,18 @@ void GLWebViewState::showFrameInfo(const IntRect& rect, bool treesSwapped) frameInfoRect.setWidth(frameInfoRect.width() * ratio); clearRectWithColor(frameInfoRect, 1, 0, 0, 1); - // Draw the tree swap counter as a circling progress bar. - // This will basically show how fast we are updating the tree. + // Draw the collection swap counter as a circling progress bar. + // This will basically show how fast we are updating the collection. static int swappedCounter = 0; - if (treesSwapped) - swappedCounter = (swappedCounter + 1) % TREE_SWAPPED_COUNTER_MODULE; + if (collectionsSwapped) + swappedCounter = (swappedCounter + 1) % COLLECTION_SWAPPED_COUNTER_MODULE; frameInfoRect = rect; frameInfoRect.setHeight(FPS_INDICATOR_HEIGHT); frameInfoRect.move(0, FPS_INDICATOR_HEIGHT); clearRectWithColor(frameInfoRect, 1, 1, 1, 1); - ratio = (swappedCounter + 1.0) / TREE_SWAPPED_COUNTER_MODULE; + ratio = (swappedCounter + 1.0) / COLLECTION_SWAPPED_COUNTER_MODULE; frameInfoRect.setWidth(frameInfoRect.width() * ratio); clearRectWithColor(frameInfoRect, 0, 1, 0, 1); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 334cd8e..da579da 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -36,7 +36,7 @@ #include "SkRect.h" #include "SkRegion.h" #include "TiledPage.h" -#include "TreeManager.h" +#include "SurfaceCollectionManager.h" #include "ZoomManager.h" #include @@ -210,7 +210,7 @@ public: bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, IntRect& webViewRect, int titleBarHeight, IntRect& clip, float scale, - bool* treesSwappedPtr, bool* newTreeHasAnimPtr); + bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr); #ifdef MEASURES_PERF void dumpMeasures(); @@ -252,7 +252,7 @@ private: double setupDrawing(const IntRect& viewRect, const SkRect& visibleRect, const IntRect& webViewRect, int titleBarHeight, const IntRect& screenClip, float scale); - void showFrameInfo(const IntRect& rect, bool treesSwapped); + void showFrameInfo(const IntRect& rect, bool collectionsSwapped); void clearRectWithColor(const IntRect& rect, float r, float g, float b, float a); double m_prevDrawTime; @@ -291,7 +291,7 @@ private: float m_scale; LayersRenderingMode m_layersRenderingMode; - TreeManager m_treeManager; + SurfaceCollectionManager m_surfaceCollectionManager; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp index 0ca8ee7..c2b70b2 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp +++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp @@ -188,18 +188,18 @@ bool ImageTexture::prepareGL(GLWebViewState* state) return false; if (!m_texture && m_picture) { - m_texture = new TiledTexture(this); + m_texture = new TiledTexture(); SkRegion region; region.setRect(0, 0, m_image->width(), m_image->height()); - m_texture->update(region, m_picture); + m_texture->markAsDirty(region); } if (!m_texture) return false; IntRect visibleArea(0, 0, m_image->width(), m_image->height()); - m_texture->prepare(state, 1.0, true, true, visibleArea); - if (m_texture->ready()) { + m_texture->prepareGL(state, 1.0, visibleArea, this); + if (m_texture->isReady()) { m_texture->swapTiles(); return false; } @@ -230,7 +230,20 @@ float ImageTexture::opacity() return m_layer->drawOpacity(); } -void ImageTexture::drawGL(LayerAndroid* layer) +bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) +{ + if (!m_picture) { + XLOG("IT %p COULDNT PAINT, NO PICTURE", this); + return false; + } + + XLOG("IT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), m_picture); + canvas->drawPicture(*m_picture); + + return true; +} + +void ImageTexture::drawGL(LayerAndroid* layer, float opacity) { if (!layer) return; @@ -242,7 +255,7 @@ void ImageTexture::drawGL(LayerAndroid* layer) m_layer = layer; if (m_texture) { IntRect visibleArea = m_layer->visibleArea(); - m_texture->draw(visibleArea); + m_texture->drawGL(visibleArea, opacity); } m_layer = 0; } diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h index 6c6a075..9c2c79c 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.h +++ b/Source/WebCore/platform/graphics/android/ImageTexture.h @@ -67,13 +67,13 @@ class TiledTexture; // so that we can share the same textures and limits as the rest of the layers. // ///////////////////////////////////////////////////////////////////////////////// -class ImageTexture : public SurfacePainter { +class ImageTexture : public TilePainter { public: ImageTexture(SkBitmap* bmp, unsigned crc); virtual ~ImageTexture(); bool prepareGL(GLWebViewState*); - void drawGL(LayerAndroid* painter); + void drawGL(LayerAndroid* layer, float opacity); void drawCanvas(SkCanvas*, SkRect&); bool hasContentToShow(); SkBitmap* bitmap() { return m_image; } @@ -85,12 +85,13 @@ public: bool equalsCRC(unsigned crc); // methods used by TiledTexture + virtual bool paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed); virtual const TransformationMatrix* transform(); virtual float opacity(); int nbTextures(); - virtual SurfaceType type() { return SurfacePainter::ImageSurface; } + virtual SurfaceType type() { return TilePainter::Image; } private: diff --git a/Source/WebCore/platform/graphics/android/Layer.h b/Source/WebCore/platform/graphics/android/Layer.h index 876ca24..9165307 100644 --- a/Source/WebCore/platform/graphics/android/Layer.h +++ b/Source/WebCore/platform/graphics/android/Layer.h @@ -65,19 +65,6 @@ public: void setChildrenMatrix(const SkMatrix& matrix) { m_childrenMatrix = matrix; } // rendering asset management - - // tell rendering assets to update their tile content with most recent painted data - virtual void swapTiles() {} - - // tell rendering assets to use this layer tree for drawing - virtual void setIsDrawing(bool isDrawing) {} - - // take rendering assets from drawing tree, or create if they don't exist - virtual void setIsPainting(Layer* drawingTree) {} - - // if a similar layer exists in the replacement tree, add invals to it - virtual void mergeInvalsInto(Layer* replacementTree) {} - void markAsDirty(const SkRegion& invalRegion) { m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); } @@ -88,14 +75,6 @@ public: // drawing - virtual bool isReady() { return false; } - - // TODO: clean out several of these, leave them in GLWebViewState - - virtual bool prepare(double currentTime, WebCore::IntRect& viewRect, - SkRect& visibleRect, float scale) { return 0; } - virtual bool drawGL(WebCore::IntRect& viewRect, - SkRect& visibleRect, float scale) { return 0; } WebCore::GLWebViewState* state() { return m_state; } void setState(WebCore::GLWebViewState* state); diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index b4e20e8..4e45846 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -9,8 +9,8 @@ #include "GLUtils.h" #include "ImagesManager.h" #include "InspectorCanvas.h" +#include "LayerGroup.h" #include "MediaLayer.h" -#include "PaintedSurface.h" #include "ParseCanvas.h" #include "SkBitmapRef.h" #include "SkDrawFilter.h" @@ -66,15 +66,16 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_preserves3D(false), m_anchorPointZ(0), m_recordingPicture(0), + m_zValue(0), m_uniqueId(++gUniqueId), - m_texture(0), m_imageCRC(0), m_pictureUsed(0), m_scale(1), m_lastComputeTextureSize(0), m_owningLayer(owner), m_type(LayerAndroid::WebCoreLayer), - m_hasText(true) + m_hasText(true), + m_layerGroup(0) { m_backgroundColor = 0; @@ -90,11 +91,12 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_haveClip(layer.m_haveClip), m_isIframe(layer.m_isIframe), + m_zValue(layer.m_zValue), m_uniqueId(layer.m_uniqueId), - m_texture(0), m_owningLayer(layer.m_owningLayer), m_type(LayerAndroid::UILayer), - m_hasText(true) + m_hasText(true), + m_layerGroup(0) { m_isFixed = layer.m_isFixed; m_imageCRC = layer.m_imageCRC; @@ -174,14 +176,15 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_isFixed(false), m_isIframe(false), m_recordingPicture(picture), + m_zValue(0), m_uniqueId(++gUniqueId), - m_texture(0), m_imageCRC(0), m_scale(1), m_lastComputeTextureSize(0), m_owningLayer(0), m_type(LayerAndroid::NavCacheLayer), - m_hasText(true) + m_hasText(true), + m_layerGroup(0) { m_backgroundColor = 0; SkSafeRef(m_recordingPicture); @@ -199,6 +202,7 @@ LayerAndroid::~LayerAndroid() ImagesManager::instance()->releaseImage(m_imageCRC); SkSafeUnref(m_recordingPicture); + // Don't unref m_layerGroup, owned by BaseLayerAndroid m_animations.clear(); #ifdef DEBUG_COUNT ClassTracker::instance()->remove(this); @@ -693,6 +697,17 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM this->getChild(i)->updateGLPositionsAndScale(childMatrix, drawClip(), opacity, scale); } +bool LayerAndroid::visible() { + // TODO: avoid climbing tree each access + LayerAndroid* current = this; + while (current->getParent()) { + if (!current->m_visible) + return false; + current = static_cast(current->getParent()); + } + return true; +} + void LayerAndroid::setContentsImage(SkBitmapRef* img) { ImageTexture* image = ImagesManager::instance()->setImage(img); @@ -702,16 +717,10 @@ void LayerAndroid::setContentsImage(SkBitmapRef* img) bool LayerAndroid::needsTexture() { - return m_imageCRC || (m_recordingPicture + return (m_recordingPicture && m_recordingPicture->width() && m_recordingPicture->height()); } -void LayerAndroid::removeTexture(PaintedSurface* texture) -{ - if (texture == m_texture) - m_texture = 0; -} - IntRect LayerAndroid::clippedRect() const { IntRect r(0, 0, getWidth(), getHeight()); @@ -741,18 +750,6 @@ int LayerAndroid::nbTexturedLayers() return nb; } -void LayerAndroid::computeTexturesAmount(TexturesResult* result) -{ - if (!result) - return; - - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->computeTexturesAmount(result); - if (m_texture && m_visible) - m_texture->computeTexturesAmount(result); -} - void LayerAndroid::showLayer(int indent) { char spaces[256]; @@ -792,28 +789,6 @@ void LayerAndroid::showLayer(int indent) this->getChild(i)->showLayer(indent + 1); } -void LayerAndroid::swapTiles() -{ - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->swapTiles(); - - if (m_texture) - m_texture->swapTiles(); -} - -void LayerAndroid::setIsDrawing(bool isDrawing) -{ - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->setIsDrawing(isDrawing); - - if (m_texture) { - m_texture->setDrawingLayer(isDrawing ? this : 0); - m_texture->clearPaintingLayer(); - } -} - void LayerAndroid::setIsPainting(Layer* drawingTree) { XLOG("setting layer %p as painting, needs texture %d, drawing tree %p", @@ -830,30 +805,17 @@ void LayerAndroid::setIsPainting(Layer* drawingTree) obtainTextureForPainting(drawingLayer); } -void LayerAndroid::mergeInvalsInto(Layer* replacementTree) +void LayerAndroid::mergeInvalsInto(LayerAndroid* replacementTree) { int count = this->countChildren(); for (int i = 0; i < count; i++) this->getChild(i)->mergeInvalsInto(replacementTree); - LayerAndroid* replacementLayer = static_cast(replacementTree)->findById(uniqueId()); + LayerAndroid* replacementLayer = replacementTree->findById(uniqueId()); if (replacementLayer) replacementLayer->markAsDirty(m_dirtyRegion); } -bool LayerAndroid::isReady() -{ - int count = countChildren(); - for (int i = 0; i < count; i++) - if (!getChild(i)->isReady()) - return false; - - if (m_texture) - return m_texture->isReady(); - // TODO: image, check if uploaded? - return true; -} - bool LayerAndroid::updateWithTree(LayerAndroid* newTree) { // Disable fast update for now @@ -903,24 +865,8 @@ void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingLayer) if (!needsTexture()) return; - if (m_imageCRC) { - if (m_texture) { - m_texture->setDrawingLayer(0); - m_texture->clearPaintingLayer(); - m_texture = 0; - } - } else { - if (drawingLayer) { - // if a previous tree had the same layer, paint with that painted surface - m_texture = drawingLayer->m_texture; - } - - if (!m_texture) - m_texture = new PaintedSurface(); - - // pass the invalidated regions to the PaintedSurface - m_texture->setPaintingLayer(this, m_dirtyRegion); - } + // layer group init'd with previous drawing layer + m_layerGroup->initializeGroup(this, m_dirtyRegion, drawingLayer); m_dirtyRegion.setEmpty(); } @@ -930,39 +876,55 @@ static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b) return a->zValue() > b->zValue(); } -// We call this in WebViewCore, when copying the tree of layers. -// As we construct a new tree that will be passed on the UI, -// we mark the webkit-side tree as having no more dirty region -// (otherwise we would continuously have those dirty region UI-side) -void LayerAndroid::clearDirtyRegion() +void LayerAndroid::assignGroups(Vector* allGroups) { - int count = this->countChildren(); - for (int i = 0; i < count; i++) - this->getChild(i)->clearDirtyRegion(); + // recurse through layers in draw order + // if a layer needs isolation (e.g. has animation, is fixed, overflow:scroll) + // create new layer group on the stack - m_dirtyRegion.setEmpty(); -} + bool needsIsolation = false; + LayerGroup* currentLayerGroup = 0; + if (!allGroups->isEmpty()) + currentLayerGroup = allGroups->at(0); -void LayerAndroid::prepare() -{ - XLOG("LA %p preparing, m_texture %p", this, m_texture); + // TODO: compare layer with group on top of stack - fixed? overscroll? transformed? + needsIsolation = m_isFixed || (m_animations.size() != 0); + + if (!currentLayerGroup || needsIsolation || true) { + currentLayerGroup = new LayerGroup(); + allGroups->append(currentLayerGroup); + } + + currentLayerGroup->addLayer(this); + m_layerGroup = currentLayerGroup; + // pass the layergroup through children in drawing order, so that they may + // attach themselves (and paint on it) if possible, or ignore it and create + // a new one if not int count = this->countChildren(); if (count > 0) { Vector sublayers; for (int i = 0; i < count; i++) - sublayers.append(this->getChild(i)); + sublayers.append(getChild(i)); - // now we sort for the transparency + // sort for the transparency std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ); - - // iterate in reverse so top layers get textures first - for (int i = count-1; i >= 0; i--) - sublayers[i]->prepare(); + for (int i = 0; i < count; i++) + sublayers[i]->assignGroups(allGroups); } +} + +// We call this in WebViewCore, when copying the tree of layers. +// As we construct a new tree that will be passed on the UI, +// we mark the webkit-side tree as having no more dirty region +// (otherwise we would continuously have those dirty region UI-side) +void LayerAndroid::clearDirtyRegion() +{ + int count = this->countChildren(); + for (int i = 0; i < count; i++) + this->getChild(i)->clearDirtyRegion(); - if (m_texture) - m_texture->prepare(m_state); + m_dirtyRegion.setEmpty(); } IntRect LayerAndroid::unclippedArea() @@ -1016,11 +978,6 @@ bool LayerAndroid::drawCanvas(SkCanvas* canvas) SkMatrix canvasMatrix = canvas->getTotalMatrix(); matrix.postConcat(canvasMatrix); canvas->setMatrix(matrix); - SkRect layerRect; - layerRect.fLeft = 0; - layerRect.fTop = 0; - layerRect.fRight = getWidth(); - layerRect.fBottom = getHeight(); onDraw(canvas, m_drawOpacity, 0); } @@ -1034,33 +991,23 @@ bool LayerAndroid::drawCanvas(SkCanvas* canvas) return askScreenUpdate; } -bool LayerAndroid::drawGL() +bool LayerAndroid::drawGL(bool layerTilesDisabled) { - FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(m_clippingRect); - TilesManager::instance()->shader()->clip(clippingRect); - if (!m_visible) - return false; - - bool askScreenUpdate = false; - - if (m_state->layersRenderingMode() < GLWebViewState::kScrollableAndFixedLayers) { - if (m_texture) - askScreenUpdate |= m_texture->draw(); - if (m_imageCRC) { - ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC); - if (imageTexture) - imageTexture->drawGL(this); - ImagesManager::instance()->releaseImage(m_imageCRC); - } + if (!layerTilesDisabled && m_imageCRC) { + ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC); + if (imageTexture) + imageTexture->drawGL(this, getOpacity()); + ImagesManager::instance()->releaseImage(m_imageCRC); } m_state->glExtras()->drawGL(this); + bool askScreenUpdate = false; - // When the layer is dirty, the UI thread should be notified to redraw. - askScreenUpdate |= drawChildrenGL(); m_atomicSync.lock(); - if (askScreenUpdate || m_hasRunningAnimations || m_drawTransform.hasPerspective()) + if (m_hasRunningAnimations || m_drawTransform.hasPerspective()) { + askScreenUpdate = true; addDirtyArea(); + } m_atomicSync.unlock(); return askScreenUpdate; @@ -1086,26 +1033,6 @@ bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas) return askScreenUpdate; } -bool LayerAndroid::drawChildrenGL() -{ - bool askScreenUpdate = false; - int count = this->countChildren(); - if (count > 0) { - Vector sublayers; - for (int i = 0; i < count; i++) - sublayers.append(this->getChild(i)); - - // now we sort for the transparency - std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ); - for (int i = 0; i < count; i++) { - LayerAndroid* layer = sublayers[i]; - askScreenUpdate |= layer->drawGL(); - } - } - - return askScreenUpdate; -} - void LayerAndroid::contentDraw(SkCanvas* canvas) { if (m_recordingPicture) diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index d33eea1..2361e62 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -48,6 +48,7 @@ class SkPicture; namespace WebCore { class LayerAndroid; +class LayerGroup; class ImageTexture; } @@ -139,30 +140,23 @@ public: IntRect visibleArea(); virtual bool needsTexture(); - void removeTexture(PaintedSurface*); // Debug helper methods int nbLayers(); int nbTexturedLayers(); void showLayer(int indent = 0); - void computeTexturesAmount(TexturesResult*); - float getScale() { return m_scale; } - // draw layer and its children via Z, pre-order traversal - virtual bool drawGL(); - bool drawChildrenGL(); + virtual bool drawGL(bool layerTilesDisabled); virtual bool drawCanvas(SkCanvas*); bool drawChildrenCanvas(SkCanvas*); - // prepare layer and its children via reverse-Z, post-order traversal - void prepare(); - void updateGLPositionsAndScale(const TransformationMatrix& parentMatrix, const FloatRect& clip, float opacity, float scale); void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } float drawOpacity() { return m_drawOpacity; } + bool visible(); void setVisible(bool value) { m_visible = value; } bool preserves3D() { return m_preserves3D; } @@ -292,7 +286,6 @@ public: friend LayerAndroid* android::deserializeLayer(SkStream* stream); friend void android::cleanupImageRefs(LayerAndroid* layer); - PaintedSurface* texture() { return m_texture; } void obtainTextureForPainting(LayerAndroid* drawingLayer); // Update layers using another tree. Only works for basic properties @@ -309,11 +302,11 @@ public: void copyAnimationStartTimesRecursive(LayerAndroid* oldTree); // rendering asset management - void swapTiles(); - void setIsDrawing(bool isDrawing); void setIsPainting(Layer* drawingTree); - void mergeInvalsInto(Layer* replacementTree); - bool isReady(); + void mergeInvalsInto(LayerAndroid* replacementTree); + + void assignGroups(Vector* allGroups); + LayerGroup* group() { return m_layerGroup; } protected: virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra); @@ -389,7 +382,6 @@ private: int m_uniqueId; - PaintedSurface* m_texture; unsigned m_imageCRC; unsigned int m_pictureUsed; @@ -414,6 +406,8 @@ private: bool m_hasText; + LayerGroup* m_layerGroup; + typedef Layer INHERITED; }; diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/LayerGroup.cpp new file mode 100644 index 0000000..e9f8967 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/LayerGroup.cpp @@ -0,0 +1,203 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "LayerGroup.h" + +#include "ClassTracker.h" +#include "LayerAndroid.h" +#include "TiledTexture.h" +#include "TilesManager.h" + +#include +#include +#include + +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "LayerGroup", __VA_ARGS__) + +#ifdef DEBUG + +#undef XLOG +#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "LayerGroup", __VA_ARGS__) + +#else + +#undef XLOG +#define XLOG(...) + +#endif // DEBUG + +// LayerGroups with an area larger than 2048*2048 should never be unclipped +#define MAX_UNCLIPPED_AREA 4194304 + +#define TEMP_LAYER m_layers[0] + +namespace WebCore { + +LayerGroup::LayerGroup() + : m_hasText(false) + , m_dualTiledTexture(0) +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("LayerGroup"); +#endif +} + +LayerGroup::~LayerGroup() +{ + for (unsigned int i = 0; i < m_layers.size(); i++) + SkSafeUnref(m_layers[i]); + if (m_dualTiledTexture) + SkSafeUnref(m_dualTiledTexture); +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("LayerGroup"); +#endif +} + +void LayerGroup::initializeGroup(LayerAndroid* newLayer, const SkRegion& newLayerInval, + LayerAndroid* oldLayer) +{ + if (!newLayer->needsTexture()) + return; + + XLOG("init on LG %p, layer %p, oldlayer %p", this, newLayer, oldLayer); + if (oldLayer && oldLayer->group() && oldLayer->group()->m_dualTiledTexture) { + // steal DTT from old group, and apply new inval + m_dualTiledTexture = oldLayer->group()->m_dualTiledTexture; + SkSafeRef(m_dualTiledTexture); + m_dualTiledTexture->markAsDirty(newLayerInval); + } else + m_dualTiledTexture = new DualTiledTexture(); + } + +void LayerGroup::addLayer(LayerAndroid* layer) +{ + m_layers.append(layer); + SkSafeRef(layer); +} + +void LayerGroup::prepareGL(bool layerTilesDisabled) +{ + if (!m_dualTiledTexture) + return; + + if (layerTilesDisabled) { + m_dualTiledTexture->discardTextures(); + } else { + XLOG("prepareGL on LG %p with DTT %p", this, m_dualTiledTexture); + bool allowZoom = m_hasText; // only allow for scale > 1 if painting vectors + IntRect prepareArea = computePrepareArea(); + m_dualTiledTexture->prepareGL(TEMP_LAYER->state(), TEMP_LAYER->hasText(), + prepareArea, this); + } +} + +bool LayerGroup::drawGL(bool layerTilesDisabled) +{ + if (!TEMP_LAYER->visible()) + return false; + + FloatRect drawClip = TEMP_LAYER->drawClip(); + FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip); + TilesManager::instance()->shader()->clip(clippingRect); + + bool askRedraw = false; + if (m_dualTiledTexture && !layerTilesDisabled) { + XLOG("drawGL on LG %p with DTT %p", this, m_dualTiledTexture); + IntRect visibleArea = TEMP_LAYER->visibleArea(); + askRedraw |= m_dualTiledTexture->drawGL(visibleArea, opacity()); + } + askRedraw |= TEMP_LAYER->drawGL(layerTilesDisabled); + + return askRedraw; +} + +void LayerGroup::swapTiles() +{ + if (!m_dualTiledTexture) + return; + + m_dualTiledTexture->swapTiles(); +} + +bool LayerGroup::isReady() +{ + if (!m_dualTiledTexture) + return true; + + return m_dualTiledTexture->isReady(); +} + +IntRect LayerGroup::computePrepareArea() { + IntRect area; + + if (!TEMP_LAYER->contentIsScrollable() + && TEMP_LAYER->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { + area = TEMP_LAYER->unclippedArea(); + + double total = ((double) area.width()) * ((double) area.height()); + if (total > MAX_UNCLIPPED_AREA) + area = TEMP_LAYER->visibleArea(); + } else { + area = TEMP_LAYER->visibleArea(); + } + + return area; +} + +void LayerGroup::computeTexturesAmount(TexturesResult* result) +{ + if (!m_dualTiledTexture) + return; + + // TODO: don't calculate through layer recursion, use the group list + m_dualTiledTexture->computeTexturesAmount(result, TEMP_LAYER); +} + +bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) +{ + SkPicture *picture = TEMP_LAYER->picture(); + if (!picture) { + XLOGC("LG %p couldn't paint, no picture in layer %p", this, TEMP_LAYER); + return false; + } + + canvas->drawPicture(*picture); + + return true; +} + +const TransformationMatrix* LayerGroup::transform() +{ + return TEMP_LAYER->drawTransform(); +} + +float LayerGroup::opacity() +{ + return TEMP_LAYER->getOpacity(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.h b/Source/WebCore/platform/graphics/android/LayerGroup.h new file mode 100644 index 0000000..1b90f4b --- /dev/null +++ b/Source/WebCore/platform/graphics/android/LayerGroup.h @@ -0,0 +1,71 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LayerGroup_h +#define LayerGroup_h + +#include "TilePainter.h" +#include "Vector.h" + +class SkCanvas; +class SkRegion; + +namespace WebCore { + +class BaseTile; +class DualTiledTexture; +class TexturesResult; +class LayerAndroid; + +class LayerGroup : public TilePainter { +public: + LayerGroup(); + virtual ~LayerGroup(); + + void initializeGroup(LayerAndroid* newLayer, const SkRegion& newLayerInval, + LayerAndroid* oldLayer); + + void addLayer(LayerAndroid* layer); + void prepareGL(bool layerTilesDisabled); + bool drawGL(bool layerTilesDisabled); + void swapTiles(); + bool isReady(); + + IntRect computePrepareArea(); + void computeTexturesAmount(TexturesResult* result); + + // TilePainter methods + virtual bool paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed); + virtual const TransformationMatrix* transform(); + virtual float opacity(); +private: + bool m_hasText; + DualTiledTexture* m_dualTiledTexture; + Vector m_layers; +}; + +} // namespace WebCore + +#endif //#define LayerGroup_h diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/MediaLayer.cpp index 12cfe38..c2f3630 100644 --- a/Source/WebCore/platform/graphics/android/MediaLayer.cpp +++ b/Source/WebCore/platform/graphics/android/MediaLayer.cpp @@ -66,7 +66,7 @@ MediaLayer::~MediaLayer() m_mediaTexture->decStrong(this); } -bool MediaLayer::drawGL() +bool MediaLayer::drawGL(bool layerTilesDisabled) { FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip()); TilesManager::instance()->shader()->clip(clippingRect); @@ -92,8 +92,7 @@ bool MediaLayer::drawGL() // draw any content or video if present m_mediaTexture->draw(m, m_drawTransform, mediaBounds); - - return drawChildrenGL(); + return false; } ANativeWindow* MediaLayer::acquireNativeWindowForContent() diff --git a/Source/WebCore/platform/graphics/android/MediaLayer.h b/Source/WebCore/platform/graphics/android/MediaLayer.h index b94ec53..907c53c 100644 --- a/Source/WebCore/platform/graphics/android/MediaLayer.h +++ b/Source/WebCore/platform/graphics/android/MediaLayer.h @@ -36,7 +36,7 @@ public: MediaLayer(const MediaLayer& layer); virtual ~MediaLayer(); - virtual bool drawGL(); + virtual bool drawGL(bool layerTilesDisabled); virtual void paintBitmapGL() const { }; virtual bool needsTexture() { return false; } diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp index 2d69706..9fb06b3 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp @@ -28,18 +28,19 @@ #include "ImageTexture.h" #include "ImagesManager.h" #include "LayerAndroid.h" -#include "PaintedSurface.h" +#include "TiledPage.h" +#include "TilesManager.h" namespace WebCore { -PaintTileOperation::PaintTileOperation(BaseTile* tile, SurfacePainter* surface) +PaintTileOperation::PaintTileOperation(BaseTile* tile, TilePainter* painter) : QueuedOperation(QueuedOperation::PaintTile, tile->page()) , m_tile(tile) - , m_surface(surface) + , m_painter(painter) { if (m_tile) m_tile->setRepaintPending(true); - SkSafeRef(m_surface); + SkSafeRef(m_painter); } PaintTileOperation::~PaintTileOperation() @@ -49,11 +50,11 @@ PaintTileOperation::~PaintTileOperation() m_tile = 0; } - if (m_surface && m_surface->type() == SurfacePainter::ImageSurface) { - ImageTexture* image = static_cast(m_surface); + if (m_painter && m_painter->type() == TilePainter::Image) { + ImageTexture* image = static_cast(m_painter); ImagesManager::instance()->releaseImage(image->imageCRC()); } else { - SkSafeUnref(m_surface); + SkSafeUnref(m_painter); } } diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/PaintTileOperation.h index bc74d03..3ade065 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h @@ -33,12 +33,12 @@ namespace WebCore { class LayerAndroid; -class SurfacePainter; +class TilePainter; class ImageTexture; class PaintTileOperation : public QueuedOperation { public: - PaintTileOperation(BaseTile* tile, SurfacePainter* surface = 0); + PaintTileOperation(BaseTile* tile, TilePainter* painter = 0); virtual ~PaintTileOperation(); virtual bool operator==(const QueuedOperation* operation); virtual void run(); @@ -49,12 +49,12 @@ public: private: BaseTile* m_tile; - SurfacePainter* m_surface; + TilePainter* m_painter; }; class ScaleFilter : public OperationFilter { public: - ScaleFilter(TilePainter* painter, float scale) + ScaleFilter(const TilePainter* painter, float scale) : m_painter(painter) , m_scale(scale) {} virtual bool check(QueuedOperation* operation) @@ -67,7 +67,7 @@ public: return false; } private: - TilePainter* m_painter; + const TilePainter* m_painter; float m_scale; }; diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp deleted file mode 100644 index b65c64a..0000000 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PaintedSurface.h" - - -#include "LayerAndroid.h" -#include "TiledTexture.h" -#include "TilesManager.h" -#include "SkCanvas.h" -#include "SkPicture.h" - -#include -#include -#include - -#undef XLOGC -#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__) - -#ifdef DEBUG - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -// Layers with an area larger than 2048*2048 should never be unclipped -#define MAX_UNCLIPPED_AREA 4194304 - -namespace WebCore { - -PaintedSurface::PaintedSurface() - : m_drawingLayer(0) - , m_paintingLayer(0) - , m_tiledTexture(0) - , m_scale(0) - , m_pictureUsed(0) -{ - TilesManager::instance()->addPaintedSurface(this); -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("PaintedSurface"); -#endif - m_tiledTexture = new DualTiledTexture(this); -} - -PaintedSurface::~PaintedSurface() -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("PaintedSurface"); -#endif - delete m_tiledTexture; -} - -void PaintedSurface::prepare(GLWebViewState* state) -{ - XLOG("PS %p has PL %p, DL %p", this, m_paintingLayer, m_drawingLayer); - LayerAndroid* paintingLayer = m_paintingLayer; - if (!paintingLayer) - paintingLayer = m_drawingLayer; - - if (!paintingLayer) - return; - - bool startFastSwap = false; - if (state->isScrolling()) { - // when scrolling, block updates and swap tiles as soon as they're ready - startFastSwap = true; - } - - XLOG("prepare layer %d %x at scale %.2f", - paintingLayer->uniqueId(), paintingLayer, - paintingLayer->getScale()); - - IntRect prepareArea = computePrepareArea(paintingLayer); - - m_scale = state->scale(); - - // If we do not have text, we may as well limit ourselves to - // a scale factor of one... this saves up textures. - if (m_scale > 1 && !paintingLayer->hasText()) - m_scale = 1; - - m_tiledTexture->prepare(state, m_scale, m_pictureUsed != paintingLayer->pictureUsed(), - startFastSwap, prepareArea); -} - -bool PaintedSurface::draw() -{ - if (!m_drawingLayer || !m_drawingLayer->needsTexture()) - return false; - - bool askRedraw = false; - if (m_tiledTexture) { - IntRect visibleArea = m_drawingLayer->visibleArea(); - askRedraw = m_tiledTexture->draw(visibleArea); - } - - return askRedraw; -} - -void PaintedSurface::setPaintingLayer(LayerAndroid* layer, const SkRegion& dirtyArea) -{ - m_paintingLayer = layer; - if (m_tiledTexture) - m_tiledTexture->update(dirtyArea, layer->picture()); -} - -bool PaintedSurface::isReady() -{ - if (m_tiledTexture) - return m_tiledTexture->isReady(); - return false; -} - -void PaintedSurface::swapTiles() -{ - if (m_tiledTexture) - m_tiledTexture->swapTiles(); -} - -float PaintedSurface::opacity() { - if (m_drawingLayer) - return m_drawingLayer->drawOpacity(); - return 1.0; -} - -const TransformationMatrix* PaintedSurface::transform() { - // used exclusively for drawing, so only use m_drawingLayer - if (!m_drawingLayer) - return 0; - - return m_drawingLayer->drawTransform(); -} - -void PaintedSurface::computeTexturesAmount(TexturesResult* result) -{ - if (!m_tiledTexture) - return; - - // for now, always done on drawinglayer - LayerAndroid* layer = m_drawingLayer; - - if (!layer) - return; - - IntRect unclippedArea = layer->unclippedArea(); - IntRect clippedVisibleArea = layer->visibleArea(); - // get two numbers here: - // - textures needed for a clipped area - // - textures needed for an un-clipped area - int nbTexturesUnclipped = m_tiledTexture->nbTextures(unclippedArea, m_scale); - int nbTexturesClipped = m_tiledTexture->nbTextures(clippedVisibleArea, m_scale); - - // Set kFixedLayers level - if (layer->isFixed()) - result->fixed += nbTexturesClipped; - - // Set kScrollableAndFixedLayers level - if (layer->contentIsScrollable() - || layer->isFixed()) - result->scrollable += nbTexturesClipped; - - // Set kClippedTextures level - result->clipped += nbTexturesClipped; - - // Set kAllTextures level - if (layer->contentIsScrollable()) - result->full += nbTexturesClipped; - else - result->full += nbTexturesUnclipped; -} - -IntRect PaintedSurface::computePrepareArea(LayerAndroid* layer) { - IntRect area; - if (!layer) - return area; - - if (!layer->contentIsScrollable() - && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { - area = layer->unclippedArea(); - double total = ((double) area.width()) * ((double) area.height()); - if (total > MAX_UNCLIPPED_AREA) - area = layer->visibleArea(); - } else { - area = layer->visibleArea(); - } - - return area; -} - -bool PaintedSurface::owns(BaseTileTexture* texture) -{ - if (m_tiledTexture) - return m_tiledTexture->owns(texture); - return false; -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h deleted file mode 100644 index 0f201a7..0000000 --- a/Source/WebCore/platform/graphics/android/PaintedSurface.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PaintedSurface_h -#define PaintedSurface_h - -#include "BaseTileTexture.h" -#include "ClassTracker.h" -#include "IntRect.h" -#include "LayerAndroid.h" -#include "SkRefCnt.h" -#include "TextureOwner.h" -#include "TilesManager.h" -#include "TilePainter.h" -#include "TransformationMatrix.h" - -class SkCanvas; -class SkRegion; - -namespace WebCore { - -class DualTiledTexture; - -class PaintedSurface : public SurfacePainter { -public: - PaintedSurface(); - virtual ~PaintedSurface(); - - // PaintedSurface methods - - void prepare(GLWebViewState*); - bool draw(); - bool paint(SkCanvas*); - - void setDrawingLayer(LayerAndroid* layer) { m_drawingLayer = layer; } - LayerAndroid* drawingLayer() { return m_drawingLayer; } - - void setPaintingLayer(LayerAndroid* layer, const SkRegion& dirtyArea); - void clearPaintingLayer() { m_paintingLayer = 0; } - LayerAndroid* paintingLayer() { return m_paintingLayer; } - - void swapTiles(); - bool isReady(); - - bool owns(BaseTileTexture* texture); - - void computeTexturesAmount(TexturesResult*); - IntRect computePrepareArea(LayerAndroid*); - - // TilePainter methods for TiledTexture - virtual const TransformationMatrix* transform(); - virtual float opacity(); - - // used by TiledTexture - float scale() { return m_scale; } - unsigned int pictureUsed() { return m_pictureUsed; } - -private: - LayerAndroid* m_drawingLayer; - LayerAndroid* m_paintingLayer; - DualTiledTexture* m_tiledTexture; - - float m_scale; - - unsigned int m_pictureUsed; - - android::Mutex m_layerLock; -}; - -} // namespace WebCore - -#endif // PaintedSurface_h diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp new file mode 100644 index 0000000..66688cf --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp @@ -0,0 +1,254 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SurfaceCollection.h" + +#include "BaseLayerAndroid.h" +#include "ClassTracker.h" +#include "LayerAndroid.h" +#include "LayerGroup.h" +#include "GLWebViewState.h" +#include "ScrollableLayerAndroid.h" + +#include +#include +#include + +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "SurfaceCollection", __VA_ARGS__) + +#ifdef DEBUG + +#undef XLOG +#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "SurfaceCollection", __VA_ARGS__) + +#else + +#undef XLOG +#define XLOG(...) + +#endif // DEBUG + +namespace WebCore { + +//////////////////////////////////////////////////////////////////////////////// +// TILED PAINTING / GROUPS // +//////////////////////////////////////////////////////////////////////////////// + +SurfaceCollection::SurfaceCollection(BaseLayerAndroid* baseLayer) + : m_baseLayer(baseLayer) + , m_compositedRoot(0) +{ + SkSafeRef(m_baseLayer); + if (m_baseLayer && m_baseLayer->countChildren()) { + m_compositedRoot = static_cast(m_baseLayer->getChild(0)); + + // calculate draw transforms and z values + SkRect visibleRect = SkRect::MakeLTRB(0, 0, 1, 1); + m_baseLayer->updateLayerPositions(visibleRect); + + // allocate groups for layers, merging where possible + XLOG("new tree, allocating groups for tree %p", m_baseLayer); + m_compositedRoot->assignGroups(&m_layerGroups); + } +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("SurfaceCollection"); +#endif +} + +SurfaceCollection::~SurfaceCollection() +{ + SkSafeUnref(m_baseLayer); + for (unsigned int i = 0; i < m_layerGroups.size(); i++) + SkSafeUnref(m_layerGroups[i]); + m_layerGroups.clear(); + +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("SurfaceCollection"); +#endif +} + +void SurfaceCollection::prepareGL(const SkRect& visibleRect, float scale, double currentTime) +{ + if (!m_baseLayer) + return; + + m_baseLayer->prepareGL(visibleRect, scale, currentTime); + + if (m_compositedRoot) { + m_baseLayer->updateLayerPositions(visibleRect); + bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode() + > GLWebViewState::kClippedTextures; + for (unsigned int i = 0; i < m_layerGroups.size(); i++) + m_layerGroups[i]->prepareGL(layerTilesDisabled); + } +} + +bool SurfaceCollection::drawGL(const SkRect& visibleRect, float scale) +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->show(); +#endif + + if (!m_baseLayer) + return false; + + m_baseLayer->drawGL(scale); + + bool needsRedraw = false; + if (m_compositedRoot) { + m_baseLayer->updateLayerPositions(visibleRect); + bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode() + > GLWebViewState::kClippedTextures; + for (unsigned int i = 0; i < m_layerGroups.size(); i++) + needsRedraw |= m_layerGroups[i]->drawGL(layerTilesDisabled); + } + + return needsRedraw; +} + +void SurfaceCollection::swapTiles() +{ + if (!m_baseLayer) + return; + + m_baseLayer->swapTiles(); + + for (unsigned int i = 0; i < m_layerGroups.size(); i++) + m_layerGroups[i]->swapTiles(); +} + +bool SurfaceCollection::isReady() +{ + if (!m_baseLayer) + return true; + + if (!m_baseLayer->isReady()) + return false; + + for (unsigned int i = 0; i < m_layerGroups.size(); i++) { + if (!m_layerGroups[i]->isReady()) { + XLOG("layer group %p isn't ready", m_layerGroups[i]); + return false; + } + } + return true; +} + +void SurfaceCollection::computeTexturesAmount(TexturesResult* result) +{ + for (unsigned int i = 0; i < m_layerGroups.size(); i++) + m_layerGroups[i]->computeTexturesAmount(result); +} + +void SurfaceCollection::drawCanvas(SkCanvas* canvas, bool drawLayers) +{ + // TODO: move this functionality out! + if (!m_baseLayer) + return; + + m_baseLayer->drawCanvas(canvas); + + // draw the layers onto the same canvas (for single surface mode) + if (drawLayers && m_compositedRoot) + m_compositedRoot->drawCanvas(canvas); +} + + +//////////////////////////////////////////////////////////////////////////////// +// RECURSIVE ANIMATION / INVALS / LAYERS // +//////////////////////////////////////////////////////////////////////////////// + +void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface) +{ + if (!m_baseLayer) + return; + + m_baseLayer->setIsPainting(); + + LayerAndroid* oldCompositedSurface = 0; + if (drawingSurface) + oldCompositedSurface = drawingSurface->m_compositedRoot; + + if (m_compositedRoot) + m_compositedRoot->setIsPainting(oldCompositedSurface); +} + +void SurfaceCollection::setIsDrawing() +{ + if (m_compositedRoot) + m_compositedRoot->initAnimations(); +} + +void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface) +{ + if (!m_baseLayer) + return; + + m_baseLayer->mergeInvalsInto(replacementSurface->m_baseLayer); + + if (m_compositedRoot && replacementSurface->m_compositedRoot) + m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot); +} + +void SurfaceCollection::evaluateAnimations(double currentTime) +{ + if (m_compositedRoot) + m_compositedRoot->evaluateAnimations(currentTime); +} + +bool SurfaceCollection::hasCompositedLayers() +{ + return m_compositedRoot != 0; +} + +bool SurfaceCollection::hasCompositedAnimations() +{ + return m_compositedRoot != 0 && m_compositedRoot->hasAnimations(); +} + +int SurfaceCollection::baseContentWidth() +{ + // TODO: move this functionality out! + return m_baseLayer ? m_baseLayer->content()->width() : 0; +} + +int SurfaceCollection::baseContentHeight() +{ + // TODO: move this functionality out! + return m_baseLayer ? m_baseLayer->content()->height() : 0; +} + +void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y) +{ + if (m_compositedRoot) { + LayerAndroid* layer = m_compositedRoot->findById(layerId); + if (layer && layer->contentIsScrollable()) + static_cast(layer)->scrollTo(x, y); + } +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/SurfaceCollection.h new file mode 100644 index 0000000..921929b --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.h @@ -0,0 +1,77 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SurfaceCollection_h +#define SurfaceCollection_h + +#include "SkRefCnt.h" +#include "SkRect.h" +#include "Vector.h" + +class SkCanvas; +class SkRegion; + +namespace WebCore { + +class BaseLayerAndroid; +class LayerAndroid; +class LayerGroup; +class TexturesResult; + +class SurfaceCollection : public SkRefCnt { +// TODO: investigate webkit threadsafe ref counting +public: + SurfaceCollection(BaseLayerAndroid* baseLayer); + virtual ~SurfaceCollection(); + + // Tiled painting methods (executed on groups) + void prepareGL(const SkRect& visibleRect, float scale, double currentTime); + bool drawGL(const SkRect& visibleRect, float scale); + void swapTiles(); + bool isReady(); + void computeTexturesAmount(TexturesResult* result); + void drawCanvas(SkCanvas* canvas, bool drawLayers); + + // Recursive tree methods (animations, invals, etc) + void setIsPainting(SurfaceCollection* drawingSurfaceCollection); + void setIsDrawing(); + void mergeInvalsInto(SurfaceCollection* replacementSurfaceCollection); + void evaluateAnimations(double currentTime); + + bool hasCompositedLayers(); + bool hasCompositedAnimations(); + int baseContentWidth(); + int baseContentHeight(); + void updateScrollableLayer(int layerId, int x, int y); + +private: + BaseLayerAndroid* m_baseLayer; + LayerAndroid* m_compositedRoot; + Vector m_layerGroups; +}; + +} // namespace WebCore + +#endif //#define SurfaceCollection_h diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp new file mode 100644 index 0000000..8ffcabd --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp @@ -0,0 +1,287 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SurfaceCollectionManager.h" + +#include "BaseLayerAndroid.h" +#include "LayerGroup.h" +#include "TilesManager.h" +#include "SurfaceCollection.h" + +#include +#include +#include + +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "SurfaceCollectionManager", __VA_ARGS__) + +#ifdef DEBUG + +#undef XLOG +#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "SurfaceCollectionManager", __VA_ARGS__) + +#else + +#undef XLOG +#define XLOG(...) + +#endif // DEBUG + +namespace WebCore { + +SurfaceCollectionManager::SurfaceCollectionManager(GLWebViewState* state) + : m_state(state) + , m_drawingCollection(0) + , m_paintingCollection(0) + , m_queuedCollection(0) + , m_fastSwapMode(false) +{ +} + +SurfaceCollectionManager::~SurfaceCollectionManager() +{ + clearCollections(); +} + +// the painting collection has finished painting: +// discard the drawing collection +// swap the painting collection in place of the drawing collection +// and start painting the queued collection +void SurfaceCollectionManager::swap() +{ + // swap can't be called unless painting just finished + ASSERT(m_paintingCollection); + + android::Mutex::Autolock lock(m_paintSwapLock); + + XLOG("SWAPPING, D %p, P %p, Q %p", + m_drawingCollection, m_paintingCollection, m_queuedCollection); + + // if we have a drawing collection, discard it since the painting collection is done + if (m_drawingCollection) { + XLOG("destroying drawing collection %p", m_drawingCollection); + SkSafeUnref(m_drawingCollection); + } + + // painting collection becomes the drawing collection + XLOG("drawing collection %p", m_paintingCollection); + m_paintingCollection->setIsDrawing(); // initialize animations + + if (m_queuedCollection) { + // start painting with the queued collection + XLOG("now painting collection %p", m_queuedCollection); + m_queuedCollection->setIsPainting(m_paintingCollection); + } + m_drawingCollection = m_paintingCollection; + m_paintingCollection = m_queuedCollection; + m_queuedCollection = 0; + + XLOG("SWAPPING COMPLETE, D %p, P %p, Q %p", + m_drawingCollection, m_paintingCollection, m_queuedCollection); +} + +// clear all of the content in the three collections held by the collection manager +void SurfaceCollectionManager::clearCollections() +{ + XLOG("SurfaceCollectionManager %p removing PS from state %p", this, m_state); + + SkSafeUnref(m_drawingCollection); + m_drawingCollection = 0; + SkSafeUnref(m_paintingCollection); + m_paintingCollection = 0; + SkSafeUnref(m_queuedCollection); + m_queuedCollection = 0; +} + +// a new layer collection has arrived, queue it if we're painting something already, +// or start painting it if we aren't. Returns true if the manager has two collections +// already queued. +bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* newCollection, + bool brandNew) +{ + XLOG("updateWithSurfaceCollection - %p, has children %d, has animations %d", + newCollection, newCollection->hasCompositedLayers(), + newCollection->hasCompositedAnimations); + + // can't have a queued collection unless have a painting collection too + ASSERT(m_paintingCollection || !m_queuedCollection); + + android::Mutex::Autolock lock(m_paintSwapLock); + + if (!newCollection || brandNew) { + clearCollections(); + if (brandNew) { + m_paintingCollection = newCollection; + m_paintingCollection->setIsPainting(m_drawingCollection); + } + return false; + } + + if (m_queuedCollection || m_paintingCollection) { + // currently painting, so defer this new collection + if (m_queuedCollection) { + // already have a queued collection, copy over invals so the regions are + // eventually repainted and let the old queued collection be discarded + m_queuedCollection->mergeInvalsInto(newCollection); + + if (!TilesManager::instance()->useDoubleBuffering()) { + // not double buffering, count discarded collection/webkit paint as an update + TilesManager::instance()->incContentUpdates(); + } + + XLOG("DISCARDING collection - %p, has children %d, has animations %d", + newCollection, newCollection->hasCompositedLayers(), + newCollection->hasCompositedAnimations()); + } + SkSafeUnref(m_queuedCollection); + m_queuedCollection = newCollection; + } else { + // don't have painting collection, paint this one! + m_paintingCollection = newCollection; + m_paintingCollection->setIsPainting(m_drawingCollection); + } + return m_drawingCollection && TilesManager::instance()->useDoubleBuffering(); +} + +void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y) +{ + if (m_queuedCollection) + m_queuedCollection->updateScrollableLayer(layerId, x, y); + if (m_paintingCollection) + m_paintingCollection->updateScrollableLayer(layerId, x, y); + if (m_drawingCollection) + m_drawingCollection->updateScrollableLayer(layerId, x, y); +} + +bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, + SkRect& visibleRect, float scale, + bool enterFastSwapMode, + bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, + TexturesResult* texturesResultPtr) +{ + m_fastSwapMode |= enterFastSwapMode; + + XLOG("drawGL, D %p, P %p, Q %p, fastSwap %d", + m_drawingCollection, m_paintingCollection, m_queuedCollection, m_fastSwapMode); + + bool ret = false; + bool didCollectionSwap = false; + if (m_paintingCollection) { + XLOG("preparing painting collection %p", m_paintingCollection); + + m_paintingCollection->evaluateAnimations(currentTime); + + m_paintingCollection->prepareGL(visibleRect, scale, currentTime); + m_paintingCollection->computeTexturesAmount(texturesResultPtr); + + if (!TilesManager::instance()->useDoubleBuffering() || m_paintingCollection->isReady()) { + XLOG("have painting collection %p ready, swapping!", m_paintingCollection); + didCollectionSwap = true; + TilesManager::instance()->incContentUpdates(); + if (collectionsSwappedPtr) + *collectionsSwappedPtr = true; + if (newCollectionHasAnimPtr) + *newCollectionHasAnimPtr = m_paintingCollection->hasCompositedAnimations(); + swap(); + } + } else if (m_drawingCollection) { + XLOG("preparing drawing collection %p", m_drawingCollection); + m_drawingCollection->prepareGL(visibleRect, scale, currentTime); + m_drawingCollection->computeTexturesAmount(texturesResultPtr); + } + + if (m_drawingCollection) { + bool drawingReady = didCollectionSwap || m_drawingCollection->isReady(); + + // call the page swap callback if registration happened without more collections enqueued + if (collectionsSwappedPtr && drawingReady && !m_paintingCollection) + *collectionsSwappedPtr = true; + + if (didCollectionSwap || m_fastSwapMode || (drawingReady && !m_paintingCollection)) + m_drawingCollection->swapTiles(); + + if (drawingReady) { + // exit fast swap mode, as content is up to date + m_fastSwapMode = false; + } else { + // drawing isn't ready, must redraw + ret = true; + } + + m_drawingCollection->evaluateAnimations(currentTime); + XLOG("drawing collection %p", m_drawingCollection); + ret |= m_drawingCollection->drawGL(visibleRect, scale); + } else { + // Dont have a drawing collection, draw white background + Color defaultBackground = Color::white; + m_state->drawBackground(defaultBackground); + } + + if (m_paintingCollection) { + XLOG("still have painting collection %p", m_paintingCollection); + return true; + } + + return ret; +} + +// draw for base tile - called on TextureGeneration thread +void SurfaceCollectionManager::drawCanvas(SkCanvas* canvas, bool drawLayers) +{ + SurfaceCollection* paintingCollection = 0; + m_paintSwapLock.lock(); + paintingCollection = m_paintingCollection ? m_paintingCollection : m_drawingCollection; + SkSafeRef(paintingCollection); + m_paintSwapLock.unlock(); + + if (!paintingCollection) + return; + + paintingCollection->drawCanvas(canvas, drawLayers); + + SkSafeUnref(paintingCollection); +} + +// TODO: refactor this functionality elsewhere +int SurfaceCollectionManager::baseContentWidth() +{ + if (m_paintingCollection) + return m_paintingCollection->baseContentWidth(); + else if (m_drawingCollection) + return m_drawingCollection->baseContentWidth(); + return 0; +} + +int SurfaceCollectionManager::baseContentHeight() +{ + if (m_paintingCollection) + return m_paintingCollection->baseContentHeight(); + else if (m_drawingCollection) + return m_drawingCollection->baseContentHeight(); + return 0; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h new file mode 100644 index 0000000..76e5e9e --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h @@ -0,0 +1,79 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SurfaceCollectionManager_h +#define SurfaceCollectionManager_h + +#include "TestExport.h" +#include + +class SkRect; +class SkCanvas; + +namespace WebCore { + +class GLWebViewState; +class IntRect; +class TexturesResult; +class SurfaceCollection; + +class TEST_EXPORT SurfaceCollectionManager { +public: + SurfaceCollectionManager(GLWebViewState* state); + + ~SurfaceCollectionManager(); + + bool updateWithSurfaceCollection(SurfaceCollection* collection, bool brandNew); + + void updateScrollableLayer(int layerId, int x, int y); + + bool drawGL(double currentTime, IntRect& viewRect, + SkRect& visibleRect, float scale, + bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, + TexturesResult* texturesResultPtr); + + void drawCanvas(SkCanvas* canvas, bool drawLayers); + + int baseContentWidth(); + int baseContentHeight(); + +private: + void swap(); + void clearCollections(); + + android::Mutex m_paintSwapLock; + + GLWebViewState* m_state; + + SurfaceCollection* m_drawingCollection; + SurfaceCollection* m_paintingCollection; + SurfaceCollection* m_queuedCollection; + + bool m_fastSwapMode; +}; + +} // namespace WebCore + +#endif //#define SurfaceCollectionManager_h diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index 4d0f5dc..04d8bf0 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -35,20 +35,15 @@ namespace WebCore { class BaseTile; -class TilePainter { +class TilePainter : public SkRefCnt { +// TODO: investigate webkit threadsafe ref counting public: - virtual ~TilePainter() { } - virtual bool paint(BaseTile* tile, SkCanvas*, unsigned int*) = 0; - virtual const TransformationMatrix* transform() { return 0; } -}; - -class SurfacePainter : public SkRefCnt { -public: - virtual ~SurfacePainter() { } - virtual const TransformationMatrix* transform() { return 0; } - virtual float opacity() { return 1.0; } - enum SurfaceType { PaintedSurface, ImageSurface }; - virtual SurfaceType type() { return PaintedSurface; } + virtual ~TilePainter() { } + virtual bool paint(BaseTile* tile, SkCanvas*, unsigned int*) = 0; + virtual const TransformationMatrix* transform() { return 0; } + virtual float opacity() { return 1.0; } + enum SurfaceType { Painted, Image }; + virtual SurfaceType type() { return Painted; } }; } diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index 1e8b946..31a439d 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -29,7 +29,6 @@ #include "TilesManager.h" #include "TilesTracker.h" -#include "PaintedSurface.h" #include "PaintTileOperation.h" #include "SkCanvas.h" #include "SkPicture.h" @@ -57,14 +56,13 @@ namespace WebCore { TiledTexture::~TiledTexture() { - SkSafeUnref(m_paintingPicture); #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("TiledTexture"); #endif removeTiles(); } -bool TiledTexture::ready() +bool TiledTexture::isReady() { bool tilesAllReady = true; bool tilesVisible = false; @@ -99,7 +97,7 @@ void TiledTexture::swapTiles() XLOG("TT %p swapping, swaps = %d", this, swaps); } -IntRect TiledTexture::computeTilesArea(IntRect& contentArea, float scale) +IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale) { IntRect computedArea; IntRect area(contentArea.x() * scale, @@ -127,18 +125,15 @@ IntRect TiledTexture::computeTilesArea(IntRect& contentArea, float scale) return computedArea; } -void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, - bool startFastSwap, IntRect& prepareArea) +void TiledTexture::prepareGL(GLWebViewState* state, float scale, + const IntRect& prepareArea, TilePainter* painter) { - if (!m_surface) - return; - // first, how many tiles do we need m_area = computeTilesArea(prepareArea, scale); if (m_area.isEmpty()) return; - XLOG("for TiledTexture %p, we prepare with scale %.2f, have a prepare area of " + XLOG("prepare TiledTexture %p with scale %.2f, prepareArea " " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles", this, scale, prepareArea.x(), prepareArea.y(), @@ -150,45 +145,36 @@ void TiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, m_prevTileY = m_area.y(); if (scale != m_scale) - TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(this, scale)); + TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, scale)); m_scale = scale; // apply dirty region to affected tiles if (!m_dirtyRegion.isEmpty()) { - for (unsigned int i = 0; i < m_tiles.size(); i++) { - // TODO: don't mark all tiles dirty + for (unsigned int i = 0; i < m_tiles.size(); i++) m_tiles[i]->markAsDirty(1, m_dirtyRegion); - } + m_dirtyRegion.setEmpty(); } - m_dirtyRegion.setEmpty(); for (int i = 0; i < m_area.width(); i++) { if (goingDown) { - for (int j = 0; j < m_area.height(); j++) { - prepareTile(repaint, m_area.x() + i, m_area.y() + j); - } + for (int j = 0; j < m_area.height(); j++) + prepareTile(m_area.x() + i, m_area.y() + j, painter); } else { - for (int j = m_area.height() - 1; j >= 0; j--) { - prepareTile(repaint, m_area.x() + i, m_area.y() + j); - } + for (int j = m_area.height() - 1; j >= 0; j--) + prepareTile(m_area.x() + i, m_area.y() + j, painter); } } } -void TiledTexture::update(const SkRegion& invalRegion, SkPicture* picture) +void TiledTexture::markAsDirty(const SkRegion& invalRegion) { - XLOG("TT %p update, current region empty %d, new empty %d, painting picture %p", - this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty(), picture); + XLOG("TT %p markAsDirty, current region empty %d, new empty %d", + this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty()); m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); - - android::Mutex::Autolock lock(m_paintingPictureSync); - SkSafeRef(picture); - SkSafeUnref(m_paintingPicture); - m_paintingPicture = picture; } -void TiledTexture::prepareTile(bool repaint, int x, int y) +void TiledTexture::prepareTile(int x, int y, TilePainter* painter) { BaseTile* tile = getTile(x, y); if (!tile) { @@ -196,18 +182,18 @@ void TiledTexture::prepareTile(bool repaint, int x, int y) m_tiles.append(tile); } - XLOG("preparing tile %p at %d, %d, painter is this %p", tile, x, y, this); - tile->setContents(this, x, y, m_scale); + XLOG("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter); + tile->setContents(painter, x, y, m_scale); // TODO: move below (which is largely the same for layers / tiled page) into - // prepare() function + // prepareGL() function if (tile->isDirty() || !tile->frontTexture()) tile->reserveTexture(); - bool hasPicture = m_paintingPicture != 0; // safely read on UI thread, since only UI thread writes - if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && hasPicture) { - PaintTileOperation *operation = new PaintTileOperation(tile, m_surface); + if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) { + XLOG("painting TT %p's tile %d %d for LG %p", this, x, y, painter); + PaintTileOperation *operation = new PaintTileOperation(tile, painter); TilesManager::instance()->scheduleOperation(operation); } } @@ -239,13 +225,8 @@ int TiledTexture::nbTextures(IntRect& area, float scale) return numberTextures; } -bool TiledTexture::draw(IntRect& visibleArea) +bool TiledTexture::drawGL(IntRect& visibleArea, float opacity) { - if (!m_surface) - return true; - - XLOG("TT %p draw", this); - #ifdef DEBUG TilesManager::instance()->getTilesTracker()->trackLayer(); #endif @@ -262,6 +243,7 @@ bool TiledTexture::draw(IntRect& visibleArea) const float tileWidth = TilesManager::layerTileWidth() * m_invScale; const float tileHeight = TilesManager::layerTileHeight() * m_invScale; + int drawn = 0; bool askRedraw = false; for (unsigned int i = 0; i < m_tiles.size(); i++) { BaseTile* tile = m_tiles[i]; @@ -273,48 +255,25 @@ bool TiledTexture::draw(IntRect& visibleArea) rect.fTop = tile->y() * tileHeight; rect.fRight = rect.fLeft + tileWidth; rect.fBottom = rect.fTop + tileHeight; - XLOG("- [%d], { painter %x vs %x }, tile %x (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d", - i, this, tile->painter(), tile, tile->isLayerTile(), tile->x(), tile->y(), + XLOG("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->draw(m_surface->opacity(), rect, m_scale); + tile->draw(opacity, rect, m_scale); + if (tile->frontTexture()) + drawn++; #ifdef DEBUG - TilesManager::instance()->getTilesTracker()->track(tile->isTileReady(), tile->backTexture()); + TilesManager::instance()->getTilesTracker()->track( + tile->isTileReady(), tile->backTexture()); #endif } } + XLOG("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; } -bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) -{ - m_paintingPictureSync.lock(); - SkPicture* picture = m_paintingPicture; - SkSafeRef(picture); - m_paintingPictureSync.unlock(); - - if (!picture) { - XLOG("TT %p COULDNT PAINT, NO PICTURE", this); - return false; - } - - XLOG("TT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), picture); - - canvas->drawPicture(*picture); - - SkSafeUnref(picture); - - return true; -} - -const TransformationMatrix* TiledTexture::transform() -{ - if (!m_surface) - return 0; - return m_surface->transform(); -} - void TiledTexture::removeTiles() { for (unsigned int i = 0; i < m_tiles.size(); i++) { @@ -325,6 +284,7 @@ void TiledTexture::removeTiles() void TiledTexture::discardTextures() { + XLOG("TT %p discarding textures", this); for (unsigned int i = 0; i < m_tiles.size(); i++) m_tiles[i]->discardTextures(); } @@ -341,10 +301,10 @@ bool TiledTexture::owns(BaseTileTexture* texture) return false; } -DualTiledTexture::DualTiledTexture(SurfacePainter* surface) +DualTiledTexture::DualTiledTexture() { - m_textureA = new TiledTexture(surface); - m_textureB = new TiledTexture(surface); + m_textureA = new TiledTexture(); + m_textureB = new TiledTexture(); m_frontTexture = m_textureA; m_backTexture = m_textureB; m_scale = -1; @@ -358,14 +318,18 @@ DualTiledTexture::~DualTiledTexture() delete m_textureB; } -void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, - bool startFastSwap, IntRect& prepareArea) +void DualTiledTexture::prepareGL(GLWebViewState* state, bool allowZoom, + const IntRect& prepareArea, TilePainter* painter) { // 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; + if (m_scale == -1) { m_scale = scale; m_futureScale = scale; @@ -377,16 +341,17 @@ void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint, m_zooming = true; } - XLOG("Preparing DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d", - this, scale, m_scale, m_futureScale, m_zooming); + XLOG("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_frontTexture->prepare(state, m_scale, repaint, startFastSwap, m_preZoomPrepareArea); + m_frontTexture->prepareGL(state, m_scale, m_preZoomPrepareArea, painter); // If we had a scheduled update if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) { - m_backTexture->prepare(state, m_futureScale, repaint, startFastSwap, prepareArea); - if (m_backTexture->ready()) { + m_backTexture->prepareGL(state, m_futureScale, prepareArea, painter); + if (m_backTexture->isReady()) { m_backTexture->swapTiles(); swap(); m_zooming = false; @@ -402,18 +367,18 @@ void DualTiledTexture::swap() m_backTexture->discardTextures(); } -bool DualTiledTexture::draw(IntRect& visibleArea) +bool DualTiledTexture::drawGL(IntRect& visibleArea, float opacity) { - bool needsRepaint = m_frontTexture->draw(visibleArea); + bool needsRepaint = m_frontTexture->drawGL(visibleArea, opacity); needsRepaint |= m_zooming; needsRepaint |= (m_scale <= 0); return needsRepaint; } -void DualTiledTexture::update(const SkRegion& dirtyArea, SkPicture* picture) +void DualTiledTexture::markAsDirty(const SkRegion& dirtyArea) { - m_backTexture->update(dirtyArea, picture); - m_frontTexture->update(dirtyArea, picture); + m_backTexture->markAsDirty(dirtyArea); + m_frontTexture->markAsDirty(dirtyArea); } void DualTiledTexture::swapTiles() @@ -429,4 +394,39 @@ bool DualTiledTexture::owns(BaseTileTexture* texture) return owns; } +void DualTiledTexture::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer) +{ + // TODO: shouldn't use layer, as this DTT may paint multiple layers + if (!layer) + return; + + IntRect unclippedArea = layer->unclippedArea(); + IntRect clippedVisibleArea = layer->visibleArea(); + + // get two numbers here: + // - textures needed for a clipped area + // - textures needed for an un-clipped area + TiledTexture* tiledTexture = m_zooming ? m_backTexture : m_frontTexture; + int nbTexturesUnclipped = tiledTexture->nbTextures(unclippedArea, m_scale); + int nbTexturesClipped = tiledTexture->nbTextures(clippedVisibleArea, m_scale); + + // Set kFixedLayers level + if (layer->isFixed()) + result->fixed += nbTexturesClipped; + + // Set kScrollableAndFixedLayers level + if (layer->contentIsScrollable() + || layer->isFixed()) + result->scrollable += nbTexturesClipped; + + // Set kClippedTextures level + result->clipped += nbTexturesClipped; + + // Set kAllTextures level + if (layer->contentIsScrollable()) + result->full += nbTexturesClipped; + else + result->full += nbTexturesUnclipped; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h index 971a99f..ee1c28c 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.h +++ b/Source/WebCore/platform/graphics/android/TiledTexture.h @@ -31,6 +31,7 @@ #include "ClassTracker.h" #include "IntRect.h" #include "LayerAndroid.h" +#include "SkRefCnt.h" #include "SkRegion.h" #include "TextureOwner.h" #include "TilePainter.h" @@ -39,12 +40,10 @@ class SkCanvas; namespace WebCore { -class TiledTexture : public TilePainter { +class TiledTexture { public: - TiledTexture(SurfacePainter* surface) - : m_paintingPicture(0) - , m_surface(surface) - , m_prevTileX(0) + TiledTexture() + : m_prevTileX(0) , m_prevTileY(0) , m_scale(1) , m_swapWhateverIsReady(false) @@ -57,15 +56,15 @@ public: virtual ~TiledTexture(); - IntRect computeTilesArea(IntRect& contentArea, float scale); + IntRect computeTilesArea(const IntRect& contentArea, float scale); - void prepare(GLWebViewState* state, float scale, bool repaint, - bool startFastSwap, IntRect& prepareArea); + void prepareGL(GLWebViewState* state, float scale, + const IntRect& prepareArea, TilePainter* painter); void swapTiles(); - bool draw(IntRect& visibleArea); + bool drawGL(IntRect& visibleArea, float opacity); - void prepareTile(bool repaint, int x, int y); - void update(const SkRegion& dirtyArea, SkPicture* picture); + void prepareTile(int x, int y, TilePainter* painter); + void markAsDirty(const SkRegion& dirtyArea); BaseTile* getTile(int x, int y); @@ -73,28 +72,17 @@ public: void discardTextures(); bool owns(BaseTileTexture* texture); - // TilePainter methods - bool paint(BaseTile* tile, SkCanvas*, unsigned int*); - virtual const TransformationMatrix* transform(); - float scale() { return m_scale; } - bool ready(); + bool isReady(); int nbTextures(IntRect& area, float scale); private: bool tileIsVisible(BaseTile* tile); - // protect m_paintingPicture - // update() on UI thread modifies - // paint() on texture gen thread reads - android::Mutex m_paintingPictureSync; - SkPicture* m_paintingPicture; - - SurfacePainter* m_surface; Vector m_tiles; - // tile coordinates in viewport, set in prepare() + // tile coordinates in viewport, set in prepareGL() IntRect m_area; SkRegion m_dirtyRegion; @@ -106,20 +94,27 @@ private: bool m_swapWhateverIsReady; }; -class DualTiledTexture { +class DualTiledTexture : public SkRefCnt { +// TODO: investigate webkit threadsafe ref counting public: - DualTiledTexture(SurfacePainter* surface); + DualTiledTexture(); ~DualTiledTexture(); - void prepare(GLWebViewState* state, float scale, bool repaint, - bool startFastSwap, IntRect& area); + void prepareGL(GLWebViewState* state, bool allowZoom, + const IntRect& prepareArea, TilePainter* painter); void swapTiles(); void swap(); - bool draw(IntRect& visibleArea); - void update(const SkRegion& dirtyArea, SkPicture* picture); + bool drawGL(IntRect& visibleArea, float opacity); + void markAsDirty(const SkRegion& dirtyArea); bool owns(BaseTileTexture* texture); + void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer); + void discardTextures() + { + m_textureA->discardTextures(); + m_textureB->discardTextures(); + } bool isReady() { - return !m_zooming && m_frontTexture->ready(); + return !m_zooming && m_frontTexture->isReady(); } int nbTextures(IntRect& area, float scale) diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index 6640230..93452b9 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -29,7 +29,6 @@ #if USE(ACCELERATED_COMPOSITING) #include "BaseTile.h" -#include "PaintedSurface.h" #include "SkCanvas.h" #include "SkDevice.h" #include "SkPaint.h" @@ -105,7 +104,7 @@ TilesManager::TilesManager() , m_invertedScreenSwitch(false) , m_useMinimalMemory(true) , m_useDoubleBuffering(true) - , m_treeUpdates(0) + , m_contentUpdates(0) , m_queue(0) , m_drawGLCount(1) , m_lastTimeLayersUsed(0) @@ -262,11 +261,6 @@ void TilesManager::printTextures() #endif // DEBUG } -void TilesManager::addPaintedSurface(PaintedSurface* surface) -{ - m_paintedSurfaces.append(surface); -} - void TilesManager::gatherTextures() { android::Mutex::Autolock lock(m_texturesLock); @@ -307,9 +301,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) // busy anyway // 2. If a tile isn't owned, break with that one // 3. Don't let tiles acquire their front textures - // 4. If we find a tile in the same page with a different scale, - // it's old and not visible. Break with that one - // 5. Otherwise, use the least recently prepared tile, but ignoring tiles + // 4. Otherwise, use the least recently prepared tile, but ignoring tiles // drawn in the last frame to avoid flickering BaseTileTexture* farthestTexture = 0; @@ -330,14 +322,6 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) continue; } - if (currentOwner->painter() == owner->painter() && texture->scale() != owner->scale()) { - // if we render the back page with one scale, then another while - // still zooming, we recycle the tiles with the old scale instead of - // taking ones from the front page - farthestTexture = texture; - break; - } - unsigned long long textureDrawCount = currentOwner->drawCount(); if (oldestDrawCount > textureDrawCount) { farthestTexture = texture; @@ -478,50 +462,6 @@ float TilesManager::layerTileHeight() return LAYER_TILE_HEIGHT; } -void TilesManager::paintedSurfacesCleanup(GLWebViewState* state) -{ - // PaintedSurfaces are created by LayerAndroid with a refcount of 1, - // and just transferred to new (corresponding) layers when a new layer tree - // is received. - // PaintedSurface also keep a reference on the Layer it currently has, so - // when we unref the tree of layer, those layers with a PaintedSurface will - // still be around if we do nothing. - // Here, if the surface does not have any associated layer, it means that we - // received a new layer tree without a corresponding layer (i.e. a layer - // using a texture has been removed by webkit). - // In that case, we remove the PaintedSurface from our list, and unref it. - // If the surface does have a layer, but the GLWebViewState associated to - // that layer is different from the one passed in parameter, it means we can - // also remove the surface (and we also remove/unref any layer that surface - // has). We do this when we deallocate GLWebViewState (i.e. the webview has - // been destroyed) and also when we switch to a page without - // composited layers. - - WTF::Vector collect; - for (unsigned int i = 0; i < m_paintedSurfaces.size(); i++) { - PaintedSurface* surface = m_paintedSurfaces[i]; - - Layer* drawing = surface->drawingLayer(); - Layer* painting = surface->paintingLayer(); - - XLOG("considering PS %p, drawing %p, painting %p", surface, drawing, painting); - - bool drawingMatchesState = state && drawing && (drawing->state() == state); - bool paintingMatchesState = state && painting && (painting->state() == state); - - if ((!painting && !drawing) || drawingMatchesState || paintingMatchesState) { - XLOG("trying to remove PS %p, painting %p, drawing %p, DMS %d, PMS %d", - surface, painting, drawing, drawingMatchesState, paintingMatchesState); - collect.append(surface); - } - } - for (unsigned int i = 0; i < collect.size(); i++) { - PaintedSurface* surface = collect[i]; - m_paintedSurfaces.remove(m_paintedSurfaces.find(surface)); - SkSafeUnref(surface); - } -} - TilesManager* TilesManager::instance() { if (!gInstance) { diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h index 749ba98..a5b5930 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/TilesManager.h @@ -45,8 +45,6 @@ namespace WebCore { -class PaintedSurface; - class TilesManager { public: static TilesManager* instance(); @@ -78,9 +76,6 @@ public: m_pixmapsGenerationThread->scheduleOperation(operation); } - void swapLayersTextures(LayerAndroid* newTree, LayerAndroid* oldTree); - void addPaintedSurface(PaintedSurface* surface); - ShaderProgram* shader() { return &m_shader; } TransferQueue* transferQueue(); VideoLayerManager* videoLayerManager() { return &m_videoLayerManager; } @@ -121,7 +116,6 @@ public: static float tileHeight(); static float layerTileWidth(); static float layerTileHeight(); - void paintedSurfacesCleanup(GLWebViewState* state = 0); void allocateTiles(); @@ -191,9 +185,9 @@ public: } bool useDoubleBuffering() { return m_useDoubleBuffering; } - void incTreeUpdates() { m_treeUpdates++; } - unsigned int getTreeUpdates() { return m_treeUpdates; } - void clearTreeUpdates() { m_treeUpdates = 0; } + void incContentUpdates() { m_contentUpdates++; } + unsigned int getContentUpdates() { return m_contentUpdates; } + void clearContentUpdates() { m_contentUpdates = 0; } void incDrawGLCount() { @@ -205,11 +199,6 @@ public: return m_drawGLCount; } - int getPaintedSurfaceCount() - { - return m_paintedSurfaces.size(); - } - private: TilesManager(); @@ -231,8 +220,6 @@ private: Vector m_availableTilesTextures; bool m_layerTexturesRemain; - Vector m_paintedSurfaces; - bool m_highEndGfx; int m_maxTextureCount; int m_maxLayerTextureCount; @@ -246,7 +233,7 @@ private: bool m_useMinimalMemory; bool m_useDoubleBuffering; - unsigned int m_treeUpdates; + unsigned int m_contentUpdates; // nr of successful tiled paints sp m_pixmapsGenerationThread; diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index 35a36dd..107bd82 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -29,7 +29,8 @@ #if USE(ACCELERATED_COMPOSITING) #include "BaseTile.h" -#include "PaintedSurface.h" +#include "GLUtils.h" +#include "TilesManager.h" #include #include #include diff --git a/Source/WebCore/platform/graphics/android/TreeManager.cpp b/Source/WebCore/platform/graphics/android/TreeManager.cpp deleted file mode 100644 index fd5e525..0000000 --- a/Source/WebCore/platform/graphics/android/TreeManager.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "TreeManager.h" - -#include "Layer.h" -#include "BaseLayerAndroid.h" -#include "ScrollableLayerAndroid.h" -#include "TilesManager.h" - -#include -#include -#include - -#undef XLOGC -#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "TreeManager", __VA_ARGS__) - -#ifdef DEBUG - -#undef XLOG -#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "TreeManager", __VA_ARGS__) - -#else - -#undef XLOG -#define XLOG(...) - -#endif // DEBUG - -namespace WebCore { - -TreeManager::TreeManager(GLWebViewState* state) - : m_state(state) - , m_drawingTree(0) - , m_paintingTree(0) - , m_queuedTree(0) - , m_fastSwapMode(false) -{ -} - -TreeManager::~TreeManager() -{ - clearTrees(); -} - -// the painting tree has finished painting: -// discard the drawing tree -// swap the painting tree in place of the drawing tree -// and start painting the queued tree -void TreeManager::swap() -{ - // swap can't be called unless painting just finished - ASSERT(m_paintingTree); - - android::Mutex::Autolock lock(m_paintSwapLock); - - XLOG("SWAPPING, D %p, P %p, Q %p", m_drawingTree, m_paintingTree, m_queuedTree); - - // if we have a drawing tree, discard it since the painting tree is done - if (m_drawingTree) { - XLOG("destroying drawing tree %p", m_drawingTree); - m_drawingTree->setIsDrawing(false); - SkSafeUnref(m_drawingTree); - } - - // painting tree becomes the drawing tree - XLOG("drawing tree %p", m_paintingTree); - m_paintingTree->setIsDrawing(true); - if (m_paintingTree->countChildren()) - static_cast(m_paintingTree->getChild(0))->initAnimations(); - - if (m_queuedTree) { - // start painting with the queued tree - XLOG("now painting tree %p", m_queuedTree); - m_queuedTree->setIsPainting(m_paintingTree); - } - m_drawingTree = m_paintingTree; - m_paintingTree = m_queuedTree; - m_queuedTree = 0; - - TilesManager::instance()->paintedSurfacesCleanup(); - - XLOG("SWAPPING COMPLETE, D %p, P %p, Q %p", m_drawingTree, m_paintingTree, m_queuedTree); -} - -// clear all of the content in the three trees held by the tree manager -void TreeManager::clearTrees() -{ - // remove painted surfaces from any tree in this view, and set trees as no - // longer drawing, to clear ptrs from surfaces to layers - if (m_drawingTree) - m_drawingTree->setIsDrawing(false); - if (m_paintingTree) - m_paintingTree->setIsDrawing(false); - - XLOG("TreeManager %p removing PS from state %p", this, m_state); - TilesManager::instance()->paintedSurfacesCleanup(m_state); - - SkSafeUnref(m_drawingTree); - m_drawingTree = 0; - SkSafeUnref(m_paintingTree); - m_paintingTree = 0; - SkSafeUnref(m_queuedTree); - m_queuedTree = 0; -} - -// a new layer tree has arrived, queue it if we're painting something already, -// or start painting it if we aren't. Returns true if the manager has two trees -// already queued. -bool TreeManager::updateWithTree(Layer* newTree, bool brandNew) -{ - XLOG("updateWithTree - %p, has children %d, has animations %d", - newTree, newTree && newTree->countChildren(), - newTree && newTree->countChildren() - ? static_cast(newTree->getChild(0))->hasAnimations() : 0); - - // can't have a queued tree unless have a painting tree too - ASSERT(m_paintingTree || !m_queuedTree); - - SkSafeRef(newTree); - - android::Mutex::Autolock lock(m_paintSwapLock); - - if (!newTree || brandNew) { - clearTrees(); - if (brandNew) { - m_paintingTree = newTree; - m_paintingTree->setIsPainting(m_drawingTree); - } - return false; - } - - if (m_queuedTree || m_paintingTree) { - // currently painting, so defer this new tree - if (m_queuedTree) { - // already have a queued tree, copy over invals so the regions are - // eventually repainted and let the old queued tree be discarded - m_queuedTree->mergeInvalsInto(newTree); - - if (!TilesManager::instance()->useDoubleBuffering()) { - // not double buffering, count discarded tree/webkit paint as an update - TilesManager::instance()->incTreeUpdates(); - } - - XLOG("DISCARDING tree - %p, has children %d, has animations %d", - newTree, newTree && newTree->countChildren(), - newTree && newTree->countChildren() - ? static_cast(newTree->getChild(0))->hasAnimations() : 0); - } - SkSafeUnref(m_queuedTree); - m_queuedTree = newTree; - } else { - // don't have painting tree, paint this one! - m_paintingTree = newTree; - m_paintingTree->setIsPainting(m_drawingTree); - } - return m_drawingTree && TilesManager::instance()->useDoubleBuffering(); -} - -void TreeManager::updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y) -{ - LayerAndroid* layer; - if (tree && tree->countChildren()) { - layer = static_cast(tree->getChild(0))->findById(layerId); - if (layer && layer->contentIsScrollable()) - static_cast(layer)->scrollTo(x, y); - } -} - -void TreeManager::updateScrollableLayer(int layerId, int x, int y) -{ - updateScrollableLayerInTree(m_queuedTree, layerId, x, y); - updateScrollableLayerInTree(m_paintingTree, layerId, x, y); - updateScrollableLayerInTree(m_drawingTree, layerId, x, y); -} - -bool TreeManager::drawGL(double currentTime, IntRect& viewRect, - SkRect& visibleRect, float scale, - bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr, - TexturesResult* texturesResultPtr) -{ - m_fastSwapMode |= enterFastSwapMode; - - XLOG("drawGL, D %p, P %p, Q %p, fastSwap %d", - m_drawingTree, m_paintingTree, m_queuedTree, m_fastSwapMode); - - bool ret = false; - bool didTreeSwap = false; - if (m_paintingTree) { - XLOG("preparing painting tree %p", m_paintingTree); - - LayerAndroid* laTree = 0; - if (m_paintingTree->countChildren()) { - laTree = static_cast(m_paintingTree->getChild(0)); - ret |= laTree->evaluateAnimations(currentTime); - } - - ret |= m_paintingTree->prepare(currentTime, viewRect, - visibleRect, scale); - - if (laTree) - laTree->computeTexturesAmount(texturesResultPtr); - - if (!TilesManager::instance()->useDoubleBuffering() || m_paintingTree->isReady()) { - XLOG("have painting tree %p ready, swapping!", m_paintingTree); - didTreeSwap = true; - TilesManager::instance()->incTreeUpdates(); - swap(); - if (treesSwappedPtr) - *treesSwappedPtr = true; - if (laTree && newTreeHasAnimPtr) - *newTreeHasAnimPtr = laTree->hasAnimations(); - } - } else if (m_drawingTree) { - XLOG("preparing drawing tree %p", m_drawingTree); - ret |= m_drawingTree->prepare(currentTime, viewRect, - visibleRect, scale); - if (m_drawingTree->countChildren()) { - LayerAndroid* laTree = static_cast(m_drawingTree->getChild(0)); - laTree->computeTexturesAmount(texturesResultPtr); - } - } - - - if (m_drawingTree) { - bool drawingReady = didTreeSwap || m_drawingTree->isReady(); - - // call the page swap callback if registration happened without more trees enqueued - if (treesSwappedPtr && drawingReady && !m_paintingTree) - *treesSwappedPtr = true; - - if (didTreeSwap || m_fastSwapMode || (drawingReady && !m_paintingTree)) - m_drawingTree->swapTiles(); - - if (drawingReady) { - // exit fast swap mode, as content is up to date - m_fastSwapMode = false; - } else { - // drawing isn't ready, must redraw - ret = true; - } - - if (m_drawingTree->countChildren()) { - LayerAndroid* laTree = static_cast(m_drawingTree->getChild(0)); - ret |= laTree->evaluateAnimations(currentTime); - } - XLOG("drawing tree %p", m_drawingTree); - ret |= m_drawingTree->drawGL(viewRect, visibleRect, scale); - } else if (m_paintingTree && m_paintingTree->state()) { - // Dont have a drawing tree, draw white background - Color defaultBackground = Color::white; - m_paintingTree->state()->drawBackground(defaultBackground); - } - - if (m_paintingTree) { - XLOG("still have painting tree %p", m_paintingTree); - return true; - } - - return ret; -} - -int TreeManager::getTotalPaintedSurfaceCount() -{ - return TilesManager::instance()->getPaintedSurfaceCount(); -} - -// draw for base tile - called on TextureGeneration thread -void TreeManager::drawCanvas(SkCanvas* canvas, bool drawLayers) -{ - BaseLayerAndroid* paintingTree = 0; - m_paintSwapLock.lock(); - if (m_paintingTree) - paintingTree = static_cast(m_paintingTree); - else - paintingTree = static_cast(m_drawingTree); - SkSafeRef(paintingTree); - m_paintSwapLock.unlock(); - - if (!paintingTree) - return; - - - paintingTree->drawCanvas(canvas); - - if (drawLayers && paintingTree->countChildren()) { - // draw the layers onto the canvas as well - Layer* layers = paintingTree->getChild(0); - static_cast(layers)->drawCanvas(canvas); - } - - SkSafeUnref(paintingTree); -} - -int TreeManager::baseContentWidth() -{ - if (m_paintingTree) { - return static_cast(m_paintingTree)->content()->width(); - } else if (m_drawingTree) { - return static_cast(m_drawingTree)->content()->width(); - } - return 0; -} - -int TreeManager::baseContentHeight() -{ - if (m_paintingTree) { - return static_cast(m_paintingTree)->content()->height(); - } else if (m_drawingTree) { - return static_cast(m_drawingTree)->content()->height(); - } - return 0; -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TreeManager.h b/Source/WebCore/platform/graphics/android/TreeManager.h deleted file mode 100644 index a571d1a..0000000 --- a/Source/WebCore/platform/graphics/android/TreeManager.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TreeManager_h -#define TreeManager_h - -#include "TestExport.h" -#include -#include "PerformanceMonitor.h" - -class Layer; -class SkRect; -class SkCanvas; - -namespace WebCore { - -class GLWebViewState; -class IntRect; -class TexturesResult; - -class TEST_EXPORT TreeManager { -public: - TreeManager(GLWebViewState* state); - - ~TreeManager(); - - bool updateWithTree(Layer* tree, bool brandNew); - - void updateScrollableLayer(int layerId, int x, int y); - - bool drawGL(double currentTime, IntRect& viewRect, - SkRect& visibleRect, float scale, - bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr, - TexturesResult* texturesResultPtr); - - void drawCanvas(SkCanvas* canvas, bool drawLayers); - - // used in debugging (to avoid exporting TilesManager symbols) - static int getTotalPaintedSurfaceCount(); - - int baseContentWidth(); - int baseContentHeight(); - -private: - static void updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y); - - void swap(); - void clearTrees(); - - android::Mutex m_paintSwapLock; - - GLWebViewState* m_state; - - Layer* m_drawingTree; - Layer* m_paintingTree; - Layer* m_queuedTree; - - bool m_fastSwapMode; - PerformanceMonitor m_perf; -}; - -} // namespace WebCore - -#endif //#define TreeManager_h diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp index a527e6a..46a8c1d 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp @@ -196,7 +196,7 @@ SkRect VideoLayerAndroid::calVideoRect(const SkRect& rect) return videoRect; } -bool VideoLayerAndroid::drawGL() +bool VideoLayerAndroid::drawGL(bool layerTilesDisabled) { // Lazily allocated the textures. if (!m_createdTexture) { @@ -284,8 +284,7 @@ bool VideoLayerAndroid::drawGL() } } - // Don't short circuit here since we still want to draw the children. - return drawChildrenGL() || needRedraw; + return needRedraw; } } diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h index 6bd9fa1..8ec16d4 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h @@ -57,7 +57,7 @@ public: virtual LayerAndroid* copy() const { return new VideoLayerAndroid(*this); } // The following 3 functions are called in UI thread only. - virtual bool drawGL(); + virtual bool drawGL(bool layerTilesDisabled); void setSurfaceTexture(sp texture, int textureName, PlayerState playerState); GLuint createBackgroundTexture(); GLuint createSpinnerOuterTexture(); -- cgit v1.1