summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2012-02-23 13:10:41 -0800
committerChris Craik <ccraik@google.com>2012-02-28 16:18:19 -0800
commitd8be9016b7fda67a91b4ee17b3b2e7ba692ee553 (patch)
tree071de9016650d451a21cb3bb1c2fee3c914b33b6 /Source
parent7a5ba79e8c522b61d1dba7cb6766ee6bc756386f (diff)
downloadexternal_webkit-d8be9016b7fda67a91b4ee17b3b2e7ba692ee553.zip
external_webkit-d8be9016b7fda67a91b4ee17b3b2e7ba692ee553.tar.gz
external_webkit-d8be9016b7fda67a91b4ee17b3b2e7ba692ee553.tar.bz2
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
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/Android.mk5
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp103
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.h19
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp51
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h8
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.cpp25
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.h7
-rw-r--r--Source/WebCore/platform/graphics/android/Layer.h21
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp221
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h24
-rw-r--r--Source/WebCore/platform/graphics/android/LayerGroup.cpp203
-rw-r--r--Source/WebCore/platform/graphics/android/LayerGroup.h (renamed from Source/WebCore/platform/graphics/android/PaintedSurface.h)69
-rw-r--r--Source/WebCore/platform/graphics/android/MediaLayer.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/MediaLayer.h2
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.cpp15
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.h10
-rw-r--r--Source/WebCore/platform/graphics/android/PaintedSurface.cpp226
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollection.cpp254
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollection.h77
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp287
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h (renamed from Source/WebCore/platform/graphics/android/TreeManager.h)33
-rw-r--r--Source/WebCore/platform/graphics/android/TilePainter.h21
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.cpp178
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.h57
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp64
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h21
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.cpp338
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.h2
-rw-r--r--Source/WebKit/android/nav/WebView.cpp4
33 files changed, 1175 insertions, 1190 deletions
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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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 <wtf/CurrentTime.h>
#include <pthread.h>
@@ -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 <utils/threads.h>
@@ -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<LayerAndroid*>(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<LayerAndroid*>(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<LayerGroup*>* 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 <LayerAndroid*> 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 <LayerAndroid*> 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<LayerGroup*>* 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 <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#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/PaintedSurface.h b/Source/WebCore/platform/graphics/android/LayerGroup.h
index 0f201a7..1b90f4b 100644
--- a/Source/WebCore/platform/graphics/android/PaintedSurface.h
+++ b/Source/WebCore/platform/graphics/android/LayerGroup.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, The Android Open Source Project
+ * 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
@@ -23,72 +23,49 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PaintedSurface_h
-#define PaintedSurface_h
+#ifndef LayerGroup_h
+#define LayerGroup_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"
+#include "Vector.h"
class SkCanvas;
class SkRegion;
namespace WebCore {
+class BaseTile;
class DualTiledTexture;
+class TexturesResult;
+class LayerAndroid;
-class PaintedSurface : public SurfacePainter {
+class LayerGroup : public TilePainter {
public:
- PaintedSurface();
- virtual ~PaintedSurface();
+ LayerGroup();
+ virtual ~LayerGroup();
- // 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 initializeGroup(LayerAndroid* newLayer, const SkRegion& newLayerInval,
+ LayerAndroid* oldLayer);
+ void addLayer(LayerAndroid* layer);
+ void prepareGL(bool layerTilesDisabled);
+ bool drawGL(bool layerTilesDisabled);
void swapTiles();
bool isReady();
- bool owns(BaseTileTexture* texture);
+ IntRect computePrepareArea();
+ void computeTexturesAmount(TexturesResult* result);
- void computeTexturesAmount(TexturesResult*);
- IntRect computePrepareArea(LayerAndroid*);
-
- // TilePainter methods for TiledTexture
+ // TilePainter methods
+ virtual bool paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed);
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;
+ bool m_hasText;
+ DualTiledTexture* m_dualTiledTexture;
+ Vector<LayerAndroid*> m_layers;
};
} // namespace WebCore
-#endif // PaintedSurface_h
+#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<ImageTexture*>(m_surface);
+ if (m_painter && m_painter->type() == TilePainter::Image) {
+ ImageTexture* image = static_cast<ImageTexture*>(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 <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#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/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 <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#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<LayerAndroid*>(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<ScrollableLayerAndroid*>(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<LayerGroup*> 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 <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#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/TreeManager.h b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h
index a571d1a..76e5e9e 100644
--- a/Source/WebCore/platform/graphics/android/TreeManager.h
+++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.h
@@ -23,14 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef TreeManager_h
-#define TreeManager_h
+#ifndef SurfaceCollectionManager_h
+#define SurfaceCollectionManager_h
#include "TestExport.h"
#include <utils/threads.h>
-#include "PerformanceMonitor.h"
-class Layer;
class SkRect;
class SkCanvas;
@@ -39,48 +37,43 @@ namespace WebCore {
class GLWebViewState;
class IntRect;
class TexturesResult;
+class SurfaceCollection;
-class TEST_EXPORT TreeManager {
+class TEST_EXPORT SurfaceCollectionManager {
public:
- TreeManager(GLWebViewState* state);
+ SurfaceCollectionManager(GLWebViewState* state);
- ~TreeManager();
+ ~SurfaceCollectionManager();
- bool updateWithTree(Layer* tree, bool brandNew);
+ 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* treesSwappedPtr, bool* newTreeHasAnimPtr,
+ bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
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();
+ void clearCollections();
android::Mutex m_paintSwapLock;
GLWebViewState* m_state;
- Layer* m_drawingTree;
- Layer* m_paintingTree;
- Layer* m_queuedTree;
+ SurfaceCollection* m_drawingCollection;
+ SurfaceCollection* m_paintingCollection;
+ SurfaceCollection* m_queuedCollection;
bool m_fastSwapMode;
- PerformanceMonitor m_perf;
};
} // namespace WebCore
-#endif //#define TreeManager_h
+#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<BaseTile*> 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<PaintedSurface*> 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<BaseTileTexture*> m_availableTilesTextures;
bool m_layerTexturesRemain;
- Vector<PaintedSurface*> 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<TexturesGenerator> 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 <android/native_window.h>
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
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 <cutils/log.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/text/CString.h>
-
-#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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(tree->getChild(0))->findById(layerId);
- if (layer && layer->contentIsScrollable())
- static_cast<ScrollableLayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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<LayerAndroid*>(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<BaseLayerAndroid*>(m_paintingTree);
- else
- paintingTree = static_cast<BaseLayerAndroid*>(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<LayerAndroid*>(layers)->drawCanvas(canvas);
- }
-
- SkSafeUnref(paintingTree);
-}
-
-int TreeManager::baseContentWidth()
-{
- if (m_paintingTree) {
- return static_cast<BaseLayerAndroid*>(m_paintingTree)->content()->width();
- } else if (m_drawingTree) {
- return static_cast<BaseLayerAndroid*>(m_drawingTree)->content()->width();
- }
- return 0;
-}
-
-int TreeManager::baseContentHeight()
-{
- if (m_paintingTree) {
- return static_cast<BaseLayerAndroid*>(m_paintingTree)->content()->height();
- } else if (m_drawingTree) {
- return static_cast<BaseLayerAndroid*>(m_drawingTree)->content()->height();
- }
- return 0;
-}
-
-} // namespace WebCore
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<SurfaceTexture> texture, int textureName, PlayerState playerState);
GLuint createBackgroundTexture();
GLuint createSpinnerOuterTexture();
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 6aed700..2e74405 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -1394,7 +1394,7 @@ static bool nativeSetProperty(JNIEnv *env, jobject obj, jstring jkey, jstring jv
return true;
}
else if (key == "tree_updates") {
- TilesManager::instance()->clearTreeUpdates();
+ TilesManager::instance()->clearContentUpdates();
return true;
}
return false;
@@ -1404,7 +1404,7 @@ static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring jkey)
{
WTF::String key = jstringToWtfString(env, jkey);
if (key == "tree_updates") {
- int updates = TilesManager::instance()->getTreeUpdates();
+ int updates = TilesManager::instance()->getContentUpdates();
WTF::String wtfUpdates = WTF::String::number(updates);
return wtfStringToJstring(env, wtfUpdates);
}