diff options
Diffstat (limited to 'Source')
40 files changed, 511 insertions, 430 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 4884e5b..816b163 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -672,6 +672,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/PaintTileOperation.cpp \ platform/graphics/android/PathAndroid.cpp \ platform/graphics/android/PatternAndroid.cpp \ + platform/graphics/android/PictureLayerContent.cpp \ + platform/graphics/android/PictureSetLayerContent.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ platform/graphics/android/PerformanceMonitor.cpp \ platform/graphics/android/RasterRenderer.cpp \ diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 3cf863e..c9a8b9a 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -68,6 +68,7 @@ using namespace android; BaseLayerAndroid::BaseLayerAndroid() #if USE(ACCELERATED_COMPOSITING) : m_color(Color::white) + , m_content(0) , m_scrollState(NotScrolling) #endif { @@ -78,23 +79,17 @@ BaseLayerAndroid::BaseLayerAndroid() BaseLayerAndroid::~BaseLayerAndroid() { - m_content.clear(); + SkSafeUnref(m_content); #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("BaseLayerAndroid"); #endif } -void BaseLayerAndroid::setContent(const PictureSet& src) +void BaseLayerAndroid::setContent(LayerContent* content) { -#if USE(ACCELERATED_COMPOSITING) - // FIXME: We lock here because we do not want - // to paint and change the m_content concurrently. - // We should instead refactor PictureSet to use - // an atomic refcounting scheme and use atomic operations - // to swap PictureSets. - android::Mutex::Autolock lock(m_drawLock); -#endif - m_content.set(src); + SkSafeRef(content); + SkSafeUnref(m_content); + m_content = content; // FIXME: We cannot set the size of the base layer because it will screw up // the matrix used. We need to fix matrix computation for the base layer // and then we can set the size. @@ -103,11 +98,9 @@ void BaseLayerAndroid::setContent(const PictureSet& src) bool BaseLayerAndroid::drawCanvas(SkCanvas* canvas) { -#if USE(ACCELERATED_COMPOSITING) android::Mutex::Autolock lock(m_drawLock); -#endif - if (!m_content.isEmpty()) - m_content.draw(canvas); + if (m_content && !m_content->isEmpty()) + m_content->draw(canvas); return true; } @@ -146,7 +139,7 @@ void BaseLayerAndroid::prefetchBasePicture(const SkRect& viewport, float current prefetchTiledPage); prefetchTiledPage->setScale(prefetchScale); - prefetchTiledPage->updateTileDirtiness(bounds); + prefetchTiledPage->updateTileDirtiness(); prefetchTiledPage->prepare(goingDown, goingLeft, bounds, TiledPage::ExpandedBounds); prefetchTiledPage->swapBuffersIfReady(bounds, @@ -218,8 +211,7 @@ void BaseLayerAndroid::prepareGL(const SkRect& viewport, float scale, double cur nextTiledPage->setScale(scale); m_state->setFutureViewport(viewportTileBounds); - // ignore dirtiness return value since while zooming we repaint regardless - nextTiledPage->updateTileDirtiness(viewportTileBounds); + nextTiledPage->updateTileDirtiness(); nextTiledPage->prepare(goingDown, goingLeft, viewportTileBounds, TiledPage::VisibleBounds); @@ -256,7 +248,7 @@ void BaseLayerAndroid::prepareGL(const SkRect& viewport, float scale, double cur m_state->swapPages(); } - tiledPage->updateTileDirtiness(preZoomBounds); + tiledPage->updateTileDirtiness(); // paint what's needed unless we're zooming, since the new tiles won't // be relevant soon anyway diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h index e7d0471..a807b8b 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -29,6 +29,7 @@ #include "Color.h" #include "Layer.h" #include "PictureSet.h" +#include "LayerContent.h" namespace WebCore { @@ -50,8 +51,9 @@ public: void setBackgroundColor(Color& color) { m_color = color; } Color getBackgroundColor() { return m_color; } #endif - void setContent(const android::PictureSet& src); - android::PictureSet* content() { return &m_content; } + void setContent(LayerContent* content); + LayerContent* content() { return m_content; } + // This method will paint using the current PictureSet onto // the passed canvas. We used it to paint the GL tiles as well as // WebView::copyBaseContentToPicture(), so a lock is necessary as @@ -78,7 +80,7 @@ private: android::Mutex m_drawLock; Color m_color; #endif - android::PictureSet m_content; + LayerContent* m_content; ScrollState m_scrollState; }; diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp index b708ad1..832ed0c 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp @@ -41,11 +41,14 @@ #include <wtf/text/CString.h> -#ifdef DEBUG - #include <cutils/log.h> #include <wtf/CurrentTime.h> +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "BaseRenderer", __VA_ARGS__) + +#ifdef DEBUG + #undef XLOG #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseRenderer", __VA_ARGS__) @@ -56,6 +59,9 @@ #endif // DEBUG +#define UPDATE_COUNT_MASK 0xFF // displayed count wraps at 256 +#define UPDATE_COUNT_ALPHA_MASK 0x3F // alpha wraps at 64 + namespace WebCore { BaseRenderer::RendererType BaseRenderer::g_currentType = BaseRenderer::Raster; @@ -79,12 +85,12 @@ void BaseRenderer::swapRendererIfNeeded(BaseRenderer*& renderer) } void BaseRenderer::drawTileInfo(SkCanvas* canvas, - const TileRenderInfo& renderInfo, int pictureCount) + const TileRenderInfo& renderInfo, int updateCount) { SkPaint paint; char str[256]; snprintf(str, 256, "(%d,%d) %.2f, tl%x p%x c%d", renderInfo.x, renderInfo.y, - renderInfo.scale, this, renderInfo.tilePainter, pictureCount); + renderInfo.scale, this, renderInfo.tilePainter, updateCount); paint.setARGB(255, 0, 0, 0); canvas->drawText(str, strlen(str), 0, 10, paint); paint.setARGB(255, 255, 0, 0); @@ -112,7 +118,7 @@ void BaseRenderer::drawTileInfo(SkCanvas* canvas, canvas->drawText(str, strlen(str), 0, textY + 1, paint); } -int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) +void BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) { const bool visualIndicator = TilesManager::instance()->getShowVisualIndicator(); const SkSize& tileSize = renderInfo.tileSize; @@ -122,7 +128,7 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) if (!canvas.getDevice()) { XLOG("Error: No Device"); - return 0; + return; } if (visualIndicator) @@ -131,12 +137,12 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) setupPartialInval(renderInfo, &canvas); canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height()); canvas.scale(renderInfo.scale, renderInfo.scale); - unsigned int pictureCount = 0; - renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas, &pictureCount); + renderInfo.tilePainter->paint(renderInfo.baseTile, &canvas); if (visualIndicator) { canvas.restore(); - const int color = 20 + (pictureCount % 100); + unsigned int updateCount = renderInfo.tilePainter->getUpdateCount() & UPDATE_COUNT_MASK; + const int color = updateCount & UPDATE_COUNT_ALPHA_MASK; // only color the invalidated area SkPaint invalPaint; @@ -173,11 +179,9 @@ int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo) } if (renderInfo.measurePerf) - drawTileInfo(&canvas, renderInfo, pictureCount); + drawTileInfo(&canvas, renderInfo, updateCount); } - renderInfo.textureInfo->m_pictureCount = pictureCount; renderingComplete(renderInfo, &canvas); - return pictureCount; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.h b/Source/WebCore/platform/graphics/android/BaseRenderer.h index 7780db1..2defcc3 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.h +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.h @@ -76,7 +76,7 @@ public: BaseRenderer(RendererType type) : m_type(type) {} virtual ~BaseRenderer() {} - int renderTiledContent(const TileRenderInfo& renderInfo); + void renderTiledContent(const TileRenderInfo& renderInfo); RendererType getType() { return m_type; } @@ -92,7 +92,7 @@ protected: virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0; void drawTileInfo(SkCanvas* canvas, const TileRenderInfo& renderInfo, - int pictureCount); + int updateCount); virtual const String* getPerformanceTags(int& tagCount) = 0; diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 7466d64..de64425 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -74,7 +74,6 @@ BaseTile::BaseTile(bool isLayerTile) , m_scale(1) , m_dirty(true) , m_repaintPending(false) - , m_lastDirtyPicture(0) , m_fullRepaint(true) , m_isTexturePainted(false) , m_isLayerTile(isLayerTile) @@ -167,13 +166,11 @@ bool BaseTile::removeTexture(BaseTileTexture* texture) return true; } -void BaseTile::markAsDirty(int unsigned pictureCount, - const SkRegion& dirtyArea) +void BaseTile::markAsDirty(const SkRegion& dirtyArea) { if (dirtyArea.isEmpty()) return; android::AutoMutex lock(m_atomicSync); - m_lastDirtyPicture = pictureCount; m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op); // Check if we actually intersect with the area @@ -255,11 +252,7 @@ void BaseTile::drawGL(float opacity, const SkRect& rect, float scale, if (!isTexturePainted) return; - if (m_frontTexture->readyFor(this)) - m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform); - else { - XLOG("tile %p at %d, %d not readyfor (at draw),", this, m_x, m_y); - } + m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform); } bool BaseTile::isTileReady() @@ -280,14 +273,7 @@ bool BaseTile::isTileReady() if (m_state != ReadyToSwap && m_state != UpToDate) return false; - bool ready = texture->readyFor(this); - - if (ready) - return true; - - XLOG("tile %p at %d, %d not readyfor (at isTileReady)", this, m_x, m_y); - - return false; + return true; } bool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight, @@ -351,8 +337,6 @@ void BaseTile::paintBitmap() return; } - unsigned int pictureCount = 0; - // swap out the renderer if necessary BaseRenderer::swapRendererIfNeeded(m_renderer); // setup the common renderInfo fields; @@ -429,7 +413,7 @@ void BaseTile::paintBitmap() if (!fullRepaint) { renderInfo.invalRect = &totalRect; renderInfo.measurePerf = false; - pictureCount = m_renderer->renderTiledContent(renderInfo); + m_renderer->renderTiledContent(renderInfo); } } @@ -437,7 +421,7 @@ void BaseTile::paintBitmap() if (fullRepaint) { renderInfo.invalRect = 0; renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator(); - pictureCount = m_renderer->renderTiledContent(renderInfo); + m_renderer->renderTiledContent(renderInfo); } m_atomicSync.lock(); diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h index 6ba66ef..f02386b 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.h +++ b/Source/WebCore/platform/graphics/android/BaseTile.h @@ -112,8 +112,7 @@ public: SkRect& realTileRect); bool isTileVisible(const IntRect& viewTileBounds); - void markAsDirty(const unsigned int pictureCount, - const SkRegion& dirtyArea); + void markAsDirty(const SkRegion& dirtyArea); bool isDirty(); bool isRepaintPending(); void setRepaintPending(bool pending); @@ -167,10 +166,6 @@ private: // used to signal that a repaint is pending bool m_repaintPending; - // stores the id of the latest picture from webkit that caused this tile to - // become dirty. A tile is no longer dirty when it has been painted with a - // picture that is newer than this value. - unsigned int m_lastDirtyPicture; // store the dirty region SkRegion m_dirtyArea; diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp index 955d6dd..9403584 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp @@ -120,54 +120,13 @@ bool BaseTileTexture::release(TextureOwner* owner) return true; } -float BaseTileTexture::scale() +void BaseTileTexture::transferComplete() { - TextureTileInfo* textureInfo = &m_ownTextureTileInfo; - return textureInfo->m_scale; -} - -// This function + TilesManager::addItemInTransferQueue() is replacing the -// setTile(). -void BaseTileTexture::setOwnTextureTileInfoFromQueue(const TextureTileInfo* info) -{ - m_ownTextureTileInfo.m_x = info->m_x; - m_ownTextureTileInfo.m_y = info->m_y; - m_ownTextureTileInfo.m_scale = info->m_scale; - m_ownTextureTileInfo.m_painter = info->m_painter; - m_ownTextureTileInfo.m_picture = info->m_picture; - m_ownTextureTileInfo.m_inverted = TilesManager::instance()->invertedScreen(); if (m_owner) { BaseTile* owner = static_cast<BaseTile*>(m_owner); owner->backTextureTransfer(); - } - -} - -bool BaseTileTexture::readyFor(BaseTile* baseTile) -{ - const TextureTileInfo* info = &m_ownTextureTileInfo; - - if (isPureColor() && info->m_painter == baseTile->painter()) { - XLOG("ReadyFor saw a pureColor tile (%p) at (%d, %d), rgb %x", - this, baseTile->x(), baseTile->y(), pureColor().rgb()); - 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_inverted == TilesManager::instance()->invertedScreen())) - return true; - - XLOG("texture %p readyFor return false for tile x, y (%d %d) texId %d ," - " BaseTileTexture %p, BaseTile is %p, SCALE %f, painter %p, inv %d", - this, baseTile->x(), baseTile->y(), m_ownTextureId, this, baseTile, - baseTile->scale(), baseTile->painter(), TilesManager::instance()->invertedScreen()); - return false; + } else + XLOGC("ERROR: owner missing after transfer of texture %p", this); } void BaseTileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h index 3e4f872..321ca31 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h @@ -39,30 +39,6 @@ namespace WebCore { class BaseTile; -class TextureTileInfo { -public: - TextureTileInfo() - : m_x(-1) - , m_y(-1) - , m_layerId(-1) - , m_scale(0) - , m_texture(0) - , m_painter(0) - , m_picture(0) - , m_inverted(false) - { - } - int m_x; - int m_y; - int m_layerId; - float m_scale; - TextureInfo* m_texture; - TilePainter* m_painter; - unsigned int m_picture; - bool m_inverted; - IntRect m_inval; -}; - class BaseTileTexture { public: // This object is to be constructed on the consumer's thread and must have @@ -92,7 +68,7 @@ public: void requireGLTexture(); void discardGLTexture(); - void setOwnTextureTileInfoFromQueue(const TextureTileInfo* info); + void transferComplete(); TextureInfo* getTextureInfo() { return &m_ownTextureInfo; } @@ -106,8 +82,6 @@ public: void drawGL(bool isLayer, const SkRect& rect, float opacity, const TransformationMatrix* transform); private: - TextureTileInfo m_ownTextureTileInfo; - // TODO: Merge this info into the TextureTileInfo. TextureInfo m_ownTextureInfo; SkSize m_size; SkBitmap::Config m_config; diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index cfd8937..97bd7a8 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -81,7 +81,6 @@ using namespace android; GLWebViewState::GLWebViewState() : m_zoomManager(this) - , m_currentPictureCounter(0) , m_usePageA(true) , m_frameworkInval(0, 0, 0, 0) , m_frameworkLayersInval(0, 0, 0, 0) @@ -186,11 +185,10 @@ void GLWebViewState::invalRegion(const SkRegion& region) void GLWebViewState::inval(const IntRect& rect) { - m_currentPictureCounter++; if (!rect.isEmpty()) { // find which tiles fall within the invalRect and mark them as dirty - m_tiledPageA->invalidateRect(rect, m_currentPictureCounter); - m_tiledPageB->invalidateRect(rect, m_currentPictureCounter); + m_tiledPageA->invalidateRect(rect); + m_tiledPageB->invalidateRect(rect); if (m_frameworkInval.isEmpty()) m_frameworkInval = rect; else @@ -202,10 +200,9 @@ void GLWebViewState::inval(const IntRect& rect) TilesManager::instance()->getProfiler()->nextInval(rect, zoomManager()->currentScale()); } -unsigned int GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) +void GLWebViewState::paintBaseLayerContent(SkCanvas* canvas) { m_surfaceCollectionManager.drawCanvas(canvas, m_layersRenderingMode == kSingleSurfaceRendering); - return m_currentPictureCounter; } TiledPage* GLWebViewState::sibling(TiledPage* page) diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index da579da..fcdd07c 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -175,7 +175,7 @@ public: const SkIRect& futureViewport() const { return m_futureViewportTileBounds; } void setFutureViewport(const SkIRect& viewport) { m_futureViewportTileBounds = viewport; } - unsigned int paintBaseLayerContent(SkCanvas* canvas); + void paintBaseLayerContent(SkCanvas* canvas); bool setBaseLayer(BaseLayerAndroid* layer, bool showVisualIndicator, bool isPictureAfterFirstLayout); void paintExtras(); @@ -197,8 +197,6 @@ public: const SkIRect& preZoomBounds() const { return m_preZoomBounds; } void setPreZoomBounds(const SkIRect& bounds) { m_preZoomBounds = bounds; } - unsigned int currentPictureCounter() const { return m_currentPictureCounter; } - void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; } bool isScrolling() { return m_isScrolling || m_isViewportScrolling; } @@ -264,7 +262,6 @@ private: SkIRect m_futureViewportTileBounds; SkIRect m_preZoomBounds; - unsigned int m_currentPictureCounter; bool m_usePageA; TiledPage* m_tiledPageA; TiledPage* m_tiledPageB; diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index 1ac90e9..6bc2dc7 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -31,6 +31,7 @@ #include "Layer.h" #include "Length.h" #include "MediaLayer.h" +#include "PictureLayerContent.h" #include "PlatformBridge.h" #include "PlatformGraphicsContext.h" #include "RenderLayerBacking.h" @@ -603,9 +604,8 @@ bool GraphicsLayerAndroid::repaint() PaintingPhase phase(this); // Paint the background into a separate context. phase.set(GraphicsLayerPaintBackground); - if (!paintContext(m_contentLayer->recordContext(), layerBounds)) + if (!paintContext(m_contentLayer, layerBounds)) return false; - m_contentLayer->checkForPictureOptimizations(); // Construct the foreground layer and draw. RenderBox* box = layer->renderBox(); @@ -625,8 +625,7 @@ bool GraphicsLayerAndroid::repaint() IntSize scroll = layer->scrolledContentOffset(); layer->scrollToOffset(0, 0); // At this point, it doesn't matter if painting failed. - (void) paintContext(m_foregroundLayer->recordContext(), contentsRect); - m_foregroundLayer->checkForPictureOptimizations(); + (void) paintContext(m_foregroundLayer, contentsRect); layer->scrollToOffset(scroll.width(), scroll.height()); // Construct the clip layer for masking the contents. @@ -658,15 +657,12 @@ bool GraphicsLayerAndroid::repaint() SkRegion region; region.setRect(0, 0, contentsRect.width(), contentsRect.height()); m_foregroundLayer->markAsDirty(region); - m_foregroundLayer->needsRepaint(); } else { // If there is no contents clip, we can draw everything into one // picture. - bool painting = paintContext(m_contentLayer->recordContext(), layerBounds); + bool painting = paintContext(m_contentLayer, layerBounds); if (!painting) return false; - // We painted new content - m_contentLayer->checkForPictureOptimizations(); // Check for a scrollable iframe and report the scrolling // limits based on the view size. if (m_contentLayer->isIFrameContent()) { @@ -688,7 +684,6 @@ bool GraphicsLayerAndroid::repaint() m_contentLayer->markAsDirty(m_dirtyRegion); m_dirtyRegion.setEmpty(); - m_contentLayer->needsRepaint(); m_needsRepaint = false; return true; @@ -698,7 +693,6 @@ bool GraphicsLayerAndroid::repaint() // texture. Only do so if we effectively have a new image! m_contentLayer->markAsDirty(m_dirtyRegion); m_dirtyRegion.setEmpty(); - m_contentLayer->needsRepaint(); m_newImage = false; m_needsRepaint = false; return true; @@ -706,19 +700,32 @@ bool GraphicsLayerAndroid::repaint() return false; } -bool GraphicsLayerAndroid::paintContext(SkPicture* context, +bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer, const IntRect& rect) { - SkAutoPictureRecord arp(context, rect.width(), rect.height()); - SkCanvas* canvas = arp.getRecordingCanvas(); + if (!layer) + return false; - if (!canvas) + SkPicture* picture = new SkPicture(); + SkCanvas* canvas = picture->beginRecording(rect.width(), rect.height(), 0); + if (!canvas) { + picture->endRecording(); + SkSafeUnref(picture); return false; + } PlatformGraphicsContext platformContext(canvas); GraphicsContext graphicsContext(&platformContext); paintGraphicsLayerContents(graphicsContext, rect); + + picture->endRecording(); + + PictureLayerContent* layerContent = new PictureLayerContent(picture); + layerContent->checkForOptimisations(); + layer->setContent(layerContent); + SkSafeUnref(layerContent); + SkSafeUnref(picture); return true; } diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 4c049cd..1eb77d6 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -24,6 +24,7 @@ #include "GraphicsLayer.h" #include "GraphicsLayerClient.h" #include "LayerAndroid.h" +#include "LayerContent.h" #include "RefPtr.h" #include "ScrollableLayerAndroid.h" #include "SkBitmapRef.h" @@ -143,7 +144,7 @@ private: bool repaint(); void needsNotifyClient(); - bool paintContext(SkPicture* context, const IntRect& rect); + bool paintContext(LayerAndroid* layer, const IntRect& rect); bool m_needsSyncChildren; bool m_needsSyncMask; diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp index 25dd6f3..815a70a 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp +++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp @@ -230,7 +230,7 @@ float ImageTexture::opacity() return m_layer->drawOpacity(); } -bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) +bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas) { if (!m_picture) { XLOG("IT %p COULDNT PAINT, NO PICTURE", this); diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h index f2f99dd..91c8a29 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.h +++ b/Source/WebCore/platform/graphics/android/ImageTexture.h @@ -85,7 +85,7 @@ public: bool equalsCRC(unsigned crc); // methods used by TiledTexture - virtual bool paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed); + virtual bool paint(BaseTile* tile, SkCanvas* canvas); virtual float opacity(); int nbTextures(); diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index f101208..7886d7b 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -11,9 +11,11 @@ #include "GLUtils.h" #include "ImagesManager.h" #include "InspectorCanvas.h" +#include "LayerContent.h" #include "LayerGroup.h" #include "MediaLayer.h" #include "ParseCanvas.h" +#include "PictureLayerContent.h" #include "SkBitmapRef.h" #include "SkDrawFilter.h" #include "SkPaint.h" @@ -72,16 +74,14 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_preserves3D(false), m_anchorPointZ(0), m_fixedPosition(0), - m_recordingPicture(0), m_zValue(0), m_uniqueId(++gUniqueId), + m_content(0), m_imageCRC(0), - m_pictureUsed(0), m_scale(1), m_lastComputeTextureSize(0), m_owningLayer(owner), m_type(LayerAndroid::WebCoreLayer), - m_hasText(true), m_intrinsicallyComposited(true), m_layerGroup(0) { @@ -102,7 +102,6 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_uniqueId(layer.m_uniqueId), m_owningLayer(layer.m_owningLayer), m_type(LayerAndroid::UILayer), - m_hasText(layer.m_hasText), m_intrinsicallyComposited(layer.m_intrinsicallyComposited), m_layerGroup(0) { @@ -116,8 +115,9 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_backgroundColor = layer.m_backgroundColor; m_offset = layer.m_offset; - m_recordingPicture = layer.m_recordingPicture; - SkSafeRef(m_recordingPicture); + + m_content = layer.m_content; + SkSafeRef(m_content); m_preserves3D = layer.m_preserves3D; m_anchorPointZ = layer.m_anchorPointZ; @@ -129,7 +129,6 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_drawTransform = layer.m_drawTransform; m_childrenTransform = layer.m_childrenTransform; - m_pictureUsed = layer.m_pictureUsed; m_dirtyRegion = layer.m_dirtyRegion; m_scale = layer.m_scale; m_lastComputeTextureSize = 0; @@ -148,33 +147,9 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), #endif } -void LayerAndroid::checkForPictureOptimizations() -{ - if (m_recordingPicture) { - // Let's check if we have text or not. If we don't, we can limit - // ourselves to scale 1! - InspectorBounder inspectorBounder; - InspectorCanvas checker(&inspectorBounder, m_recordingPicture); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, - m_recordingPicture->width(), - m_recordingPicture->height()); - checker.setBitmapDevice(bitmap); - checker.drawPicture(*m_recordingPicture); - m_hasText = checker.hasText(); - if (!checker.hasContent()) { - // no content to draw, discard picture so UI / tile generation - // doesn't bother with it - SkSafeUnref(m_recordingPicture); - m_recordingPicture = 0; - } - } -} - LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_haveClip(false), m_fixedPosition(0), - m_recordingPicture(picture), m_zValue(0), m_uniqueId(++gUniqueId), m_imageCRC(0), @@ -182,12 +157,11 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_lastComputeTextureSize(0), m_owningLayer(0), m_type(LayerAndroid::NavCacheLayer), - m_hasText(true), m_intrinsicallyComposited(true), m_layerGroup(0) { m_backgroundColor = 0; - SkSafeRef(m_recordingPicture); + m_content = new PictureLayerContent(picture); m_dirtyRegion.setEmpty(); #ifdef DEBUG_COUNT ClassTracker::instance()->increment("LayerAndroid - from picture"); @@ -202,7 +176,7 @@ LayerAndroid::~LayerAndroid() if (m_fixedPosition) delete m_fixedPosition; - SkSafeUnref(m_recordingPicture); + SkSafeUnref(m_content); // Don't unref m_layerGroup, owned by BaseLayerAndroid m_animations.clear(); #ifdef DEBUG_COUNT @@ -216,6 +190,11 @@ LayerAndroid::~LayerAndroid() #endif } +bool LayerAndroid::hasText() +{ + return m_content && m_content->hasText(); +} + static int gDebugNbAnims = 0; bool LayerAndroid::evaluateAnimations() @@ -383,7 +362,7 @@ void LayerAndroid::clipInner(SkTDArray<SkRect>* region, localBounds.intersect(local); if (localBounds.isEmpty()) return; - if (m_recordingPicture && boundsIsUnique(*region, localBounds)) + if (m_content && boundsIsUnique(*region, localBounds)) *region->append() = localBounds; for (int i = 0; i < countChildren(); i++) getChild(i)->clipInner(region, m_haveClip ? localBounds : local); @@ -538,10 +517,16 @@ void LayerAndroid::setContentsImage(SkBitmapRef* img) m_imageCRC = image ? image->imageCRC() : 0; } +void LayerAndroid::setContent(LayerContent* content) +{ + SkSafeRef(content); + SkSafeUnref(m_content); + m_content = content; +} + bool LayerAndroid::needsTexture() { - return (m_recordingPicture - && m_recordingPicture->width() && m_recordingPicture->height()); + return m_content && !m_content->isEmpty(); } IntRect LayerAndroid::clippedRect() const @@ -594,7 +579,7 @@ void LayerAndroid::showLayer(int indent) IntRect clip(m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height()); XLOGC("%s %s (%d) [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) " - "clip (%d, %d, %d, %d) %s %s prepareContext(%x), pic w: %d h: %d", + "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d", spaces, subclassName().latin1().data(), subclassType(), uniqueId(), m_owningLayer, needsTexture() ? "needs a texture" : "no texture", m_imageCRC ? "has an image" : "no image", @@ -603,9 +588,9 @@ void LayerAndroid::showLayer(int indent) clip.x(), clip.y(), clip.width(), clip.height(), contentIsScrollable() ? "SCROLLABLE" : "", isFixed() ? "FIXED" : "", - m_recordingPicture, - m_recordingPicture ? m_recordingPicture->width() : -1, - m_recordingPicture ? m_recordingPicture->height() : -1); + m_content, + m_content ? m_content->width() : -1, + m_content ? m_content->height() : -1); int count = this->countChildren(); for (int i = 0; i < count; i++) @@ -660,7 +645,7 @@ bool LayerAndroid::updateWithLayer(LayerAndroid* layer) if (m_imageCRC != layer->m_imageCRC) m_visible = false; - if ((m_recordingPicture != layer->m_recordingPicture) + if ((m_content != layer->m_content) || (m_imageCRC != layer->m_imageCRC)) return true; @@ -705,7 +690,7 @@ bool LayerAndroid::canJoinGroup(LayerGroup* group) // currently, we don't group zoomable with non-zoomable layers (unless the // group or the layer doesn't need a texture) - if (group->needsTexture() && needsTexture() && m_hasText != group->hasText()) + if (group->needsTexture() && needsTexture() && m_content->hasText() != group->hasText()) return false; // TODO: compare other layer properties - fixed? overscroll? transformed? @@ -895,8 +880,8 @@ bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style) void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style) { - if (m_recordingPicture) - canvas->drawPicture(*m_recordingPicture); + if (m_content) + m_content->draw(canvas); if (TilesManager::instance()->getShowVisualIndicator()) { float w = getSize().width(); @@ -933,7 +918,7 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity, return; } - if (!prepareContext()) + if (masksToBounds() || !m_content) return; // we just have this save/restore for opacity... @@ -958,72 +943,12 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity, extra->draw(canvas, this); } -SkPicture* LayerAndroid::recordContext() -{ - if (prepareContext(true)) - return m_recordingPicture; - return 0; -} - -bool LayerAndroid::prepareContext(bool force) -{ - if (masksToBounds()) - return false; - - if (force || !m_recordingPicture || - (m_recordingPicture && - ((m_recordingPicture->width() != (int) getSize().width()) || - (m_recordingPicture->height() != (int) getSize().height())))) { - SkSafeUnref(m_recordingPicture); - m_recordingPicture = new SkPicture(); - } - - return m_recordingPicture; -} - void LayerAndroid::setFixedPosition(FixedPositioning* position) { if (m_fixedPosition && m_fixedPosition != position) delete m_fixedPosition; m_fixedPosition = position; } -SkRect LayerAndroid::subtractLayers(const SkRect& visibleRect) const -{ - SkRect result; - if (m_recordingPicture) { - // FIXME: This seems wrong. localToGlobal() applies the full local transform, - // se surely we should operate globalMatrix on size(), not bounds() with - // the position removed? Perhaps we never noticed the bug because most - // layers don't use a local transform? - // See http://b/5338388 - SkRect globalRect = bounds(); - globalRect.offset(-getPosition()); // localToGlobal adds in position - SkMatrix globalMatrix; - localToGlobal(&globalMatrix); - globalMatrix.mapRect(&globalRect); - SkIRect roundedGlobal; - globalRect.round(&roundedGlobal); - SkIRect iVisibleRect; - visibleRect.round(&iVisibleRect); - SkRegion visRegion(iVisibleRect); - visRegion.op(roundedGlobal, SkRegion::kDifference_Op); - result.set(visRegion.getBounds()); -#if DEBUG_NAV_UI - SkDebugf("%s visibleRect=(%g,%g,r=%g,b=%g) globalRect=(%g,%g,r=%g,b=%g)" - "result=(%g,%g,r=%g,b=%g)", __FUNCTION__, - visibleRect.fLeft, visibleRect.fTop, - visibleRect.fRight, visibleRect.fBottom, - globalRect.fLeft, globalRect.fTop, - globalRect.fRight, globalRect.fBottom, - result.fLeft, result.fTop, result.fRight, result.fBottom); -#endif - } else - result = visibleRect; - for (int i = 0; i < countChildren(); i++) - result = getChild(i)->subtractLayers(result); - return result; -} - void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const { writeHexVal(file, indentLevel + 1, "layer", (int)this); @@ -1040,9 +965,9 @@ void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform); writeRect(file, indentLevel + 1, "clippingRect", SkRect(m_clippingRect)); - if (m_recordingPicture) { - writeIntVal(file, indentLevel + 1, "m_recordingPicture.width", m_recordingPicture->width()); - writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height()); + if (m_content) { + writeIntVal(file, indentLevel + 1, "m_content.width", m_content->width()); + writeIntVal(file, indentLevel + 1, "m_content.height", m_content->height()); } if (m_fixedPosition) diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index 7f5d5e2..459c159 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 LayerContent; class LayerGroup; class ImageTexture; } @@ -170,7 +171,8 @@ public: } bool masksToBounds() const { return m_haveClip; } - SkPicture* recordContext(); + LayerContent* content() { return m_content; } + void setContent(LayerContent* content); void addAnimation(PassRefPtr<AndroidAnimation> anim); void removeAnimationsForProperty(AnimatedPropertyID property); @@ -181,13 +183,6 @@ public: bool hasAnimations() const; void addDirtyArea(); - SkPicture* picture() const { return m_recordingPicture; } - - // Given a rect in global space, subtracts from it the bounds of this layer - // and of all of its children. Returns the bounding rectangle of the result, - // in global space. - SkRect subtractLayers(const SkRect&) const; - virtual void dumpLayer(FILE*, int indentLevel) const; void dumpLayers(FILE*, int indentLevel) const; void dumpToLog() const; @@ -235,9 +230,6 @@ public: virtual LayerAndroid* copy() const { return new LayerAndroid(*this); } - void needsRepaint() { m_pictureUsed++; } - unsigned int pictureUsed() { return m_pictureUsed; } - void clearDirtyRegion(); virtual void contentDraw(SkCanvas* canvas, PaintStyle style); @@ -269,8 +261,7 @@ public: LayerType type() { return m_type; } virtual SubclassType subclassType() { return LayerAndroid::StandardLayer; } - bool hasText() { return m_hasText; } - void checkForPictureOptimizations(); + bool hasText(); void copyAnimationStartTimesRecursive(LayerAndroid* oldTree); @@ -316,14 +307,6 @@ private: FixedPositioning* m_fixedPosition; - // Note that m_recordingPicture and m_imageRef are mutually exclusive; - // m_recordingPicture is used when WebKit is asked to paint the layer's - // content, while m_imageRef contains an image that we directly - // composite, using the layer's dimensions as a destination rect. - // We do this as if the layer only contains an image, directly compositing - // it is a much faster method than using m_recordingPicture. - SkPicture* m_recordingPicture; - typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap; KeyframesMap m_animations; @@ -340,10 +323,15 @@ private: int m_uniqueId; + // Note that m_content and m_imageCRC are mutually exclusive; + // m_content is used when WebKit is asked to paint the layer's + // content, while m_imageCRC references an image that we directly + // composite, using the layer's dimensions as a destination rect. + // We do this as if the layer only contains an image, directly compositing + // it is a much faster method than using m_content. + LayerContent* m_content; unsigned m_imageCRC; - unsigned int m_pictureUsed; - // used to signal the framework we need a repaint bool m_hasRunningAnimations; @@ -363,7 +351,6 @@ private: LayerType m_type; SubclassType m_subclassType; - bool m_hasText; bool m_intrinsicallyComposited; LayerGroup* m_layerGroup; diff --git a/Source/WebCore/platform/graphics/android/LayerContent.h b/Source/WebCore/platform/graphics/android/LayerContent.h new file mode 100644 index 0000000..32108ec --- /dev/null +++ b/Source/WebCore/platform/graphics/android/LayerContent.h @@ -0,0 +1,51 @@ +/* + * 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 LayerContent_h +#define LayerContent_h + +#include "SkRefCnt.h" + +class SkCanvas; +class SkPicture; +class SkWStream; + +namespace WebCore { + +class LayerContent : public SkRefCnt { +public: + virtual int width() = 0; + virtual int height() = 0; + virtual bool isEmpty() = 0; + virtual void checkForOptimisations() = 0; + virtual bool hasText() = 0; + virtual void draw(SkCanvas* canvas) = 0; + + virtual void serialize(SkWStream* stream) = 0; +}; + +} // WebCore + +#endif // LayerContent_h diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/LayerGroup.cpp index 5ec41f8..af45e41 100644 --- a/Source/WebCore/platform/graphics/android/LayerGroup.cpp +++ b/Source/WebCore/platform/graphics/android/LayerGroup.cpp @@ -102,19 +102,21 @@ bool LayerGroup::tryUpdateLayerGroup(LayerGroup* oldLayerGroup) m_dualTiledTexture->markAsDirty(*layerInval); } else { SkRegion invalRegion; - bool fullInval = false; - for (unsigned int i = 0; i < m_layers.size(); i++) { - if (m_layers[i]->uniqueId() != oldLayerGroup->m_layers[i]->uniqueId()) { - // layer list has changed, fully invalidate - // TODO: partially invalidate based on layer size/position - fullInval = true; - break; - } else if (!m_layers[i]->getInvalRegion()->isEmpty()) { - // merge layer inval - translate the layer's inval region into group coordinates - SkPoint pos = m_layers[i]->getPosition(); - m_layers[i]->getInvalRegion()->translate(pos.fX, pos.fY); - invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op); - break; + bool fullInval = m_layers.size() != oldLayerGroup->m_layers.size(); + if (!fullInval) { + for (unsigned int i = 0; i < m_layers.size(); i++) { + if (m_layers[i]->uniqueId() != oldLayerGroup->m_layers[i]->uniqueId()) { + // layer list has changed, fully invalidate + // TODO: partially invalidate based on layer size/position + fullInval = true; + break; + } else if (!m_layers[i]->getInvalRegion()->isEmpty()) { + // merge layer inval - translate the layer's inval region into group coordinates + SkPoint pos = m_layers[i]->getPosition(); + m_layers[i]->getInvalRegion()->translate(pos.fX, pos.fY); + invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op); + break; + } } } @@ -260,7 +262,7 @@ void LayerGroup::computeTexturesAmount(TexturesResult* result) m_dualTiledTexture->computeTexturesAmount(result, getFirstLayer()); } -bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) +bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas) { if (singleLayer()) { getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers); diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.h b/Source/WebCore/platform/graphics/android/LayerGroup.h index e3e0247..90001a5 100644 --- a/Source/WebCore/platform/graphics/android/LayerGroup.h +++ b/Source/WebCore/platform/graphics/android/LayerGroup.h @@ -64,7 +64,7 @@ public: bool hasText() { return m_hasText; } // TilePainter methods - virtual bool paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed); + virtual bool paint(BaseTile* tile, SkCanvas* canvas); virtual float opacity(); private: const TransformationMatrix* drawTransform(); diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp new file mode 100644 index 0000000..cf2e569 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp @@ -0,0 +1,103 @@ +#include "config.h" +#include "PictureLayerContent.h" + +#include "InspectorCanvas.h" +#include "SkPicture.h" + +namespace WebCore { + +PictureLayerContent::PictureLayerContent(SkPicture* picture) + : m_picture(picture) + , m_checkedContent(false) + , m_hasText(true) +{ + SkSafeRef(m_picture); +} + +PictureLayerContent::PictureLayerContent(const PictureLayerContent& content) + : m_picture(content.m_picture) + , m_checkedContent(content.m_checkedContent) + , m_hasText(content.m_hasText) +{ + SkSafeRef(m_picture); +} + +PictureLayerContent::~PictureLayerContent() +{ + SkSafeUnref(m_picture); +} + +int PictureLayerContent::width() +{ + if (!m_picture) + return 0; + return m_picture->width(); +} + +int PictureLayerContent::height() +{ + if (!m_picture) + return 0; + return m_picture->height(); +} + +bool PictureLayerContent::isEmpty() +{ + if (!m_picture) + return true; + if (m_picture->width() == 0 + || m_picture->height() == 0) + return true; + return false; +} + +void PictureLayerContent::checkForOptimisations() +{ + if (!m_checkedContent) + hasText(); // for now only check the presence of text +} + +bool PictureLayerContent::hasText() +{ + if (m_checkedContent) + return m_hasText; + + // Let's check if we have text or not. If we don't, we can limit + // ourselves to scale 1! + InspectorBounder inspectorBounder; + InspectorCanvas checker(&inspectorBounder, m_picture); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, + m_picture->width(), + m_picture->height()); + checker.setBitmapDevice(bitmap); + checker.drawPicture(*m_picture); + m_hasText = checker.hasText(); + if (!checker.hasContent()) { + // no content to draw, discard picture so UI / tile generation + // doesn't bother with it + SkSafeUnref(m_picture); + m_picture = 0; + } + + m_checkedContent = true; + + return m_hasText; +} + +void PictureLayerContent::draw(SkCanvas* canvas) +{ + if (!m_picture) + return; + + canvas->drawPicture(*m_picture); +} + +void PictureLayerContent::serialize(SkWStream* stream) +{ + if (!m_picture) + return; + m_picture->serialize(stream); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/PictureLayerContent.h new file mode 100644 index 0000000..94bdfac --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.h @@ -0,0 +1,55 @@ +/* + * 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 PictureLayerContent_h +#define PictureLayerContent_h + +#include "LayerContent.h" + +namespace WebCore { + +class PictureLayerContent : public LayerContent { +public: + PictureLayerContent(SkPicture* picture); + PictureLayerContent(const PictureLayerContent& content); + ~PictureLayerContent(); + + virtual int width(); + virtual int height(); + virtual bool isEmpty(); + virtual void checkForOptimisations(); + virtual bool hasText(); + virtual void draw(SkCanvas* canvas); + virtual void serialize(SkWStream* stream); + +private: + SkPicture* m_picture; + bool m_checkedContent; + bool m_hasText; +}; + +} // WebCore + +#endif // PictureLayerContent_h diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp new file mode 100644 index 0000000..bc024eb --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp @@ -0,0 +1,35 @@ +#include "config.h" +#include "PictureSetLayerContent.h" + +#include "SkPicture.h" + +namespace WebCore { + +PictureSetLayerContent::PictureSetLayerContent(const android::PictureSet& pictureSet) +{ + m_pictureSet.set(pictureSet); +} + +PictureSetLayerContent::~PictureSetLayerContent() +{ + m_pictureSet.clear(); +} + +void PictureSetLayerContent::draw(SkCanvas* canvas) +{ + if (!m_pictureSet.isEmpty()) + m_pictureSet.draw(canvas); +} + +void PictureSetLayerContent::serialize(SkWStream* stream) +{ + if (!stream) + return; + SkPicture picture; + draw(picture.beginRecording(m_pictureSet.width(), m_pictureSet.height(), + SkPicture::kUsePathBoundsForClip_RecordingFlag)); + picture.endRecording(); + picture.serialize(stream); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h new file mode 100644 index 0000000..61fc3f4 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h @@ -0,0 +1,53 @@ +/* + * 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 PictureSetLayerContent_h +#define PictureSetLayerContent_h + +#include "LayerContent.h" +#include "PictureSet.h" + +namespace WebCore { + +class PictureSetLayerContent : public LayerContent { +public: + PictureSetLayerContent(const android::PictureSet& pictureSet); + ~PictureSetLayerContent(); + + virtual int width() { return m_pictureSet.width(); } + virtual int height() { return m_pictureSet.height(); } + virtual bool isEmpty() { return m_pictureSet.isEmpty(); } + virtual void checkForOptimisations() {} + virtual bool hasText() { return true; } + virtual void draw(SkCanvas* canvas); + virtual void serialize(SkWStream* stream); + +private: + android::PictureSet m_pictureSet; +}; + +} // WebCore + +#endif // PictureLayerContent_h diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp index 55fa51a..23abc06 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp @@ -32,6 +32,7 @@ #include "LayerGroup.h" #include "GLWebViewState.h" #include "ScrollableLayerAndroid.h" +#include "TilesManager.h" #include <cutils/log.h> #include <wtf/CurrentTime.h> @@ -62,8 +63,11 @@ SurfaceCollection::SurfaceCollection(BaseLayerAndroid* baseLayer) : m_baseLayer(baseLayer) , m_compositedRoot(0) { + if (!m_baseLayer) + return; + SkSafeRef(m_baseLayer); - if (m_baseLayer && m_baseLayer->countChildren()) { + if (m_baseLayer->countChildren()) { m_compositedRoot = static_cast<LayerAndroid*>(m_baseLayer->getChild(0)); // calculate draw transforms and z values @@ -76,6 +80,14 @@ SurfaceCollection::SurfaceCollection(BaseLayerAndroid* baseLayer) LayerMergeState layerMergeState(&m_layerGroups); m_compositedRoot->assignGroups(&layerMergeState); } + + // set the layergroups' and tiledpages' update count, to be drawn on painted tiles + unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates(); + for (unsigned int i = 0; i < m_layerGroups.size(); i++) + m_layerGroups[i]->setUpdateCount(updateCount); + m_baseLayer->state()->frontPage()->setUpdateCount(updateCount); + m_baseLayer->state()->backPage()->setUpdateCount(updateCount); + #ifdef DEBUG_COUNT ClassTracker::instance()->increment("SurfaceCollection"); #endif diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.cpp b/Source/WebCore/platform/graphics/android/TextureInfo.cpp index 3c4dde2..56b6698 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.cpp +++ b/Source/WebCore/platform/graphics/android/TextureInfo.cpp @@ -42,7 +42,6 @@ TextureInfo::TextureInfo() m_height = 0; m_internalFormat = 0; m_eglSurface = EGL_NO_SURFACE; - m_pictureCount = 0; } bool TextureInfo::equalsAttributes(const TextureInfo* otherTexture) diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.h b/Source/WebCore/platform/graphics/android/TextureInfo.h index 8549365..764c229 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.h +++ b/Source/WebCore/platform/graphics/android/TextureInfo.h @@ -64,8 +64,6 @@ public: sp<ANativeWindow> m_ANW; // The EGLSurface wraps the m_ANW to enable direct OpenGL rendering (e.g. Ganesh) EGLSurface m_eglSurface; - - int m_pictureCount; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index e2ae66c..34e877e 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -39,10 +39,16 @@ class TilePainter : public SkRefCnt { // TODO: investigate webkit threadsafe ref counting public: virtual ~TilePainter() { } - virtual bool paint(BaseTile* tile, SkCanvas*, unsigned int*) = 0; + virtual bool paint(BaseTile* tile, SkCanvas* canvas) = 0; virtual float opacity() { return 1.0; } enum SurfaceType { Painted, Image }; virtual SurfaceType type() { return Painted; } + + unsigned int getUpdateCount() { return m_updateCount; } + void setUpdateCount(unsigned int updateCount) { m_updateCount = updateCount; } + +private: + unsigned int m_updateCount; }; } diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp index 820cd56..629b095 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.cpp +++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp @@ -65,7 +65,6 @@ TiledPage::TiledPage(int id, GLWebViewState* state) , m_scale(1) , m_invScale(1) , m_glWebViewState(state) - , m_latestPictureInval(0) , m_prepare(false) , m_isPrefetchPage(false) , m_willDraw(false) @@ -126,8 +125,9 @@ void TiledPage::discardTextures() return; } -void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureCount) +void TiledPage::invalidateRect(const IntRect& inval) { +#ifdef DEBUG // Given the current scale level we need to mark the appropriate tiles as dirty const float invTileContentWidth = m_scale / TilesManager::tileWidth(); const float invTileContentHeight = m_scale / TilesManager::tileHeight(); @@ -138,11 +138,10 @@ void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureC const int lastDirtyTileY = static_cast<int>(ceilf(inval.maxY() * invTileContentHeight)); XLOG("Marking X %d-%d and Y %d-%d dirty", firstDirtyTileX, lastDirtyTileX, firstDirtyTileY, lastDirtyTileY); +#endif // We defer marking the tile as dirty until the next time we need to prepare // to draw. - m_invalRegion.op(firstDirtyTileX, firstDirtyTileY, lastDirtyTileX, lastDirtyTileY, SkRegion::kUnion_Op); - m_invalTilesRegion.op(inval.x(), inval.y(), inval.maxX(), inval.maxY(), SkRegion::kUnion_Op); - m_latestPictureInval = pictureCount; + m_invalRegion.op(inval.x(), inval.y(), inval.maxX(), inval.maxY(), SkRegion::kUnion_Op); } void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, const SkIRect& tileBounds) @@ -205,32 +204,17 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y } } -bool TiledPage::updateTileDirtiness(const SkIRect& tileBounds) +void TiledPage::updateTileDirtiness() { - if (!m_glWebViewState || tileBounds.isEmpty()) { - m_invalRegion.setEmpty(); - m_invalTilesRegion.setEmpty(); - return false; - } - - bool visibleTileIsDirty = false; - for (int x = 0; x < m_baseTileSize; x++) { - - BaseTile& tile = m_baseTiles[x]; + if (!m_glWebViewState || m_invalRegion.isEmpty()) + return; - // if the tile is in the dirty region then we must invalidate it - if (m_invalRegion.contains(tile.x(), tile.y())) { - tile.markAsDirty(m_latestPictureInval, m_invalTilesRegion); - if (tileBounds.contains(tile.x(), tile.y())) - visibleTileIsDirty = true; - } - } + for (int x = 0; x < m_baseTileSize; x++) + m_baseTiles[x].markAsDirty(m_invalRegion); // clear the invalidated region as all tiles within that region have now // been marked as dirty. m_invalRegion.setEmpty(); - m_invalTilesRegion.setEmpty(); - return visibleTileIsDirty; } void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds) @@ -385,7 +369,7 @@ void TiledPage::drawGL() m_willDraw = false; // don't redraw until re-prepared } -bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed) +bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas) { static SkPaintFlagsDrawFilter prefetchFilter(SkPaint::kAllFlags, SkPaint::kAntiAlias_Flag); @@ -396,7 +380,7 @@ bool TiledPage::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUse if (isPrefetchPage()) canvas->setDrawFilter(&prefetchFilter); - *pictureUsed = m_glWebViewState->paintBaseLayerContent(canvas); + m_glWebViewState->paintBaseLayerContent(canvas); return true; } diff --git a/Source/WebCore/platform/graphics/android/TiledPage.h b/Source/WebCore/platform/graphics/android/TiledPage.h index e6269ae..5587618 100644 --- a/Source/WebCore/platform/graphics/android/TiledPage.h +++ b/Source/WebCore/platform/graphics/android/TiledPage.h @@ -65,9 +65,8 @@ public: // prepare the page for display on the screen void prepare(bool goingDown, bool goingLeft, const SkIRect& tileBounds, PrepareBounds bounds); - // update tiles with inval information, return true if visible ones are - // dirty (and thus repaint needed) - bool updateTileDirtiness(const SkIRect& tileBounds); + // update tiles with inval information + void updateTileDirtiness(); // returns true if the page can't draw the entire region (may still be stale) bool hasMissingContent(const SkIRect& tileBounds); @@ -83,7 +82,7 @@ public: // TilePainter implementation // used by individual tiles to generate the bitmap for their tile - bool paint(BaseTile*, SkCanvas*, unsigned int*); + bool paint(BaseTile* tile, SkCanvas* canvas); // used by individual tiles to get the information about the current picture GLWebViewState* glWebViewState() { return m_glWebViewState; } @@ -93,7 +92,7 @@ public: //TODO: clear all textures if this is called with a new value void setScale(float scale) { m_scale = scale; m_invScale = 1 / scale; } - void invalidateRect(const IntRect& invalRect, const unsigned int pictureCount); + void invalidateRect(const IntRect& invalRect); void discardTextures(); void updateBaseTileSize(); bool scrollingDown() { return m_scrollingDown; } @@ -116,15 +115,8 @@ private: float m_invScale; GLWebViewState* m_glWebViewState; - // used to identify the tiles that have been invalidated (marked dirty) since - // the last time updateTileState() has been called. The region is stored in - // terms of the (x,y) coordinates used to determine the location of the tile - // within the page, not in content/view pixel coordinates. - SkRegion m_invalRegion; - // inval regions in content coordinates - SkRegion m_invalTilesRegion; - unsigned int m_latestPictureInval; + SkRegion m_invalRegion; // in content coordinates bool m_prepare; bool m_scrollingDown; bool m_isPrefetchPage; diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp index 3edc93c..57d7683 100644 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp @@ -152,7 +152,7 @@ void TiledTexture::prepareGL(GLWebViewState* state, float scale, // apply dirty region to affected tiles if (!m_dirtyRegion.isEmpty()) { for (unsigned int i = 0; i < m_tiles.size(); i++) - m_tiles[i]->markAsDirty(1, m_dirtyRegion); + m_tiles[i]->markAsDirty(m_dirtyRegion); m_dirtyRegion.setEmpty(); } diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index a284687..5e9bf58 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -105,6 +105,7 @@ TilesManager::TilesManager() , m_useMinimalMemory(true) , m_useDoubleBuffering(true) , m_contentUpdates(0) + , m_webkitContentUpdates(0) , m_queue(0) , m_drawGLCount(1) , m_lastTimeLayersUsed(0) diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h index 98fc08c..a0ed9e7 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/TilesManager.h @@ -182,6 +182,9 @@ public: } bool useDoubleBuffering() { return m_useDoubleBuffering; } + + unsigned int incWebkitContentUpdates() { return m_webkitContentUpdates++; } + void incContentUpdates() { m_contentUpdates++; } unsigned int getContentUpdates() { return m_contentUpdates; } void clearContentUpdates() { m_contentUpdates = 0; } @@ -231,6 +234,7 @@ private: bool m_useDoubleBuffering; unsigned int m_contentUpdates; // nr of successful tiled paints + unsigned int m_webkitContentUpdates; // nr of paints from webkit sp<TexturesGenerator> m_pixmapsGenerationThread; diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index 8ad9119..0002c2c 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -152,15 +152,6 @@ bool TransferQueue::checkObsolete(const TileTransferData* data) return true; } - const TextureTileInfo* tileInfo = &(data->tileInfo); - - if (tileInfo->m_x != baseTilePtr->x() - || tileInfo->m_y != baseTilePtr->y() - || tileInfo->m_scale != baseTilePtr->scale()) { - XLOG("Mismatching x, y, scale or painter , such that the tile is obsolete"); - return true; - } - return false; } @@ -176,7 +167,7 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, int textureWidth = destTex->getSize().width(); int textureHeight = destTex->getSize().height(); - IntRect inval = m_transferQueue[index].tileInfo.m_inval; + IntRect inval = m_transferQueue[index].invalRect; bool partialInval = !inval.isEmpty(); if (partialInval && frontTex) { @@ -352,7 +343,7 @@ void TransferQueue::updatePureColorTiles() if (!obsoleteBaseTile) { destTexture = data->savedBaseTilePtr->backTexture(); destTexture->setPureColor(data->pureColor); - destTexture->setOwnTextureTileInfoFromQueue(&data->tileInfo); + destTexture->transferComplete(); } } else if (data->status == emptyItem || data->status == pendingDiscard) { // The queue should be clear instead of setting to different status. @@ -413,7 +404,7 @@ void TransferQueue::updateDirtyBaseTiles() // Here we just need to upload the bitmap content to the GL Texture GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId, *m_transferQueue[index].bitmap, - m_transferQueue[index].tileInfo.m_inval); + m_transferQueue[index].invalRect); } else { if (!usedFboForUpload) { saveGLState(); @@ -425,13 +416,8 @@ void TransferQueue::updateDirtyBaseTiles() index); } - // After the base tile copied into the GL texture, we need to - // update the texture's info such that at draw time, readyFor - // will find the latest texture's info - // We don't need a map any more, each texture contains its own - // texturesTileInfo. destTexture->setPure(false); - destTexture->setOwnTextureTileInfoFromQueue(&m_transferQueue[index].tileInfo); + destTexture->transferComplete(); XLOG("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d", m_transferQueue[index].tileInfo.m_x, @@ -548,9 +534,6 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo, data->status = pendingBlit; data->uploadType = type; - // Now fill the tileInfo. - TextureTileInfo* textureInfo = &(data->tileInfo); - IntRect inval(0, 0, 0, 0); if (renderInfo->invalRect) { inval.setX(renderInfo->invalRect->fLeft); @@ -558,14 +541,7 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo, inval.setWidth(renderInfo->invalRect->width()); inval.setHeight(renderInfo->invalRect->height()); } - textureInfo->m_inval = inval; - - textureInfo->m_x = renderInfo->x; - textureInfo->m_y = renderInfo->y; - textureInfo->m_scale = renderInfo->scale; - textureInfo->m_painter = renderInfo->tilePainter; - - textureInfo->m_picture = renderInfo->textureInfo->m_pictureCount; + data->invalRect = inval; } // Note that there should be lock/unlock around this function call. diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h index 5dd2e0a..b864085 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/TransferQueue.h @@ -87,7 +87,7 @@ public: TransferItemStatus status; BaseTile* savedBaseTilePtr; BaseTileTexture* savedBaseTileTexturePtr; - TextureTileInfo tileInfo; + IntRect invalRect; TextureUploadType uploadType; // This is only useful in Cpu upload code path, so it will be dynamically // lazily allocated. diff --git a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp index 000cd5a..04b487a 100644 --- a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp @@ -176,11 +176,9 @@ void PlatformBridge::setScrollPosition(ScrollView* scrollView, int x, int y) { // Check to make sure the view is the main FrameView. android::WebViewCore *webViewCore = android::WebViewCore::getWebViewCore(scrollView); 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); + webViewCore->scrollTo(x, y); } } diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp index a96b6b4..d3075a2 100644 --- a/Source/WebKit/android/jni/ViewStateSerializer.cpp +++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp @@ -33,6 +33,8 @@ #include "IFrameLayerAndroid.h" #include "Layer.h" #include "LayerAndroid.h" +#include "LayerContent.h" +#include "PictureLayerContent.h" #include "PictureSet.h" #include "ScrollableLayerAndroid.h" #include "SkPicture.h" @@ -79,14 +81,12 @@ static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer, #else stream->write32(0); #endif - SkPicture picture; - PictureSet* content = baseLayer->content(); - baseLayer->drawCanvas(picture.beginRecording(content->width(), content->height(), - SkPicture::kUsePathBoundsForClip_RecordingFlag)); - picture.endRecording(); if (!stream) return false; - picture.serialize(stream); + if (baseLayer->content()) + baseLayer->content()->serialize(stream); + else + return false; int childCount = baseLayer->countChildren(); XLOG("BaseLayer has %d child(ren)", childCount); stream->write32(childCount); @@ -110,7 +110,9 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint v layer->setBackgroundColor(color); #endif SkPicture* picture = new SkPicture(stream); - layer->setContent(picture); + PictureLayerContent* content = new PictureLayerContent(picture); + layer->setContent(content); + SkSafeUnref(content); SkSafeUnref(picture); int childCount = stream->readS32(); for (int i = 0; i < childCount; i++) { @@ -335,10 +337,10 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream) stream->write32(buffer.size()); buffer.writeToStream(stream); } - bool hasRecordingPicture = layer->m_recordingPicture != 0; + bool hasRecordingPicture = layer->m_content != 0 && !layer->m_content->isEmpty(); stream->writeBool(hasRecordingPicture); if (hasRecordingPicture) - layer->m_recordingPicture->serialize(stream); + layer->m_content->serialize(stream); // TODO: support m_animations (maybe?) stream->write32(0); // placeholder for m_animations.size(); writeTransformationMatrix(stream, layer->m_transform); @@ -453,7 +455,11 @@ LayerAndroid* deserializeLayer(int version, SkStream* stream) } bool hasRecordingPicture = stream->readBool(); if (hasRecordingPicture) { - layer->m_recordingPicture = new SkPicture(stream); + SkPicture* picture = new SkPicture(stream); + PictureLayerContent* content = new PictureLayerContent(picture); + layer->setContent(content); + SkSafeUnref(content); + SkSafeUnref(picture); } int animationCount = stream->readU32(); // TODO: Support (maybe?) readTransformationMatrix(stream, layer->m_transform); @@ -473,7 +479,6 @@ LayerAndroid* deserializeLayer(int version, SkStream* stream) if (childLayer) layer->addChild(childLayer); } - layer->needsRepaint(); XLOG("Created layer with id %d", layer->uniqueId()); return layer; } diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 879c007..1bba9b8 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -87,6 +87,7 @@ #include "NodeList.h" #include "Page.h" #include "PageGroup.h" +#include "PictureSetLayerContent.h" #include "PlatformKeyboardEvent.h" #include "PlatformString.h" #include "PluginWidgetAndroid.h" @@ -820,7 +821,10 @@ void WebViewCore::notifyAnimationStarted() BaseLayerAndroid* WebViewCore::createBaseLayer(SkRegion* region) { BaseLayerAndroid* base = new BaseLayerAndroid(); - base->setContent(m_content); + + PictureSetLayerContent* content = new PictureSetLayerContent(m_content); + base->setContent(content); + SkSafeUnref(content); m_skipContentDraw = true; bool layoutSucceeded = layoutIfNeededRecursive(m_mainFrame); diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index c7f132f..eddf0ab 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -258,7 +258,6 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, DrawExtra* extra = getDrawExtra((DrawExtras) extras); - unsigned int pic = m_glWebViewState->currentPictureCounter(); m_glWebViewState->glExtras()->setDrawExtra(extra); // Make sure we have valid coordinates. We might not have valid coords @@ -280,7 +279,7 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, checkException(env); } } - if (ret || m_glWebViewState->currentPictureCounter() != pic) + if (ret) return !m_isDrawingPaused; #endif return false; @@ -295,14 +294,14 @@ PictureSet* draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras, bool spli } // draw the content of the base layer first - PictureSet* content = m_baseLayer->content(); + LayerContent* content = m_baseLayer->content(); + int sc = canvas->save(SkCanvas::kClip_SaveFlag); canvas->clipRect(SkRect::MakeLTRB(0, 0, content->width(), content->height()), SkRegion::kDifference_Op); canvas->drawColor(bgColor); canvas->restoreToCount(sc); - if (content->draw(canvas)) - ret = split ? new PictureSet(*content) : 0; + content->draw(canvas); DrawExtra* extra = getDrawExtra(extras); if (extra) @@ -560,7 +559,7 @@ void replaceBaseContent(PictureSet* set) { if (!m_baseLayer) return; - m_baseLayer->setContent(*set); + // TODO: remove the split picture codepath delete set; } @@ -568,7 +567,7 @@ void copyBaseContentToPicture(SkPicture* picture) { if (!m_baseLayer) return; - PictureSet* content = m_baseLayer->content(); + LayerContent* content = m_baseLayer->content(); m_baseLayer->drawCanvas(picture->beginRecording(content->width(), content->height(), SkPicture::kUsePathBoundsForClip_RecordingFlag)); picture->endRecording(); @@ -878,26 +877,6 @@ static jobject nativeLayerBounds(JNIEnv* env, jobject obj, jint jlayer) return rect; } -static jobject nativeSubtractLayers(JNIEnv* env, jobject obj, jobject jrect) -{ - SkIRect irect = jrect_to_webrect(env, jrect); -#if USE(ACCELERATED_COMPOSITING) - LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot(); - if (root) { - SkRect rect; - rect.set(irect); - rect = root->subtractLayers(rect); - rect.round(&irect); - } -#endif - jclass rectClass = env->FindClass("android/graphics/Rect"); - jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); - jobject rect = env->NewObject(rectClass, init, irect.fLeft, irect.fTop, - irect.fRight, irect.fBottom); - env->DeleteLocalRef(rectClass); - return rect; -} - static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) { WebView* view = GET_NATIVE_VIEW(env, obj); @@ -1249,8 +1228,6 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeTileProfilingGetFloat }, { "nativeStopGL", "()V", (void*) nativeStopGL }, - { "nativeSubtractLayers", "(Landroid/graphics/Rect;)Landroid/graphics/Rect;", - (void*) nativeSubtractLayers }, { "nativeScrollableLayer", "(IILandroid/graphics/Rect;Landroid/graphics/Rect;)I", (void*) nativeScrollableLayer }, { "nativeScrollLayer", "(III)Z", diff --git a/Source/WebKit/android/plugins/ANPSoundInterface.cpp b/Source/WebKit/android/plugins/ANPSoundInterface.cpp index 12c9176..41893f9 100644 --- a/Source/WebKit/android/plugins/ANPSoundInterface.cpp +++ b/Source/WebKit/android/plugins/ANPSoundInterface.cpp @@ -102,7 +102,7 @@ static ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate, fromANPFormat(format), (channelCount > 1) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, 0, // frameCount - 0, // flags + (audio_policy_output_flags_t) 0, // AUDIO_POLICY_OUTPUT_FLAG_NONE, callbackProc, track, 0); |
