diff options
Diffstat (limited to 'Source')
40 files changed, 1276 insertions, 1309 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/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index a62d2f3..395b7cf 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -306,3 +306,4 @@ z-index -webkit-user-drag -webkit-user-modify -webkit-user-select +-webkit-overflow-scrolling diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in index 6dac06f..5b6e5b0 100644 --- a/Source/WebCore/css/CSSValueKeywords.in +++ b/Source/WebCore/css/CSSValueKeywords.in @@ -756,6 +756,10 @@ windowed manual # auto +# -webkit-overflow-scrolling +# auto +touch + # -webkit-writing-mode # SVG compatibility lr 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 a29ab82..1b554c7 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) @@ -466,7 +468,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; @@ -495,9 +497,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); @@ -525,10 +524,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(); @@ -574,7 +573,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 @@ -592,7 +591,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, resetFrameworkInval(); } - showFrameInfo(rect, *treesSwappedPtr); + showFrameInfo(rect, *collectionsSwappedPtr); #ifdef DEBUG tilesManager->getTilesTracker()->showTrackTextures(); @@ -601,7 +600,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(); @@ -632,18 +631,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..48e4f27 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp @@ -0,0 +1,263 @@ +/* + * 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; + + if (!m_compositedRoot) + return true; + + // Override layer readiness check for single surface mode + if (m_compositedRoot->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) { + // TODO: single surface mode should be properly double buffered + return true; + } + + 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 184d80c..a284687 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) @@ -261,11 +260,6 @@ void TilesManager::printTextures() #endif // DEBUG } -void TilesManager::addPaintedSurface(PaintedSurface* surface) -{ - m_paintedSurfaces.append(surface); -} - void TilesManager::gatherTextures() { android::Mutex::Autolock lock(m_texturesLock); @@ -306,9 +300,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; @@ -329,14 +321,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; @@ -477,50 +461,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 b670055..98fc08c 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; } @@ -118,7 +113,6 @@ public: static float tileHeight(); static float layerTileWidth(); static float layerTileHeight(); - void paintedSurfacesCleanup(GLWebViewState* state = 0); void allocateTiles(); @@ -188,9 +182,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() { @@ -202,11 +196,6 @@ public: return m_drawGLCount; } - int getPaintedSurfaceCount() - { - return m_paintedSurfaces.size(); - } - private: TilesManager(); @@ -228,8 +217,6 @@ private: Vector<BaseTileTexture*> m_availableTilesTextures; bool m_layerTexturesRemain; - Vector<PaintedSurface*> m_paintedSurfaces; - bool m_highEndGfx; int m_maxTextureCount; int m_maxLayerTextureCount; @@ -243,7 +230,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..8ad9119 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> @@ -155,8 +156,7 @@ bool TransferQueue::checkObsolete(const TileTransferData* data) if (tileInfo->m_x != baseTilePtr->x() || tileInfo->m_y != baseTilePtr->y() - || tileInfo->m_scale != baseTilePtr->scale() - || tileInfo->m_painter != baseTilePtr->painter()) { + || tileInfo->m_scale != baseTilePtr->scale()) { XLOG("Mismatching x, y, scale or painter , such that the tile is obsolete"); return true; } 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 d325a7e..e48d36c 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp @@ -128,7 +128,7 @@ SkRect VideoLayerAndroid::calVideoRect(const SkRect& rect) return videoRect; } -bool VideoLayerAndroid::drawGL() +bool VideoLayerAndroid::drawGL(bool layerTilesDisabled) { // Lazily allocated the textures. TilesManager* tilesManager = TilesManager::instance(); @@ -213,8 +213,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 f20eb65..29b1bdc 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); private: diff --git a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp index b684a1a..e536701 100644 --- a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp @@ -49,6 +49,8 @@ #include <wtf/android/AndroidThreading.h> #include <wtf/MainThread.h> +#include <algorithm> + using namespace android; namespace WebCore { @@ -169,18 +171,21 @@ void PlatformBridge::updateTextfield(FrameView* frameView, Node* nodePtr, bool c } void PlatformBridge::setScrollPosition(ScrollView* scrollView, int x, int y) { + FrameView* frameView = scrollView->frameView(); + if (!frameView) return; // Check to make sure the view is the main FrameView. android::WebViewCore *webViewCore = android::WebViewCore::getWebViewCore(scrollView); - if (webViewCore->mainFrame()->view() == scrollView) - webViewCore->scrollTo(x, y); - else { - FrameView* frameView = scrollView->frameView(); - if (frameView) { - RenderView* renderer = frameView->frame()->contentRenderer(); - if (renderer) { - RenderLayer* layer = renderer->layer(); - layer->scrollToOffset(x, y); - } + if (webViewCore->mainFrame()->view() == scrollView) { + const IntRect& visibleContentRect = frameView->visibleContentRect(); + x = std::max(0, std::min(frameView->contentsWidth(), x)); + y = std::max(0, std::min(frameView->contentsHeight(), y)); + if ((x != visibleContentRect.x()) || (y != visibleContentRect.y())) + webViewCore->scrollTo(x, y); + } else { + RenderView* renderer = frameView->frame()->contentRenderer(); + if (renderer) { + RenderLayer* layer = renderer->layer(); + layer->scrollToOffset(x, y); } } } diff --git a/Source/WebKit/android/jni/PictureSet.cpp b/Source/WebKit/android/jni/PictureSet.cpp index 89b16dc..8e95aa3 100644 --- a/Source/WebKit/android/jni/PictureSet.cpp +++ b/Source/WebKit/android/jni/PictureSet.cpp @@ -132,7 +132,7 @@ PictureSet::PictureSet(SkPicture* picture) : pictureAndBounds.mPicture = picture; SkSafeRef(pictureAndBounds.mPicture); pictureAndBounds.mEmpty = false; - pictureAndBounds.mArea.setRect(0, 0, mWidth, mHeight); + pictureAndBounds.mArea.set(0, 0, mWidth, mHeight); pictureAndBounds.mSplit = false; pictureAndBounds.mBase = true; pictureAndBounds.mElapsed = 0; @@ -157,14 +157,13 @@ void PictureSet::add(const Pictures* temp) } #endif // FAST_PICTURESET -void PictureSet::add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split) +void PictureSet::add(const SkRegion& area, uint32_t elapsed, bool split) { if (area.isRect()) { #ifdef FAST_PICTURESET splitAdd(area.getBounds()); #else - add(area, picture, elapsed, split, false); + add(area.getBounds(), elapsed, split, false); #endif // FAST_PICTURESET } else { SkRegion::Iterator cliperator(area); @@ -173,9 +172,7 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, #ifdef FAST_PICTURESET splitAdd(ir); #else - SkRegion newArea; - newArea.setRect(ir); - add(newArea, picture, elapsed, split, false); + add(ir, elapsed, split, false); #endif // FAST_PICTURESET cliperator.next(); } @@ -448,8 +445,7 @@ void PictureSet::splitAdd(const SkIRect& rect) // things (deleting additional pictures + full repaint of base pictures) #ifdef FAST_PICTURESET #else -void PictureSet::add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split, bool empty) +void PictureSet::add(const SkIRect& area, uint32_t elapsed, bool split, bool empty) { bool checkForNewBases = false; @@ -458,12 +454,11 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, #ifdef DEBUG XLOG("--- before adding the new inval ---"); for (Pictures* working = mPictures.begin(); working != mPictures.end(); working++) { - SkIRect currentArea = working->mArea.getBounds(); - XLOG("picture %d (%d, %d, %d, %d - %d x %d) (isRect? %c) base: %c", + SkIRect currentArea = working->mArea; + XLOG("picture %d (%d, %d, %d, %d - %d x %d) base: %c", working - first, currentArea.fLeft, currentArea.fTop, currentArea.fRight, currentArea.fBottom, currentArea.width(), currentArea.height(), - working->mArea.isRect() ? 'Y' : 'N', working->mBase ? 'Y' : 'N'); } XLOG("----------------------------------"); @@ -471,14 +466,14 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, // let's gather all the Pictures intersecting with the new invalidated // area, collect their area and remove their picture - SkIRect totalArea = area.getBounds(); + SkIRect totalArea = area; for (Pictures* working = first; working != last; working++) { - SkIRect inval = area.getBounds(); + SkIRect inval = area; bool remove = false; - if (!working->mBase && working->mArea.intersects(inval)) + if (!working->mBase && SkIRect::Intersects(working->mArea, inval)) remove = true; if (working->mBase) { - SkIRect baseArea = working->mArea.getBounds(); + SkIRect baseArea = working->mArea; if (area.contains(baseArea)) { remove = true; checkForNewBases = true; @@ -486,21 +481,19 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, } if (remove) { - SkIRect currentArea = working->mArea.getBounds(); + SkIRect currentArea = working->mArea; if (working->mBase) mBaseArea -= currentArea.width() * currentArea.height(); else mAdditionalArea -= currentArea.width() * currentArea.height(); totalArea.join(currentArea); - XLOG("picture %d (%d, %d, %d, %d - %d x %d) (isRect? %c) intersects with the new inval area (%d, %d, %d, %d - %d x %d) (isRect? %c, we remove it", + XLOG("picture %d (%d, %d, %d, %d - %d x %d) intersects with the new inval area (%d, %d, %d, %d - %d x %d)", working - first, currentArea.fLeft, currentArea.fTop, currentArea.fRight, currentArea.fBottom, currentArea.width(), currentArea.height(), - working->mArea.isRect() ? 'Y' : 'N', inval.fLeft, inval.fTop, inval.fRight, inval.fBottom, - inval.width(), inval.height(), - area.isRect() ? 'Y' : 'N'); + inval.width(), inval.height()); working->mArea.setEmpty(); SkSafeUnref(working->mPicture); working->mPicture = 0; @@ -509,9 +502,7 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, // Now we can add the new Picture to the list, with the correct area // that need to be repainted - SkRegion collect; - collect.setRect(totalArea); - Pictures pictureAndBounds = {collect, 0, collect.getBounds(), + Pictures pictureAndBounds = {totalArea, 0, totalArea, elapsed, split, false, false, empty}; #ifdef FAST_PICTURESET @@ -519,6 +510,13 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, checkForNewBases = true; #endif + if (!size()) { + pictureAndBounds.mBase = true; + mBaseArea = totalArea.width() * totalArea.height(); + mAdditionalArea = 0; + mPictures.append(pictureAndBounds); + return; + } mPictures.append(pictureAndBounds); mAdditionalArea += totalArea.width() * totalArea.height(); last = mPictures.end(); @@ -552,12 +550,11 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, #ifdef DEBUG XLOG("--- after adding the new inval, but before collapsing ---"); for (Pictures* working = mPictures.begin(); working != mPictures.end(); working++) { - SkIRect currentArea = working->mArea.getBounds(); - XLOG("picture %d (%d, %d, %d, %d - %d x %d) (isRect? %c) base: %c", + SkIRect currentArea = working->mArea; + XLOG("picture %d (%d, %d, %d, %d - %d x %d) base: %c", working - first, currentArea.fLeft, currentArea.fTop, currentArea.fRight, currentArea.fBottom, currentArea.width(), currentArea.height(), - working->mArea.isRect() ? 'Y' : 'N', working->mBase ? 'Y' : 'N'); } XLOG("----------------------------------"); @@ -577,12 +574,11 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, #ifdef DEBUG XLOG("--- after adding the new inval ---"); for (Pictures* working = mPictures.begin(); working != mPictures.end(); working++) { - SkIRect currentArea = working->mArea.getBounds(); - XLOG("picture %d (%d, %d, %d, %d - %d x %d) (isRect? %c) base: %c picture %x", + SkIRect currentArea = working->mArea; + XLOG("picture %d (%d, %d, %d, %d - %d x %d) base: %c picture %x", working - first, currentArea.fLeft, currentArea.fTop, currentArea.fRight, currentArea.fBottom, currentArea.width(), currentArea.height(), - working->mArea.isRect() ? 'Y' : 'N', working->mBase ? 'Y' : 'N', working->mPicture); } XLOG("----------------------------------"); @@ -595,7 +591,8 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, Pictures* last = mPictures.end(); XLOG("checkForNewBases..."); for (Pictures* working = mPictures.begin(); working != last; working++) { - SkRegion& area = working->mArea; + SkRegion area; + area.setRect(working->mArea); const SkIRect& a = area.getBounds(); if (drawn.contains(working->mArea) == false) { working->mBase = true; @@ -606,6 +603,19 @@ void PictureSet::add(const SkRegion& area, SkPicture* picture, drawn.op(working->mArea, SkRegion::kUnion_Op); } } + +#ifdef DEBUG + XLOG("--- after checking for bases ---"); + for (Pictures* working = mPictures.begin(); working != mPictures.end(); working++) { + SkIRect currentArea = working->mArea; + XLOG("picture %d (%d, %d, %d, %d - %d x %d) base: %c picture %x", + working - first, + currentArea.fLeft, currentArea.fTop, currentArea.fRight, currentArea.fBottom, + currentArea.width(), currentArea.height(), + working->mBase ? 'Y' : 'N', working->mPicture); + } + XLOG("----------------------------------"); +#endif } #endif // FAST_PICTURESET @@ -760,11 +770,13 @@ bool PictureSet::draw(SkCanvas* canvas) return false; SkIRect irect; bounds.roundOut(&irect); + if (!irect.intersect(0, 0, width(), height())) + return false; for (working = last; working != first; ) { --working; if (working->mArea.contains(irect)) { #if PICTURE_SET_DEBUG - const SkIRect& b = working->mArea.getBounds(); + const SkIRect& b = working->mArea; DBG_SET_LOGD("contains working->mArea={%d,%d,%d,%d}" " irect={%d,%d,%d,%d}", b.fLeft, b.fTop, b.fRight, b.fBottom, irect.fLeft, irect.fTop, irect.fRight, irect.fBottom); @@ -777,7 +789,8 @@ bool PictureSet::draw(SkCanvas* canvas) last - mPictures.begin()); uint32_t maxElapsed = 0; for (working = first; working != last; working++) { - const SkRegion& area = working->mArea; + SkRegion area; + area.setRect(working->mArea); if (area.quickReject(irect)) { #if PICTURE_SET_DEBUG const SkIRect& b = area.getBounds(); @@ -1031,40 +1044,6 @@ void PictureSet::set(const PictureSet& src) #ifdef FAST_PICTURESET #else -bool PictureSet::reuseSubdivided(const SkRegion& inval) -{ - validate(__FUNCTION__); - - if (inval.isComplex()) - return false; - Pictures* working, * last = mPictures.end(); - const SkIRect& invalBounds = inval.getBounds(); - bool steal = false; - for (working = mPictures.begin(); working != last; working++) { - if (working->mSplit && invalBounds == working->mUnsplit) { - steal = true; - continue; - } - if (steal == false) - continue; - SkRegion temp = SkRegion(inval); - temp.op(working->mArea, SkRegion::kIntersect_Op); - if (temp.isEmpty() || temp == working->mArea) - continue; - return false; - } - if (steal == false) - return false; - for (working = mPictures.begin(); working != last; working++) { - if ((working->mSplit == false || invalBounds != working->mUnsplit) && - inval.contains(working->mArea) == false) - continue; - SkSafeUnref(working->mPicture); - working->mPicture = NULL; - } - return true; -} - void PictureSet::setDrawTimes(const PictureSet& src) { validate(__FUNCTION__); @@ -1086,8 +1065,8 @@ void PictureSet::setDrawTimes(const PictureSet& src) } DBG_SET_LOGD("%p [%d] [%d] {%d,%d,r=%d,b=%d} working->mElapsed=%d <- %d", this, working - mPictures.begin(), srcWorking - src.mPictures.begin(), - working->mArea.getBounds().fLeft, working->mArea.getBounds().fTop, - working->mArea.getBounds().fRight, working->mArea.getBounds().fBottom, + working->mArea.fLeft, working->mArea.fTop, + working->mArea.fRight, working->mArea.fBottom, working->mElapsed, srcWorking->mElapsed); working->mElapsed = srcWorking->mElapsed; } @@ -1130,14 +1109,14 @@ void PictureSet::split(PictureSet* out) const split ? "true" : "false"); if (multiUnsplitFastPictures <= 1 || split) { total->op(working->mArea, SkRegion::kDifference_Op); - out->add(working->mArea, working->mPicture, elapsed, split, + out->add(working->mArea, elapsed, split, working->mEmpty); } else if (balance < elapsed) balance = elapsed; continue; } total->op(working->mArea, SkRegion::kDifference_Op); - const SkIRect& bounds = working->mArea.getBounds(); + const SkIRect& bounds = working->mArea; int width = bounds.width(); int height = bounds.height(); int across = 1; @@ -1163,8 +1142,7 @@ void PictureSet::split(PictureSet* out) const int right = bounds.fLeft + width * ++indexX / across; SkIRect cBounds; cBounds.set(left, top, right, bottom); - out->add(SkRegion(cBounds), (across | down) != 1 ? NULL : - working->mPicture, elapsed, true, + out->add(cBounds, elapsed, true, (across | down) != 1 ? false : working->mEmpty); left = right; } @@ -1175,7 +1153,7 @@ void PictureSet::split(PictureSet* out) const this, mWidth, mHeight, total->isEmpty() ? "true" : "false", multiUnsplitFastPictures); if (!total->isEmpty() && multiUnsplitFastPictures > 1) - out->add(*total, NULL, balance, false, false); + out->add(*total, balance, false); delete total; validate(__FUNCTION__); out->dump("split-out"); diff --git a/Source/WebKit/android/jni/PictureSet.h b/Source/WebKit/android/jni/PictureSet.h index 97d91e0..1d9a14d 100644 --- a/Source/WebKit/android/jni/PictureSet.h +++ b/Source/WebKit/android/jni/PictureSet.h @@ -83,8 +83,7 @@ namespace android { void splitAdd(const SkIRect& rect); #endif - void add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split); + void add(const SkRegion& area, uint32_t elapsed, bool split); // Update mWidth/mHeight, and adds any additional inval region void setDimensions(int width, int height, SkRegion* inval = 0); @@ -97,11 +96,9 @@ namespace android { #ifdef FAST_PICTURESET #else - void add(const SkRegion& area, SkPicture* picture, - uint32_t elapsed, bool split, bool empty); + void add(const SkIRect& area, uint32_t elapsed, bool split, bool empty); const SkIRect& bounds(size_t i) const { - return mPictures[i].mArea.getBounds(); } - bool reuseSubdivided(const SkRegion& ); + return mPictures[i].mArea; } void setPicture(size_t i, SkPicture* p); void setDrawTimes(const PictureSet& ); size_t size() const { return mPictures.size(); } @@ -123,7 +120,7 @@ namespace android { int mBucketCountY; #else struct Pictures { - SkRegion mArea; + SkIRect mArea; SkPicture* mPicture; SkIRect mUnsplit; uint32_t mElapsed; diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 32befc7..1351d8f 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -489,7 +489,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m #endif m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V"); m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V"); - m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZLjava/lang/String;III)V"); + m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZLjava/lang/String;IIII)V"); m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V"); env->DeleteLocalRef(clazz); @@ -577,26 +577,6 @@ WebCore::Node* WebViewCore::currentFocus() return focusedFrame()->document()->focusedNode(); } -void WebViewCore::recordPicture(SkPicture* picture) -{ - // if there is no document yet, just return - if (!m_mainFrame->document()) - return; - // Call layout to ensure that the contentWidth and contentHeight are correct - if (!layoutIfNeededRecursive(m_mainFrame)) - return; - // draw into the picture's recording canvas - WebCore::FrameView* view = m_mainFrame->view(); - SkAutoPictureRecord arp(picture, view->contentsWidth(), - view->contentsHeight(), PICT_RECORD_FLAGS); - SkAutoMemoryUsageProbe mup(__FUNCTION__); - - WebCore::PlatformGraphicsContext pgc(arp.getRecordingCanvas()); - WebCore::GraphicsContext gc(&pgc); - view->platformWidget()->draw(&gc, WebCore::IntRect(0, 0, - view->contentsWidth(), view->contentsHeight())); -} - void WebViewCore::recordPictureSet(PictureSet* content) { // if there is no document yet, just return @@ -709,7 +689,7 @@ void WebViewCore::recordPictureSet(PictureSet* content) content->setDimensions(width, height, &m_addInval); // Add the current inval rects to the PictureSet, and rebuild it. - content->add(m_addInval, 0, 0, false); + content->add(m_addInval, 0, false); // If we have too many invalidations, just get the area bounds SkRegion::Iterator iterator(m_addInval); @@ -724,7 +704,6 @@ void WebViewCore::recordPictureSet(PictureSet* content) SkIRect r = m_addInval.getBounds(); m_addInval.setRect(r); } - // Rebuild the pictureset (webkit repaint) rebuildPictureSet(content); } @@ -3288,6 +3267,16 @@ WebViewCore::InputType WebViewCore::getInputType(Node* node) return WebViewCore::NONE; } +int WebViewCore::getMaxLength(Node* node) +{ + int maxLength = -1; + if (node->hasTagName(WebCore::HTMLNames::inputTag)) { + HTMLInputElement* htmlInput = static_cast<HTMLInputElement*>(node); + maxLength = htmlInput->maxLength(); + } + return maxLength; +} + bool WebViewCore::isSpellCheckEnabled(Node* node) { bool isEnabled = true; @@ -3317,6 +3306,7 @@ void WebViewCore::initEditField(Node* node) Node* nextFocus = document->nextFocusableNode(node, tabEvent.get()); bool isNextText = isTextInput(nextFocus); bool spellCheckEnabled = isSpellCheckEnabled(node); + int maxLength = getMaxLength(node); String label = requestLabel(document->frame(), node); jstring fieldText = wtfStringToJstring(env, text, true); jstring labelText = wtfStringToJstring(env, text, false); @@ -3324,7 +3314,7 @@ void WebViewCore::initEditField(Node* node) env->CallVoidMethod(javaObject.get(), m_javaGlue->m_initEditField, reinterpret_cast<int>(node), fieldText, inputType, spellCheckEnabled, isNextText, labelText, start, end, - reinterpret_cast<int>(selectText)); + reinterpret_cast<int>(selectText), maxLength); checkException(env); } diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index c5bb63f..cc7ff12 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -301,8 +301,6 @@ namespace android { // If the focus is a textfield (<input>), textarea, or contentEditable, // scroll the selection on screen (if necessary). void revealSelection(); - // Create a single picture to represent the drawn DOM (used by navcache) - void recordPicture(SkPicture* picture); void moveFocus(WebCore::Frame* frame, WebCore::Node* node); void moveMouse(WebCore::Frame* frame, int x, int y, HitTestResult* hoveredNode = 0); @@ -717,6 +715,7 @@ namespace android { VisiblePosition visiblePositionForContentPoint(const IntPoint& point); void selectWordAroundPosition(Frame* frame, VisiblePosition pos); SelectText* createSelectText(const VisibleSelection&); + static int getMaxLength(Node* node); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index b0535e7..7aae9b2 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); } |