From 594c6b805969c2673c84d1d1d1a3556ce376ac7a Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Tue, 3 Apr 2012 16:12:40 -0700 Subject: Rename several classes BaseTile,BaseTileTexture -> Tile,TileTexture Used in layers other than the base LayerGroup -> Surface Renamed to convey that it is a member of the SurfaceCollection, and that the layers grouped inside are painted together (if at all) DualTiledTexture -> SurfaceBacking Better conveys that this is the raster backing for a surface that can paint. It may be implemented with two tiled textures for now, but that isn't as important as its relationship to the surface. TiledTexture -> TileGrid Renamed to make it more clear that it was a container of tiles, and to be less similar to TileTexture Change-Id: I843f8603a2080cfe5a7313ba1c2eff10620f8aa2 --- Source/WebCore/Android.mk | 9 +- .../platform/graphics/android/BaseLayerAndroid.cpp | 1 - .../platform/graphics/android/BaseRenderer.cpp | 1 + .../platform/graphics/android/BaseRenderer.h | 4 +- .../WebCore/platform/graphics/android/BaseTile.cpp | 537 -------------------- .../WebCore/platform/graphics/android/BaseTile.h | 193 -------- .../platform/graphics/android/BaseTileTexture.cpp | 138 ------ .../platform/graphics/android/BaseTileTexture.h | 97 ---- .../platform/graphics/android/FixedPositioning.cpp | 1 + .../WebCore/platform/graphics/android/GLExtras.cpp | 1 + .../WebCore/platform/graphics/android/GLUtils.cpp | 14 +- Source/WebCore/platform/graphics/android/GLUtils.h | 6 +- .../platform/graphics/android/GLWebViewState.cpp | 12 +- .../platform/graphics/android/GLWebViewState.h | 14 +- .../platform/graphics/android/GaneshContext.cpp | 19 +- .../platform/graphics/android/GaneshContext.h | 6 +- .../platform/graphics/android/GaneshRenderer.cpp | 3 +- .../graphics/android/GraphicsLayerAndroid.cpp | 1 + .../graphics/android/GraphicsLayerAndroid.h | 2 +- .../platform/graphics/android/ImageTexture.cpp | 11 +- .../platform/graphics/android/ImageTexture.h | 13 +- .../platform/graphics/android/LayerAndroid.cpp | 57 +-- .../platform/graphics/android/LayerAndroid.h | 13 +- .../platform/graphics/android/LayerGroup.cpp | 344 ------------- .../WebCore/platform/graphics/android/LayerGroup.h | 115 ----- .../graphics/android/PaintTileOperation.cpp | 3 +- .../platform/graphics/android/PaintTileOperation.h | 6 +- .../platform/graphics/android/RasterRenderer.cpp | 1 + .../WebCore/platform/graphics/android/Surface.cpp | 346 +++++++++++++ Source/WebCore/platform/graphics/android/Surface.h | 115 +++++ .../platform/graphics/android/SurfaceBacking.cpp | 171 +++++++ .../platform/graphics/android/SurfaceBacking.h | 86 ++++ .../graphics/android/SurfaceCollection.cpp | 62 +-- .../platform/graphics/android/SurfaceCollection.h | 7 +- .../graphics/android/SurfaceCollectionManager.cpp | 1 - .../platform/graphics/android/TextureInfo.h | 1 - .../platform/graphics/android/TextureOwner.h | 4 +- .../graphics/android/TexturesGenerator.cpp | 1 + .../platform/graphics/android/TexturesGenerator.h | 4 +- Source/WebCore/platform/graphics/android/Tile.cpp | 538 +++++++++++++++++++++ Source/WebCore/platform/graphics/android/Tile.h | 193 ++++++++ .../WebCore/platform/graphics/android/TileGrid.cpp | 371 ++++++++++++++ .../WebCore/platform/graphics/android/TileGrid.h | 87 ++++ .../platform/graphics/android/TilePainter.h | 4 +- .../platform/graphics/android/TileTexture.cpp | 140 ++++++ .../platform/graphics/android/TileTexture.h | 100 ++++ .../platform/graphics/android/TiledTexture.cpp | 491 ------------------- .../platform/graphics/android/TiledTexture.h | 144 ------ .../platform/graphics/android/TilesManager.cpp | 46 +- .../platform/graphics/android/TilesManager.h | 27 +- .../platform/graphics/android/TilesProfiler.cpp | 3 +- .../platform/graphics/android/TilesProfiler.h | 10 +- .../platform/graphics/android/TransferQueue.cpp | 71 +-- .../platform/graphics/android/TransferQueue.h | 30 +- .../graphics/android/VideoLayerAndroid.cpp | 1 + .../platform/graphics/android/VideoLayerAndroid.h | 1 - .../platform/graphics/android/VideoLayerManager.h | 1 + Source/WebKit/android/jni/ViewStateSerializer.cpp | 1 + Source/WebKit/android/nav/WebView.cpp | 3 + .../WebKit/android/plugins/ANPSurfaceInterface.cpp | 14 +- 60 files changed, 2410 insertions(+), 2286 deletions(-) delete mode 100644 Source/WebCore/platform/graphics/android/BaseTile.cpp delete mode 100644 Source/WebCore/platform/graphics/android/BaseTile.h delete mode 100644 Source/WebCore/platform/graphics/android/BaseTileTexture.cpp delete mode 100644 Source/WebCore/platform/graphics/android/BaseTileTexture.h delete mode 100644 Source/WebCore/platform/graphics/android/LayerGroup.cpp delete mode 100644 Source/WebCore/platform/graphics/android/LayerGroup.h create mode 100644 Source/WebCore/platform/graphics/android/Surface.cpp create mode 100644 Source/WebCore/platform/graphics/android/Surface.h create mode 100644 Source/WebCore/platform/graphics/android/SurfaceBacking.cpp create mode 100644 Source/WebCore/platform/graphics/android/SurfaceBacking.h create mode 100644 Source/WebCore/platform/graphics/android/Tile.cpp create mode 100644 Source/WebCore/platform/graphics/android/Tile.h create mode 100644 Source/WebCore/platform/graphics/android/TileGrid.cpp create mode 100644 Source/WebCore/platform/graphics/android/TileGrid.h create mode 100644 Source/WebCore/platform/graphics/android/TileTexture.cpp create mode 100644 Source/WebCore/platform/graphics/android/TileTexture.h delete mode 100644 Source/WebCore/platform/graphics/android/TiledTexture.cpp delete mode 100644 Source/WebCore/platform/graphics/android/TiledTexture.h diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 6ddf965..de0aeab 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -636,8 +636,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/AndroidAnimation.cpp \ platform/graphics/android/BaseLayerAndroid.cpp \ platform/graphics/android/BaseRenderer.cpp \ - platform/graphics/android/BaseTile.cpp \ - platform/graphics/android/BaseTileTexture.cpp \ platform/graphics/android/BitmapAllocatorAndroid.cpp \ platform/graphics/android/CanvasLayer.cpp \ platform/graphics/android/CanvasTexture.cpp \ @@ -668,7 +666,6 @@ 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 \ @@ -681,11 +678,15 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/ScrollableLayerAndroid.cpp \ platform/graphics/android/SharedBufferStream.cpp \ platform/graphics/android/ShaderProgram.cpp \ + platform/graphics/android/Surface.cpp \ + platform/graphics/android/SurfaceBacking.cpp \ platform/graphics/android/TextureInfo.cpp \ platform/graphics/android/TexturesGenerator.cpp \ + platform/graphics/android/Tile.cpp \ + platform/graphics/android/TileGrid.cpp \ + platform/graphics/android/TileTexture.cpp \ platform/graphics/android/TilesManager.cpp \ platform/graphics/android/TilesProfiler.cpp \ - platform/graphics/android/TiledTexture.cpp \ platform/graphics/android/TransferQueue.cpp \ platform/graphics/android/SurfaceCollection.cpp \ platform/graphics/android/SurfaceCollectionManager.cpp \ diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 7bb632f..1de5ae7 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -35,7 +35,6 @@ namespace WebCore { - // Note: this must match the use of ID 0 specifying the base layer in DrawExtra #define BASE_UNIQUE_ID 0 diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp index fba62b7..833aea9 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp @@ -41,6 +41,7 @@ #include "SkDevice.h" #include "SkPicture.h" #include "SkTypeface.h" +#include "Tile.h" #include "TilesManager.h" #include diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.h b/Source/WebCore/platform/graphics/android/BaseRenderer.h index ef1e4c2..f225871 100644 --- a/Source/WebCore/platform/graphics/android/BaseRenderer.h +++ b/Source/WebCore/platform/graphics/android/BaseRenderer.h @@ -39,7 +39,7 @@ namespace WebCore { class TextureInfo; class TilePainter; -class BaseTile; +class Tile; struct TileRenderInfo { // coordinates of the tile @@ -59,7 +59,7 @@ struct TileRenderInfo { TilePainter* tilePainter; // the base tile calling us - BaseTile* baseTile; + Tile* baseTile; // info about the texture that we are to render into TextureInfo* textureInfo; diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp deleted file mode 100644 index ddaf181..0000000 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright 2010, 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. - */ - -#define LOG_TAG "BaseTile" -#define LOG_NDEBUG 1 - -#include "config.h" -#include "BaseTile.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "AndroidLog.h" -#include "GLUtils.h" -#include "RasterRenderer.h" -#include "TextureInfo.h" -#include "TilesManager.h" - -// If the dirty portion of a tile exceeds this ratio, fully repaint. -// Lower values give fewer partial repaints, thus fewer front-to-back -// texture copies (cost will vary by device). It's a tradeoff between -// the rasterization cost and the FBO texture recopy cost when using -// GPU for the transfer queue. -#define MAX_INVAL_AREA 0.6 - -namespace WebCore { - -BaseTile::BaseTile(bool isLayerTile) - : m_x(-1) - , m_y(-1) - , m_frontTexture(0) - , m_backTexture(0) - , m_scale(1) - , m_dirty(true) - , m_repaintPending(false) - , m_fullRepaint(true) - , m_isTexturePainted(false) - , m_isLayerTile(isLayerTile) - , m_drawCount(0) - , m_state(Unpainted) -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("BaseTile"); -#endif - m_renderer = BaseRenderer::createRenderer(); -} - -BaseTile::~BaseTile() -{ - if (m_backTexture) - m_backTexture->release(this); - if (m_frontTexture) - m_frontTexture->release(this); - - delete m_renderer; - -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("BaseTile"); -#endif -} - -// All the following functions must be called from the main GL thread. - -void BaseTile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile) -{ - // TODO: investigate whether below check/discard is necessary - if ((m_x != x) - || (m_y != y) - || (m_scale != scale)) { - // neither texture is relevant - discardTextures(); - } - - android::AutoMutex lock(m_atomicSync); - m_x = x; - m_y = y; - m_scale = scale; - m_drawCount = TilesManager::instance()->getDrawGLCount(); - if (isExpandedPrefetchTile) - m_drawCount--; // deprioritize expanded painting region -} - -void BaseTile::reserveTexture() -{ - BaseTileTexture* texture = TilesManager::instance()->getAvailableTexture(this); - - android::AutoMutex lock(m_atomicSync); - if (texture && m_backTexture != texture) { - ALOGV("tile %p reserving texture %p, back was %p (front %p)", - this, texture, m_backTexture, m_frontTexture); - m_state = Unpainted; - m_backTexture = texture; - } - - if (m_state == UpToDate) { - ALOGV("moving tile %p to unpainted, since it reserved while up to date", this); - m_dirty = true; - m_state = Unpainted; - } -} - -bool BaseTile::removeTexture(BaseTileTexture* texture) -{ - ALOGV("%p removeTexture %p, back %p front %p... page %p", - this, texture, m_backTexture, m_frontTexture, m_page); - // We update atomically, so paintBitmap() can see the correct value - android::AutoMutex lock(m_atomicSync); - if (m_frontTexture == texture) { - if (m_state == UpToDate) { - ALOGV("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture); - m_state = Unpainted; - } - - m_frontTexture = 0; - } - if (m_backTexture == texture) { - m_state = Unpainted; - m_backTexture = 0; - } - - // mark dirty regardless of which texture was taken - the back texture may - // have been ready to swap - m_dirty = true; - - return true; -} - -void BaseTile::markAsDirty(const SkRegion& dirtyArea) -{ - if (dirtyArea.isEmpty()) - return; - android::AutoMutex lock(m_atomicSync); - m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op); - - // Check if we actually intersect with the area - bool intersect = false; - SkRegion::Iterator cliperator(dirtyArea); - SkRect realTileRect; - SkRect dirtyRect; - while (!cliperator.done()) { - dirtyRect.set(cliperator.rect()); - if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(), - m_scale, dirtyRect, realTileRect)) { - intersect = true; - break; - } - cliperator.next(); - } - - if (!intersect) - return; - - m_dirty = true; - if (m_state == UpToDate) { - // We only mark a tile as unpainted in 'markAsDirty' if its status is - // UpToDate: marking dirty means we need to repaint, but don't stop the - // current paint - m_state = Unpainted; - } else if (m_state != Unpainted) { - // TODO: fix it so that they can paint while deferring the markAsDirty - // call (or block updates) - ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d, page %p", - this, m_x, m_y, isLayerTile(), m_state, m_page); - - // prefetch tiles can be marked dirty while in the process of painting, - // due to not using an update lock. force them to fail validate step. - m_state = Unpainted; - } -} - -bool BaseTile::isDirty() -{ - android::AutoMutex lock(m_atomicSync); - return m_dirty; -} - -bool BaseTile::isRepaintPending() -{ - android::AutoMutex lock(m_atomicSync); - return m_repaintPending; -} - -void BaseTile::setRepaintPending(bool pending) -{ - android::AutoMutex lock(m_atomicSync); - m_repaintPending = pending; -} - -bool BaseTile::drawGL(float opacity, const SkRect& rect, float scale, - const TransformationMatrix* transform) -{ - if (m_x < 0 || m_y < 0 || m_scale != scale) - return false; - - // No need to mutex protect reads of m_backTexture as it is only written to by - // the consumer thread. - if (!m_frontTexture) - return false; - - // Early return if set to un-usable in purpose! - m_atomicSync.lock(); - bool isTexturePainted = m_isTexturePainted; - m_atomicSync.unlock(); - - if (!isTexturePainted) - return false; - - m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform); - return true; -} - -bool BaseTile::isTileReady() -{ - // Return true if the tile's most recently drawn texture is up to date - android::AutoMutex lock(m_atomicSync); - BaseTileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture; - - if (!texture) - return false; - - if (texture->owner() != this) - return false; - - if (m_dirty) - return false; - - if (m_state != ReadyToSwap && m_state != UpToDate) - return false; - - return true; -} - -bool BaseTile::intersectWithRect(int x, int y, int tileWidth, int tileHeight, - float scale, const SkRect& dirtyRect, - SkRect& realTileRect) -{ - // compute the rect to corresponds to pixels - realTileRect.fLeft = x * tileWidth; - realTileRect.fTop = y * tileHeight; - realTileRect.fRight = realTileRect.fLeft + tileWidth; - realTileRect.fBottom = realTileRect.fTop + tileHeight; - - // scale the dirtyRect for intersect computation. - SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale, - dirtyRect.height() * scale); - realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale); - - if (!realTileRect.intersect(realDirtyRect)) - return false; - return true; -} - -bool BaseTile::isTileVisible(const IntRect& viewTileBounds) -{ - return (m_x >= viewTileBounds.x() - && m_x < viewTileBounds.x() + viewTileBounds.width() - && m_y >= viewTileBounds.y() - && m_y < viewTileBounds.y() + viewTileBounds.height()); -} - -// This is called from the texture generation thread -void BaseTile::paintBitmap(TilePainter* painter) -{ - // We acquire the values below atomically. This ensures that we are reading - // values correctly across cores. Further, once we have these values they - // can be updated by other threads without consequence. - m_atomicSync.lock(); - bool dirty = m_dirty; - BaseTileTexture* texture = m_backTexture; - SkRegion dirtyArea = m_dirtyArea; - float scale = m_scale; - const int x = m_x; - const int y = m_y; - - if (!dirty || !texture) { - m_atomicSync.unlock(); - return; - } - if (m_state != Unpainted) { - ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p", - this, m_state, m_frontTexture, m_backTexture); - } - m_state = PaintingStarted; - TextureInfo* textureInfo = texture->getTextureInfo(); - m_atomicSync.unlock(); - - // at this point we can safely check the ownership (if the texture got - // transferred to another BaseTile under us) - if (texture->owner() != this) { - return; - } - - // swap out the renderer if necessary - BaseRenderer::swapRendererIfNeeded(m_renderer); - // setup the common renderInfo fields; - TileRenderInfo renderInfo; - renderInfo.x = x; - renderInfo.y = y; - renderInfo.scale = scale; - renderInfo.tileSize = texture->getSize(); - renderInfo.tilePainter = painter; - renderInfo.baseTile = this; - renderInfo.textureInfo = textureInfo; - - const float tileWidth = renderInfo.tileSize.width(); - const float tileHeight = renderInfo.tileSize.height(); - - SkRegion::Iterator cliperator(dirtyArea); - - bool fullRepaint = false; - - if (m_fullRepaint - || textureInfo->m_width != tileWidth - || textureInfo->m_height != tileHeight) { - fullRepaint = true; - } - - // For now, only do full repaint - fullRepaint = true; - - if (!fullRepaint) { - // compute the partial inval area - SkIRect totalRect; - totalRect.set(0, 0, 0, 0); - float tileSurface = tileWidth * tileHeight; - float tileSurfaceCap = MAX_INVAL_AREA * tileSurface; - - // We join all the invals in the same tile for now - while (!fullRepaint && !cliperator.done()) { - SkRect realTileRect; - SkRect dirtyRect; - dirtyRect.set(cliperator.rect()); - bool intersect = intersectWithRect(x, y, tileWidth, tileHeight, - scale, dirtyRect, realTileRect); - if (intersect) { - // initialize finalRealRect to the rounded values of realTileRect - SkIRect finalRealRect; - realTileRect.roundOut(&finalRealRect); - - // stash the int values of the current width and height - const int iWidth = finalRealRect.width(); - const int iHeight = finalRealRect.height(); - - if (iWidth == tileWidth || iHeight == tileHeight) { - fullRepaint = true; - break; - } - - // translate the rect into tile space coordinates - finalRealRect.fLeft = finalRealRect.fLeft % static_cast(tileWidth); - finalRealRect.fTop = finalRealRect.fTop % static_cast(tileHeight); - finalRealRect.fRight = finalRealRect.fLeft + iWidth; - finalRealRect.fBottom = finalRealRect.fTop + iHeight; - totalRect.join(finalRealRect); - float repaintSurface = totalRect.width() * totalRect.height(); - - if (repaintSurface > tileSurfaceCap) { - fullRepaint = true; - break; - } - } - - cliperator.next(); - } - - if (!fullRepaint) { - renderInfo.invalRect = &totalRect; - m_renderer->renderTiledContent(renderInfo); - } - } - - // Do a full repaint if needed - if (fullRepaint) { - renderInfo.invalRect = 0; - m_renderer->renderTiledContent(renderInfo); - } - - m_atomicSync.lock(); - - if (texture == m_backTexture) { - m_isTexturePainted = true; - - // set the fullrepaint flags - m_fullRepaint = false; - - // The various checks to see if we are still dirty... - - m_dirty = false; - - if (m_scale != scale) - m_dirty = true; - - if (fullRepaint) - m_dirtyArea.setEmpty(); - else - m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op); - - if (!m_dirtyArea.isEmpty()) - m_dirty = true; - - ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty); - - validatePaint(); - } else { - ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p", - this, texture, m_state, m_frontTexture, m_backTexture); - } - - m_atomicSync.unlock(); -} - -void BaseTile::discardTextures() { - android::AutoMutex lock(m_atomicSync); - ALOGV("%p discarding bt %p, ft %p", - this, m_backTexture, m_frontTexture); - if (m_frontTexture) { - m_frontTexture->release(this); - m_frontTexture = 0; - } - if (m_backTexture) { - m_backTexture->release(this); - m_backTexture = 0; - } - m_dirtyArea.setEmpty(); - m_fullRepaint = true; - - m_dirty = true; - m_state = Unpainted; -} - -void BaseTile::discardBackTexture() { - android::AutoMutex lock(m_atomicSync); - if (m_backTexture) { - m_backTexture->release(this); - m_backTexture = 0; - } - m_state = Unpainted; - m_dirty = true; -} - -bool BaseTile::swapTexturesIfNeeded() { - android::AutoMutex lock(m_atomicSync); - if (m_state == ReadyToSwap) { - // discard old texture and swap the new one in its place - if (m_frontTexture) - m_frontTexture->release(this); - - m_frontTexture = m_backTexture; - m_backTexture = 0; - m_state = UpToDate; - ALOGV("display texture for %p at %d, %d front is now %p, back is %p", - this, m_x, m_y, m_frontTexture, m_backTexture); - - return true; - } - return false; -} - -void BaseTile::backTextureTransfer() { - android::AutoMutex lock(m_atomicSync); - if (m_state == PaintingStarted) - m_state = TransferredUnvalidated; - else if (m_state == ValidatedUntransferred) - m_state = ReadyToSwap; - else { - // shouldn't have transferred a tile in any other state, log - ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d", - this, m_x, m_y, m_state); - } -} - -void BaseTile::backTextureTransferFail() { - // transfer failed for some reason, mark dirty so it will (repaint and) be - // retransferred. - android::AutoMutex lock(m_atomicSync); - m_state = Unpainted; - m_dirty = true; - // whether validatePaint is called before or after, it won't do anything -} - -void BaseTile::validatePaint() { - // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap()) - - if (!m_dirty) { - // since after the paint, the tile isn't dirty, 'validate' it - this - // may happed before or after the transfer queue operation. Only - // when both have happened, mark as 'ReadyToSwap' - if (m_state == PaintingStarted) - m_state = ValidatedUntransferred; - else if (m_state == TransferredUnvalidated) { - // When the backTexture has been marked pureColor, we will skip the - // transfer and marked as ReadyToSwap, in this case, we don't want - // to reset m_dirty bit to true. - m_state = ReadyToSwap; - } else { - ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d", - this, m_x, m_y, m_state); - // failed transferring, in which case mark dirty (since - // paintBitmap() may have cleared m_dirty) - m_dirty = true; - } - - if (m_deferredDirty) { - ALOGV("Note: deferred dirty flag set, possibly a missed paint on tile %p", this); - m_deferredDirty = false; - } - } else { - ALOGV("Note: paint was unsuccessful."); - m_state = Unpainted; - } - -} - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h deleted file mode 100644 index 93ec287..0000000 --- a/Source/WebCore/platform/graphics/android/BaseTile.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2010, 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 BaseTile_h -#define BaseTile_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "BaseRenderer.h" -#include "SkRect.h" -#include "SkRegion.h" -#include "TextureOwner.h" -#include "TilePainter.h" - -#include - -namespace WebCore { - -class TextureInfo; -class BaseTileTexture; -class GLWebViewState; - -/** - * An individual tile that is used to construct part of a webpage's BaseLayer of - * content. Each tile is assigned to a TiledPage and is responsible for drawing - * and displaying their section of the page. The lifecycle of a tile is: - * - * 1. Each tile is created on the main GL thread and assigned to a specific - * location within a TiledPage. - * 2. When needed the tile is passed to the background thread where it paints - * the BaseLayer's most recent PictureSet to a bitmap which is then uploaded - * to the GPU. - * 3. After the bitmap is uploaded to the GPU the main GL thread then uses the - * tile's drawGL() function to display the tile to the screen. - * 4. Steps 2-3 are repeated as necessary. - * 5. The tile is destroyed when the user navigates to a new page. - * - */ -class BaseTile : public TextureOwner { -public: - - // eventually, m_dirty might be rolled into the state machine, but note - // that a tile that's continually marked dirty from animation should still - // progress through the state machine and be drawn periodically (esp. for - // layers) - - // /-> TransferredUnvalidated (TQ interrupts paint) -\ (TQ & paint done) - // Unpainted -> PaintingStarted -- -> ReadyToSwap -> UpToDate - // ^ \-> ValidatedUntransferred (paint finish before TQ) -/ - // | - // \--... (From any state when marked dirty. should usually come from UpToDate if the updates are locked) - // - - enum TextureState{ - // back texture is completely unpainted - Unpainted = 0, - // has started painting, but haven't been transferred or validated - PaintingStarted = 1, - // back texture painted, transferred before validating in PaintBitmap() - TransferredUnvalidated = 2, - // back texture painted, validated before transferring in TransferQueue - ValidatedUntransferred = 3, - // back texture has been blitted, will be swapped when next available - ReadyToSwap = 4, - // has been swapped, is ready to draw, all is well - UpToDate = 5, - }; - - BaseTile(bool isLayerTile = false); - ~BaseTile(); - - bool isLayerTile() { return m_isLayerTile; } - - void setContents(int x, int y, float scale, bool isExpandedPrefetchTile); - - void reserveTexture(); - - bool isTileReady(); - - // Return false when real draw didn't happen for any reason. - bool drawGL(float opacity, const SkRect& rect, float scale, - const TransformationMatrix* transform); - - // the only thread-safe function called by the background thread - void paintBitmap(TilePainter* painter); - - bool intersectWithRect(int x, int y, int tileWidth, int tileHeight, - float scale, const SkRect& dirtyRect, - SkRect& realTileRect); - bool isTileVisible(const IntRect& viewTileBounds); - - void markAsDirty(const SkRegion& dirtyArea); - bool isDirty(); - virtual bool isRepaintPending(); - void setRepaintPending(bool pending); - float scale() const { return m_scale; } - TextureState textureState() const { return m_state; } - - int x() const { return m_x; } - int y() const { return m_y; } - BaseTileTexture* frontTexture() { return m_frontTexture; } - BaseTileTexture* backTexture() { return m_backTexture; } - - // only used for prioritization - the higher, the more relevant the tile is - unsigned long long drawCount() { return m_drawCount; } - void discardTextures(); - void discardBackTexture(); - bool swapTexturesIfNeeded(); - void backTextureTransfer(); - void backTextureTransferFail(); - - // TextureOwner implementation - virtual bool removeTexture(BaseTileTexture* texture); - -private: - void validatePaint(); - - int m_x; - int m_y; - - // The remaining variables can be updated throughout the lifetime of the object - - BaseTileTexture* m_frontTexture; - BaseTileTexture* m_backTexture; - float m_scale; - - // used to signal that the that the tile is out-of-date and needs to be - // redrawn in the backTexture - bool m_dirty; - - // currently only for debugging, to be used for tracking down dropped repaints - bool m_deferredDirty; - - // used to signal that a repaint is pending - bool m_repaintPending; - - // store the dirty region - SkRegion m_dirtyArea; - bool m_fullRepaint; - - // flag used to know if we have a texture that was painted at least once - bool m_isTexturePainted; - - // This mutex serves two purposes. (1) It ensures that certain operations - // happen atomically and (2) it makes sure those operations are synchronized - // across all threads and cores. - android::Mutex m_atomicSync; - - BaseRenderer* m_renderer; - - bool m_isLayerTile; - - // the most recent GL draw before this tile was prepared. used for - // prioritization and caching. tiles with old drawcounts and textures they - // own are used for new tiles and rendering - unsigned long long m_drawCount; - - // Tracks the state of painting for the tile. High level overview: - // 1) Unpainted - until paint starts (and if marked dirty, in most cases) - // 2) PaintingStarted - until paint completes - // 3) TransferredUnvalidated - if transferred first - // or ValidatedUntransferred - if validated first - // 4) ReadyToSwap - if painted and transferred, but not swapped - // 5) UpToDate - until marked dirty again - TextureState m_state; -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) -#endif // BaseTile_h diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp deleted file mode 100644 index f7f9370..0000000 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2010, 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. - */ - -#define LOG_TAG "BaseTileTexture" -#define LOG_NDEBUG 1 - -#include "config.h" -#include "BaseTileTexture.h" - -#include "AndroidLog.h" -#include "BaseTile.h" -#include "ClassTracker.h" -#include "GLUtils.h" -#include "TilesManager.h" - -namespace WebCore { - -BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h) - : m_owner(0) - , m_isPureColor(false) -{ - m_size.set(w, h); - m_ownTextureId = 0; - -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("BaseTileTexture"); -#endif -} - -BaseTileTexture::~BaseTileTexture() -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("BaseTileTexture"); -#endif -} - -void BaseTileTexture::requireGLTexture() -{ - if (!m_ownTextureId) - m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height()); -} - -void BaseTileTexture::discardGLTexture() -{ - if (m_ownTextureId) - GLUtils::deleteTexture(&m_ownTextureId); - - if (m_owner) { - // clear both Tile->Texture and Texture->Tile links - m_owner->removeTexture(this); - release(m_owner); - } -} - -bool BaseTileTexture::acquire(TextureOwner* owner, bool force) -{ - if (m_owner == owner) - return true; - - return setOwner(owner, force); -} - -bool BaseTileTexture::setOwner(TextureOwner* owner, bool force) -{ - bool proceed = true; - if (m_owner && m_owner != owner) - proceed = m_owner->removeTexture(this); - - if (proceed) { - m_owner = owner; - return true; - } - - return false; -} - -bool BaseTileTexture::release(TextureOwner* owner) -{ - ALOGV("texture %p releasing tile %p, m_owner %p", this, owner, m_owner); - if (m_owner != owner) - return false; - - m_owner = 0; - return true; -} - -void BaseTileTexture::transferComplete() -{ - if (m_owner) { - BaseTile* owner = static_cast(m_owner); - owner->backTextureTransfer(); - } else - ALOGE("ERROR: owner missing after transfer of texture %p", this); -} - -void BaseTileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, - const TransformationMatrix* transform) -{ - ShaderProgram* shader = TilesManager::instance()->shader(); - if (isLayer && transform) { - if (isPureColor()) { - shader->drawLayerQuad(*transform, rect, 0, opacity, - true, GL_TEXTURE_2D, pureColor()); - } else { - shader->drawLayerQuad(*transform, rect, m_ownTextureId, - opacity, true); - } - } else { - if (isPureColor()) - shader->drawQuad(rect, 0, opacity, pureColor()); - else - shader->drawQuad(rect, m_ownTextureId, opacity); - } -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h deleted file mode 100644 index d8737b3..0000000 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2010, 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 BaseTileTexture_h -#define BaseTileTexture_h - -#include "GLWebViewState.h" -#include "TextureInfo.h" -#include "TextureOwner.h" -#include "TilePainter.h" -#include -#include - -class SkCanvas; - -namespace WebCore { - -class BaseTile; - -class BaseTileTexture { -public: - // This object is to be constructed on the consumer's thread and must have - // a width and height greater than 0. - BaseTileTexture(uint32_t w, uint32_t h); - virtual ~BaseTileTexture(); - - // allows consumer thread to assign ownership of the texture to the tile. It - // returns false if ownership cannot be transferred because the tile is busy - bool acquire(TextureOwner* owner, bool force = false); - bool release(TextureOwner* owner); - - // set the texture owner if not busy. Return false if busy, true otherwise. - bool setOwner(TextureOwner* owner, bool force = false); - - // private member accessor functions - TextureOwner* owner() { return m_owner; } // only used by the consumer thread - - const SkSize& getSize() const { return m_size; } - - // OpenGL ID of backing texture, 0 when not allocated - GLuint m_ownTextureId; - // these are used for dynamically (de)allocating backing graphics memory - void requireGLTexture(); - void discardGLTexture(); - - void transferComplete(); - - TextureInfo* getTextureInfo() { return &m_ownTextureInfo; } - - // Make sure the following pureColor getter/setter are only read/written - // in UI thread. Therefore no need for a lock. - void setPure(bool pure) { m_isPureColor = pure; } - bool isPureColor() {return m_isPureColor; } - void setPureColor(const Color& color) { m_pureColor = color; setPure(true); } - Color pureColor() { return m_pureColor; } - - void drawGL(bool isLayer, const SkRect& rect, float opacity, - const TransformationMatrix* transform); -private: - TextureInfo m_ownTextureInfo; - SkSize m_size; - SkBitmap::Config m_config; - - // BaseTile owning the texture, only modified by UI thread - TextureOwner* m_owner; - - // When the whole tile is single color, skip the transfer queue and draw - // it directly through shader. - bool m_isPureColor; - Color m_pureColor; -}; - -} // namespace WebCore - -#endif // BaseTileTexture_h diff --git a/Source/WebCore/platform/graphics/android/FixedPositioning.cpp b/Source/WebCore/platform/graphics/android/FixedPositioning.cpp index 989eebd..c7909c4 100644 --- a/Source/WebCore/platform/graphics/android/FixedPositioning.cpp +++ b/Source/WebCore/platform/graphics/android/FixedPositioning.cpp @@ -8,6 +8,7 @@ #include "DumpLayer.h" #include "IFrameLayerAndroid.h" #include "TilesManager.h" +#include "SkCanvas.h" #if USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/GLExtras.cpp b/Source/WebCore/platform/graphics/android/GLExtras.cpp index 1676489..1b283c2 100644 --- a/Source/WebCore/platform/graphics/android/GLExtras.cpp +++ b/Source/WebCore/platform/graphics/android/GLExtras.cpp @@ -32,6 +32,7 @@ #include "DrawExtra.h" #include "GLExtras.h" #include "IntRect.h" +#include "SkPath.h" #include "TilesManager.h" #include "android_graphics.h" diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp index beb62db..1f5a23d 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.cpp +++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp @@ -31,10 +31,14 @@ #if USE(ACCELERATED_COMPOSITING) +#include "AndroidLog.h" +#include "BaseRenderer.h" #include "ShaderProgram.h" +#include "TextureInfo.h" +#include "Tile.h" #include "TilesManager.h" +#include "TransferQueue.h" -#include #include #include #include @@ -385,7 +389,7 @@ GLuint GLUtils::createSampleTexture() return texture; } -GLuint GLUtils::createBaseTileGLTexture(int width, int height) +GLuint GLUtils::createTileGLTexture(int width, int height) { GLuint texture; glGenTextures(1, &texture); @@ -413,7 +417,7 @@ GLuint GLUtils::createBaseTileGLTexture(int width, int height) bool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor) { - // If the bitmap is the pure color, skip the transfer step, and update the BaseTile Info. + // If the bitmap is the pure color, skip the transfer step, and update the Tile Info. // This check is taking < 1ms if we do full bitmap check per tile. // TODO: use the SkPicture to determine whether or not a tile is single color. pureColor = Color(Color::transparent); @@ -456,14 +460,14 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo, const SkBitmap& bitmap) { bool skipTransfer = false; - BaseTile* tilePtr = renderInfo->baseTile; + Tile* tilePtr = renderInfo->baseTile; // TODO: use pure color for partial invals as well if (renderInfo->invalRect) return false; if (tilePtr) { - BaseTileTexture* tileTexture = tilePtr->backTexture(); + TileTexture* tileTexture = tilePtr->backTexture(); // Check the bitmap, and make everything ready here. if (tileTexture && renderInfo->isPureColor) { // update basetile's info diff --git a/Source/WebCore/platform/graphics/android/GLUtils.h b/Source/WebCore/platform/graphics/android/GLUtils.h index f24ea0d..d4a2e84 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.h +++ b/Source/WebCore/platform/graphics/android/GLUtils.h @@ -31,8 +31,6 @@ #include "Color.h" #include "SkBitmap.h" #include "SkMatrix.h" -#include "SkSize.h" -#include "TextureInfo.h" #include "TransformationMatrix.h" #include #include @@ -47,6 +45,8 @@ class SurfaceTexture; namespace WebCore { +class TileRenderInfo; + class GLUtils { public: @@ -71,7 +71,7 @@ public: static void deleteTexture(GLuint* texture); static GLuint createSampleColorTexture(int r, int g, int b); static GLuint createSampleTexture(); - static GLuint createBaseTileGLTexture(int width, int height); + static GLuint createTileGLTexture(int width, int height); static void createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter = GL_LINEAR); static void updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, const IntRect&, GLint filter = GL_LINEAR); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 4c4ca3d..99eb1c6 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -41,16 +41,12 @@ #include "ScrollableLayerAndroid.h" #include "SkPath.h" #include "TilesManager.h" +#include "TransferQueue.h" #include "SurfaceCollection.h" #include "SurfaceCollectionManager.h" #include #include -#define FIRST_TILED_PAGE_ID 1 -#define SECOND_TILED_PAGE_ID 2 - -#define FRAMERATE_CAP 0.01666 // We cap at 60 fps - // log warnings if scale goes outside this range #define MIN_SCALE_WARNING 0.1 #define MAX_SCALE_WARNING 10 @@ -329,10 +325,10 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) ALOGW("WARNING, scale seems corrupted before update: %e", scale); - // Here before we draw, update the BaseTile which has updated content. + // Here before we draw, update the Tile which has updated content. // Inside this function, just do GPU blits from the transfer queue into - // the BaseTiles' texture. - tilesManager->transferQueue()->updateDirtyBaseTiles(); + // the Tiles' texture. + tilesManager->transferQueue()->updateDirtyTiles(); // Upload any pending ImageTexture // Return true if we still have some images to upload. diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h index 82ef16e..6d969dd 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.h +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h @@ -93,7 +93,7 @@ class TexturesResult; // there is a need to be called again (i.e. if we do not have up to date // textures or a transition is going on). // -// Tiles are implemented as a BaseTile. It knows how to paint itself with the +// Tiles are implemented as a Tile. It knows how to paint itself with the // PictureSet, and to display itself. A GL texture is usually associated to it. // // We also works with two TiledPages -- one to display the page at the @@ -107,13 +107,13 @@ class TexturesResult; // Texture allocation // ------------------ // -// Obviously we cannot have every BaseTile having a GL texture -- we need to +// Obviously we cannot have every Tile having a GL texture -- we need to // get the GL textures from an existing pool, and reuse them. // // The way we do it is that when we call TiledPage::prepare(), we group the // tiles we need (i.e. in the viewport and dirty) into a TilesSet and call -// BaseTile::reserveTexture() for each tile (which ensures there is a specific -// GL textures backing the BaseTiles). +// Tile::reserveTexture() for each tile (which ensures there is a specific +// GL textures backing the Tiles). // // reserveTexture() will ask the TilesManager for a texture. The allocation // mechanism goal is to (in order): @@ -125,7 +125,7 @@ class TexturesResult; // we prepare() a TiledPage. Also during each prepare() we compute which tiles // are dirty based on the info we have received from webkit. // -// BaseTile Invalidation +// Tile Invalidation // ------------------ // // We do not want to redraw a tile if the tile is up-to-date. A tile is @@ -149,9 +149,9 @@ class TexturesResult; // // The next operation is to schedule this TilesSet to be painted // (TilesManager::schedulePaintForTilesSet()). TexturesGenerator -// will get the TilesSet and ask the BaseTiles in it to be painted. +// will get the TilesSet and ask the Tiles in it to be painted. // -// BaseTile::paintBitmap() will paint the texture using the BaseLayer's +// Tile::paintBitmap() will paint the texture using the BaseLayer's // PictureSet (calling TiledPage::paintBaseLayerContent() which in turns // calls GLWebViewState::paintBaseLayerContent()). // diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.cpp b/Source/WebCore/platform/graphics/android/GaneshContext.cpp index 620fccf..bf43652 100644 --- a/Source/WebCore/platform/graphics/android/GaneshContext.cpp +++ b/Source/WebCore/platform/graphics/android/GaneshContext.cpp @@ -31,6 +31,9 @@ #include "AndroidLog.h" #include "GLUtils.h" +#include "TextureInfo.h" +#include "TilesManager.h" +#include "TransferQueue.h" #include "android/native_window.h" @@ -40,7 +43,7 @@ namespace WebCore { GaneshContext::GaneshContext() : m_grContext(0) - , m_baseTileDeviceSurface(0) + , m_tileDeviceSurface(0) , m_surfaceConfig(0) , m_surfaceContext(EGL_NO_CONTEXT) { @@ -69,7 +72,7 @@ void GaneshContext::flush() m_grContext->flush(); } -SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo) +SkDevice* GaneshContext::getDeviceForTile(const TileRenderInfo& renderInfo) { // Ganesh should be the only code in the rendering thread that is using GL // and setting the EGLContext. If this is not the case then we need to @@ -146,7 +149,7 @@ SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo) GLUtils::checkEglError("eglMakeCurrent", returnValue); ALOGV("eglMakeCurrent"); - if (!m_baseTileDeviceSurface) { + if (!m_tileDeviceSurface) { GrPlatformRenderTargetDesc renderTargetDesc; renderTargetDesc.fWidth = TilesManager::tileWidth(); @@ -159,19 +162,19 @@ SkDevice* GaneshContext::getDeviceForBaseTile(const TileRenderInfo& renderInfo) GrContext* grContext = getGrContext(); GrRenderTarget* renderTarget = grContext->createPlatformRenderTarget(renderTargetDesc); - m_baseTileDeviceSurface = new SkGpuDevice(grContext, renderTarget); + m_tileDeviceSurface = new SkGpuDevice(grContext, renderTarget); renderTarget->unref(); - ALOGV("generated device %p", m_baseTileDeviceSurface); + ALOGV("generated device %p", m_tileDeviceSurface); } - GLUtils::checkGlError("getDeviceForBaseTile"); + GLUtils::checkGlError("getDeviceForTile"); // We must reset the Ganesh context only after we are sure we have // re-established our EGLContext as the current context. - if (m_baseTileDeviceSurface && contextNeedsReset) + if (m_tileDeviceSurface && contextNeedsReset) getGrContext()->resetContext(); - return m_baseTileDeviceSurface; + return m_tileDeviceSurface; } diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.h b/Source/WebCore/platform/graphics/android/GaneshContext.h index def35e5..57e8e19 100644 --- a/Source/WebCore/platform/graphics/android/GaneshContext.h +++ b/Source/WebCore/platform/graphics/android/GaneshContext.h @@ -31,7 +31,7 @@ #include "BaseRenderer.h" #include "GrContext.h" #include "SkGpuDevice.h" -#include "TilesManager.h" +#include namespace WebCore { @@ -39,7 +39,7 @@ class GaneshContext { public: static GaneshContext* instance(); - SkDevice* getDeviceForBaseTile(const TileRenderInfo& renderInfo); + SkDevice* getDeviceForTile(const TileRenderInfo& renderInfo); void flush(); @@ -50,7 +50,7 @@ private: GrContext* getGrContext(); GrContext* m_grContext; - SkGpuDevice* m_baseTileDeviceSurface; + SkGpuDevice* m_tileDeviceSurface; EGLConfig m_surfaceConfig; EGLContext m_surfaceContext; diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp index 559af1f..208adb6 100644 --- a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp @@ -36,6 +36,7 @@ #include "SkCanvas.h" #include "SkGpuDevice.h" #include "TilesManager.h" +#include "TransferQueue.h" namespace WebCore { @@ -71,7 +72,7 @@ void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can SkDevice* device = NULL; if (renderInfo.tileSize.width() == TilesManager::tileWidth() && renderInfo.tileSize.height() == TilesManager::tileHeight()) { - device = ganesh->getDeviceForBaseTile(renderInfo); + device = ganesh->getDeviceForTile(renderInfo); } else { // TODO support arbitrary sizes for layers ALOGV("ERROR: expected (%d,%d) actual (%d,%d)", diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index fa620e0..d62f88b 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -34,6 +34,7 @@ #include "Image.h" #include "ImagesManager.h" #include "Layer.h" +#include "LayerAndroid.h" #include "Length.h" #include "MediaLayer.h" #include "PictureLayerContent.h" diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 27dfde2..97f974e 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -23,7 +23,6 @@ #include "Frame.h" #include "GraphicsLayer.h" #include "GraphicsLayerClient.h" -#include "LayerAndroid.h" #include "LayerContent.h" #include "RefPtr.h" #include "ScrollableLayerAndroid.h" @@ -37,6 +36,7 @@ class SkRegion; namespace WebCore { +class LayerAndroid; class ScrollableLayerAndroid; class GraphicsLayerAndroid : public GraphicsLayer { diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp index 7d3f2b8..b2ead6a 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp +++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp @@ -30,12 +30,13 @@ #include "ImageTexture.h" #include "AndroidLog.h" +#include "ClassTracker.h" #include "ImagesManager.h" #include "LayerAndroid.h" #include "SkDevice.h" #include "SkPicture.h" +#include "TileGrid.h" #include "TilesManager.h" -#include "TiledTexture.h" namespace WebCore { @@ -84,7 +85,7 @@ ImageTexture::ImageTexture(SkBitmap* bmp, unsigned crc) // NOTE: This constructor is called on the webcore thread - // Create a picture containing the image (needed for TiledTexture) + // Create a picture containing the image (needed for TileGrid) m_picture = new SkPicture(); SkCanvas* pcanvas = m_picture->beginRecording(m_image->width(), m_image->height()); pcanvas->clear(SkColorSetARGBInline(0, 0, 0, 0)); @@ -174,7 +175,7 @@ bool ImageTexture::prepareGL(GLWebViewState* state) if (!m_texture && m_picture) { bool isLayerTile = true; - m_texture = new TiledTexture(isLayerTile); + m_texture = new TileGrid(isLayerTile); SkRegion region; region.setRect(0, 0, m_image->width(), m_image->height()); m_texture->markAsDirty(region); @@ -216,7 +217,7 @@ float ImageTexture::opacity() return m_layer->drawOpacity(); } -bool ImageTexture::paint(BaseTile* tile, SkCanvas* canvas) +bool ImageTexture::paint(Tile* tile, SkCanvas* canvas) { if (!m_picture) { ALOGV("IT %p COULDNT PAINT, NO PICTURE", this); @@ -236,7 +237,7 @@ void ImageTexture::drawGL(LayerAndroid* layer, float opacity) if (!hasContentToShow()) return; - // TiledTexture::draw() will call us back to know the + // TileGrid::draw() will call us back to know the // transform and opacity, so we need to set m_layer m_layer = layer; if (m_texture) { diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h index 91c8a29..34430f1 100644 --- a/Source/WebCore/platform/graphics/android/ImageTexture.h +++ b/Source/WebCore/platform/graphics/android/ImageTexture.h @@ -31,13 +31,14 @@ #include "SkBitmapRef.h" #include "SkPicture.h" #include "SkRefCnt.h" -#include "LayerAndroid.h" +#include "TilePainter.h" namespace WebCore { +class GLWebViewState; class LayerAndroid; class TexturesResult; -class TiledTexture; +class TileGrid; ///////////////////////////////////////////////////////////////////////////////// // Image sharing codepath for layers @@ -63,7 +64,7 @@ class TiledTexture; // ImageTexture at draw time. // // ImageTexture recopy the original SkBitmap so that they can safely be used -// on a different thread; it uses TiledTexture to allocate and paint the image, +// on a different thread; it uses TileGrid to allocate and paint the image, // so that we can share the same textures and limits as the rest of the layers. // ///////////////////////////////////////////////////////////////////////////////// @@ -84,8 +85,8 @@ public: static unsigned computeCRC(const SkBitmap* bitmap); bool equalsCRC(unsigned crc); - // methods used by TiledTexture - virtual bool paint(BaseTile* tile, SkCanvas* canvas); + // methods used by TileGrid + virtual bool paint(Tile* tile, SkCanvas* canvas); virtual float opacity(); int nbTextures(); @@ -97,7 +98,7 @@ private: SkBitmapRef* m_imageRef; SkBitmap* m_image; - TiledTexture* m_texture; + TileGrid* m_texture; LayerAndroid* m_layer; SkPicture* m_picture; TransformationMatrix m_layerMatrix; diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index b40e00a..df3fa42 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -13,10 +13,10 @@ #include "DumpLayer.h" #include "FixedPositioning.h" #include "GLUtils.h" +#include "GLWebViewState.h" #include "ImagesManager.h" #include "InspectorCanvas.h" #include "LayerContent.h" -#include "LayerGroup.h" #include "MediaLayer.h" #include "ParseCanvas.h" #include "PictureLayerContent.h" @@ -24,6 +24,7 @@ #include "SkDrawFilter.h" #include "SkPaint.h" #include "SkPicture.h" +#include "Surface.h" #include "TilesManager.h" #include @@ -33,8 +34,8 @@ #define DISABLE_LAYER_MERGE #undef DISABLE_LAYER_MERGE -#define LAYER_GROUPING_DEBUG -#undef LAYER_GROUPING_DEBUG +#define LAYER_MERGING_DEBUG +#undef LAYER_MERGING_DEBUG namespace WebCore { @@ -70,7 +71,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_owningLayer(owner), m_type(LayerAndroid::WebCoreLayer), m_intrinsicallyComposited(true), - m_layerGroup(0) + m_surface(0) { m_backgroundColor = 0; @@ -91,7 +92,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_owningLayer(layer.m_owningLayer), m_type(LayerAndroid::UILayer), m_intrinsicallyComposited(layer.m_intrinsicallyComposited), - m_layerGroup(0) + m_surface(0) { m_imageCRC = layer.m_imageCRC; if (m_imageCRC) @@ -177,7 +178,7 @@ LayerAndroid::~LayerAndroid() delete m_fixedPosition; SkSafeUnref(m_content); - // Don't unref m_layerGroup, owned by BaseLayerAndroid + // Don't unref m_surface, owned by BaseLayerAndroid m_animations.clear(); #ifdef DEBUG_COUNT ClassTracker::instance()->remove(this); @@ -658,16 +659,16 @@ static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b) return a->zValue() > b->zValue(); } -bool LayerAndroid::canJoinGroup(LayerGroup* group) +bool LayerAndroid::canJoinSurface(Surface* surface) { #ifdef DISABLE_LAYER_MERGE return false; #else - // returns true if the layer can be merged onto the layergroup - if (!group) + // returns true if the layer can be merged onto the surface (group of layers) + if (!surface) return false; - LayerAndroid* lastLayer = group->getFirstLayer(); + LayerAndroid* lastLayer = surface->getFirstLayer(); // isolate non-tiled layers // TODO: remove this check so that multiple tiled layers with a invisible @@ -689,9 +690,9 @@ bool LayerAndroid::canJoinGroup(LayerGroup* group) || !lastLayer->m_drawTransform.isIdentityOrTranslation()) return false; - // 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_content->hasText() != group->hasText()) + // currently, we don't surface zoomable with non-zoomable layers (unless the + // surface or the layer doesn't need a texture) + if (surface->needsTexture() && needsTexture() && m_content->hasText() != surface->hasText()) return false; // TODO: compare other layer properties - fixed? overscroll? transformed? @@ -699,31 +700,31 @@ bool LayerAndroid::canJoinGroup(LayerGroup* group) #endif } -void LayerAndroid::assignGroups(LayerMergeState* mergeState) +void LayerAndroid::assignSurfaces(LayerMergeState* mergeState) { // recurse through layers in draw order, and merge layers when able - bool needNewGroup = !mergeState->currentLayerGroup + bool needNewSurface = !mergeState->currentSurface || mergeState->nonMergeNestedLevel > 0 - || !canJoinGroup(mergeState->currentLayerGroup); + || !canJoinSurface(mergeState->currentSurface); - if (needNewGroup) { - mergeState->currentLayerGroup = new LayerGroup(); - mergeState->groupList->append(mergeState->currentLayerGroup); + if (needNewSurface) { + mergeState->currentSurface = new Surface(); + mergeState->surfaceList->append(mergeState->currentSurface); } -#ifdef LAYER_GROUPING_DEBUG - ALOGD("%*slayer %p(%d) rl %p %s group %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d", +#ifdef LAYER_MERGING_DEBUG + ALOGD("%*slayer %p(%d) rl %p %s surface %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d", 4*mergeState->depth, "", this, m_uniqueId, m_owningLayer, - needNewGroup ? "NEW" : "joins", mergeState->currentLayerGroup, + needNewSurface ? "NEW" : "joins", mergeState->currentSurface, isPositionFixed(), m_animations.size() != 0, m_intrinsicallyComposited, m_haveClip, contentIsScrollable()); #endif - mergeState->currentLayerGroup->addLayer(this, m_drawTransform); - m_layerGroup = mergeState->currentLayerGroup; + mergeState->currentSurface->addLayer(this, m_drawTransform); + m_surface = mergeState->currentSurface; if (m_haveClip || contentIsScrollable() || isPositionFixed()) { // disable layer merging within the children of these layer types @@ -731,7 +732,7 @@ void LayerAndroid::assignGroups(LayerMergeState* mergeState) } - // pass the layergroup through children in drawing order, so that they may + // pass the surface 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(); @@ -744,7 +745,7 @@ void LayerAndroid::assignGroups(LayerMergeState* mergeState) // sort for the transparency std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ); for (int i = 0; i < count; i++) - sublayers[i]->assignGroups(mergeState); + sublayers[i]->assignSurfaces(mergeState); mergeState->depth--; } @@ -752,8 +753,8 @@ void LayerAndroid::assignGroups(LayerMergeState* mergeState) // re-enable joining mergeState->nonMergeNestedLevel--; - // disallow layers painting after to join with this group - mergeState->currentLayerGroup = 0; + // disallow layers painting after to join with this surface + mergeState->currentSurface = 0; } } diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index c7028c5..6239418 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -25,6 +25,7 @@ #include "GraphicsLayerClient.h" #include "ImageTexture.h" #include "Layer.h" +#include "PlatformString.h" #include "RefPtr.h" #include "SkBitmap.h" #include "SkColor.h" @@ -32,6 +33,7 @@ #include "SkStream.h" #include "TransformationMatrix.h" +#include #include #ifndef BZERO_DEFINED @@ -49,8 +51,8 @@ class SkPicture; namespace WebCore { class LayerAndroid; class LayerContent; -class LayerGroup; class ImageTexture; +class Surface; } namespace android { @@ -65,7 +67,6 @@ using namespace android; namespace WebCore { class AndroidAnimation; -class BaseTileTexture; class FixedPositioning; class GLWebViewState; class IFrameLayerAndroid; @@ -273,9 +274,9 @@ public: SkRegion* getInvalRegion() { return &m_dirtyRegion; } void mergeInvalsInto(LayerAndroid* replacementTree); - bool canJoinGroup(LayerGroup* group); - void assignGroups(LayerMergeState* mergeState); - LayerGroup* group() { return m_layerGroup; } + bool canJoinSurface(Surface* surface); + void assignSurfaces(LayerMergeState* mergeState); + Surface* surface() { return m_surface; } void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; } @@ -360,7 +361,7 @@ private: bool m_intrinsicallyComposited; - LayerGroup* m_layerGroup; + Surface* m_surface; typedef Layer INHERITED; }; diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/LayerGroup.cpp deleted file mode 100644 index 05180a4..0000000 --- a/Source/WebCore/platform/graphics/android/LayerGroup.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/* - * 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. - */ - -#define LOG_TAG "LayerGroup" -#define LOG_NDEBUG 1 - -#include "config.h" -#include "LayerGroup.h" - -#include "AndroidLog.h" -#include "ClassTracker.h" -#include "LayerAndroid.h" -#include "TiledTexture.h" -#include "TilesManager.h" - -// LayerGroups with an area larger than 2048*2048 should never be unclipped -#define MAX_UNCLIPPED_AREA 4194304 - -namespace WebCore { - -LayerGroup::LayerGroup() - : m_dualTiledTexture(0) - , m_needsTexture(false) - , m_hasText(false) -{ -#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 -} - -bool LayerGroup::tryUpdateLayerGroup(LayerGroup* oldLayerGroup) -{ - if (!needsTexture() || !oldLayerGroup->needsTexture()) - return false; - - // merge layer group based on first layer ID - if (getFirstLayer()->uniqueId() != oldLayerGroup->getFirstLayer()->uniqueId()) - return false; - - m_dualTiledTexture = oldLayerGroup->m_dualTiledTexture; - SkSafeRef(m_dualTiledTexture); - - ALOGV("%p taking old DTT %p from group %p, nt %d", - this, m_dualTiledTexture, oldLayerGroup, oldLayerGroup->needsTexture()); - - if (!m_dualTiledTexture) { - // no DTT to inval, so don't worry about it. - return true; - } - - if (singleLayer() && oldLayerGroup->singleLayer()) { - // both are single matching layers, simply apply inval - SkRegion* layerInval = getFirstLayer()->getInvalRegion(); - m_dualTiledTexture->markAsDirty(*layerInval); - } else { - SkRegion invalRegion; - 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; - } - } - } - - if (fullInval) - invalRegion.setRect(-1e8, -1e8, 2e8, 2e8); - - m_dualTiledTexture->markAsDirty(invalRegion); - } - return true; -} - -void LayerGroup::addLayer(LayerAndroid* layer, const TransformationMatrix& transform) -{ - m_layers.append(layer); - SkSafeRef(layer); - - m_needsTexture |= layer->needsTexture(); - m_hasText |= layer->hasText(); - - // calculate area size for comparison later - IntRect rect = layer->unclippedArea(); - SkPoint pos = layer->getPosition(); - rect.setLocation(IntPoint(pos.fX, pos.fY)); - - if (layer->needsTexture()) { - if (m_unclippedArea.isEmpty()) { - m_drawTransform = transform; - m_drawTransform.translate3d(-pos.fX, -pos.fY, 0); - m_unclippedArea = rect; - } else - m_unclippedArea.unite(rect); - ALOGV("LG %p adding LA %p, size %d, %d %dx%d, now LG size %d,%d %dx%d", - this, layer, rect.x(), rect.y(), rect.width(), rect.height(), - m_unclippedArea.x(), m_unclippedArea.y(), - m_unclippedArea.width(), m_unclippedArea.height()); - } -} - -IntRect LayerGroup::visibleArea() -{ - if (singleLayer()) - return getFirstLayer()->visibleArea(); - - IntRect rect = m_unclippedArea; - - // clip with the viewport in documents coordinate - IntRect documentViewport(TilesManager::instance()->shader()->documentViewport()); - rect.intersect(documentViewport); - - // TODO: handle recursive layer clip - - return rect; -} - -IntRect LayerGroup::unclippedArea() -{ - if (singleLayer()) - return getFirstLayer()->unclippedArea(); - return m_unclippedArea; -} - -bool LayerGroup::useAggressiveRendering() -{ - // When the background is translucent, 0 < alpha < 255, we had to turn off - // low res to avoid artifacts from double drawing. - // TODO: avoid double drawing for low res tiles. - return isBase() - && (!m_background.alpha() - || !m_background.hasAlpha()); -} - -void LayerGroup::prepareGL(bool layerTilesDisabled) -{ - bool tilesDisabled = layerTilesDisabled && !isBase(); - if (!m_dualTiledTexture) { - ALOGV("prepareGL on LG %p, no DTT, needsTexture? %d", - this, m_dualTiledTexture, needsTexture()); - - if (!needsTexture()) - return; - - m_dualTiledTexture = new DualTiledTexture(isBase()); - } - - if (tilesDisabled) { - m_dualTiledTexture->discardTextures(); - } else { - bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors - IntRect prepareArea = computePrepareArea(); - IntRect fullArea = unclippedArea(); - - ALOGV("prepareGL on LG %p with DTT %p, %d layers", - this, m_dualTiledTexture, m_layers.size()); - - m_dualTiledTexture->prepareGL(getFirstLayer()->state(), allowZoom, - prepareArea, fullArea, - this, useAggressiveRendering()); - } -} - -bool LayerGroup::drawGL(bool layerTilesDisabled) -{ - bool tilesDisabled = layerTilesDisabled && !isBase(); - if (!getFirstLayer()->visible()) - return false; - - if (!isBase()) { - // TODO: why are clipping regions wrong for base layer? - FloatRect drawClip = getFirstLayer()->drawClip(); - FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip); - TilesManager::instance()->shader()->clip(clippingRect); - } - - bool askRedraw = false; - if (m_dualTiledTexture && !tilesDisabled) { - ALOGV("drawGL on LG %p with DTT %p", this, m_dualTiledTexture); - - // TODO: why this visibleArea is different from visibleRect at zooming for base? - IntRect drawArea = visibleArea(); - m_dualTiledTexture->drawGL(drawArea, opacity(), drawTransform(), - useAggressiveRendering(), background()); - } - - // draw member layers (draws image textures, glextras) - for (unsigned int i = 0; i < m_layers.size(); i++) - askRedraw |= m_layers[i]->drawGL(tilesDisabled); - - 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 (!getFirstLayer()->contentIsScrollable() - && !isBase() - && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { - - area = unclippedArea(); - - double total = ((double) area.width()) * ((double) area.height()); - if (total > MAX_UNCLIPPED_AREA) - area = visibleArea(); - } else { - area = visibleArea(); - } - - return area; -} - -void LayerGroup::computeTexturesAmount(TexturesResult* result) -{ - if (!m_dualTiledTexture || isBase()) - return; - - m_dualTiledTexture->computeTexturesAmount(result, getFirstLayer()); -} - -bool LayerGroup::isBase() -{ - // base layer group - // - doesn't use layer tiles (disables blending, doesn't compute textures amount) - // - ignores clip rects - // - only prepares clippedArea - return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer; -} - -bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas) -{ - if (singleLayer()) { - getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers); - - // TODO: double buffer by disabling SurfaceCollection swaps and position - // updates until painting complete - - // In single surface mode, draw layer content onto the base layer - if (isBase() - && getFirstLayer()->countChildren() - && getFirstLayer()->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) - getFirstLayer()->getChild(0)->drawCanvas(canvas, true, Layer::FlattenedLayers); - } else { - SkAutoCanvasRestore acr(canvas, true); - SkMatrix matrix; - GLUtils::toSkMatrix(matrix, m_drawTransform); - - SkMatrix inverse; - inverse.reset(); - matrix.invert(&inverse); - - SkMatrix canvasMatrix = canvas->getTotalMatrix(); - inverse.postConcat(canvasMatrix); - canvas->setMatrix(inverse); - - for (unsigned int i=0; idrawCanvas(canvas, false, Layer::MergedLayers); - } - return true; -} - -float LayerGroup::opacity() -{ - if (singleLayer()) - return getFirstLayer()->drawOpacity(); - return 1.0; -} - -Color* LayerGroup::background() -{ - if (!isBase() || !m_background.isValid()) - return 0; - return &m_background; -} - -const TransformationMatrix* LayerGroup::drawTransform() -{ - // single layer groups query the layer's draw transform, while multi-layer - // groups copy the draw transform once, during initialization - // TODO: support fixed multi-layer groups by querying the changing drawTransform - if (singleLayer()) - return getFirstLayer()->drawTransform(); - - return &m_drawTransform; -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.h b/Source/WebCore/platform/graphics/android/LayerGroup.h deleted file mode 100644 index 8e9608d..0000000 --- a/Source/WebCore/platform/graphics/android/LayerGroup.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LayerGroup_h -#define LayerGroup_h - -#include "Color.h" -#include "IntRect.h" -#include "TilePainter.h" -#include "Vector.h" - -class SkCanvas; -class SkRegion; - -namespace WebCore { - -class BaseTile; -class DualTiledTexture; -class LayerAndroid; -class TexturesResult; - -class LayerGroup : public TilePainter { -public: - LayerGroup(); - virtual ~LayerGroup(); - - bool tryUpdateLayerGroup(LayerGroup* oldLayerGroup); - - void addLayer(LayerAndroid* layer, const TransformationMatrix& transform); - void prepareGL(bool layerTilesDisabled); - bool drawGL(bool layerTilesDisabled); - void swapTiles(); - bool isReady(); - - void computeTexturesAmount(TexturesResult* result); - - LayerAndroid* getFirstLayer() { return m_layers[0]; } - bool needsTexture() { return m_needsTexture; } - bool hasText() { return m_hasText; } - bool isBase(); - void setBackground(Color background) { m_background = background; } - - // TilePainter methods - virtual bool paint(BaseTile* tile, SkCanvas* canvas); - virtual float opacity(); - virtual Color* background(); - -private: - IntRect computePrepareArea(); - IntRect visibleArea(); - IntRect unclippedArea(); - bool singleLayer() { return m_layers.size() == 1; } - void updateBackground(const Color& background); - bool useAggressiveRendering(); - - const TransformationMatrix* drawTransform(); - IntRect m_unclippedArea; - TransformationMatrix m_drawTransform; - - DualTiledTexture* m_dualTiledTexture; - bool m_needsTexture; - bool m_hasText; - Vector m_layers; - - Color m_background; -}; - -class LayerMergeState { -public: - LayerMergeState(Vector* const allGroups) - : groupList(allGroups) - , currentLayerGroup(0) - , nonMergeNestedLevel(-1) // start at -1 to ignore first LayerAndroid's clipping - , depth(0) - {} - - // vector storing all generated layer groups - Vector* const groupList; - - // currently merging group. if cleared, no more layers may join - LayerGroup* currentLayerGroup; - - // records depth within non-mergeable parents (clipping, fixed, scrolling) - // and disable merging therein. - int nonMergeNestedLevel; - - // counts layer tree depth for debugging - int depth; -}; - -} // namespace WebCore - -#endif //#define LayerGroup_h diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp index 4ae1f31..b5e435b 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp @@ -30,6 +30,7 @@ #include "PaintTileOperation.h" #include "AndroidLog.h" +#include "GLWebViewState.h" #include "ImageTexture.h" #include "ImagesManager.h" #include "LayerAndroid.h" @@ -37,7 +38,7 @@ namespace WebCore { -PaintTileOperation::PaintTileOperation(BaseTile* tile, TilePainter* painter, +PaintTileOperation::PaintTileOperation(Tile* tile, TilePainter* painter, GLWebViewState* state, bool isLowResPrefetch) : m_tile(tile) , m_painter(painter) diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/PaintTileOperation.h index afd2fc1..1d376bf 100644 --- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h +++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h @@ -26,7 +26,7 @@ #ifndef PaintTileSetOperation_h #define PaintTileSetOperation_h -#include "BaseTile.h" +#include "Tile.h" #include "QueuedOperation.h" #include "SkRefCnt.h" @@ -38,7 +38,7 @@ class ImageTexture; class PaintTileOperation : public QueuedOperation { public: - PaintTileOperation(BaseTile* tile, TilePainter* painter, + PaintTileOperation(Tile* tile, TilePainter* painter, GLWebViewState* state, bool isLowResPrefetch); virtual ~PaintTileOperation(); virtual bool operator==(const QueuedOperation* operation); @@ -49,7 +49,7 @@ public: float scale() { return m_tile->scale(); } private: - BaseTile* m_tile; + Tile* m_tile; TilePainter* m_painter; GLWebViewState* m_state; bool m_isLowResPrefetch; diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp index a012c8b..b880eef 100644 --- a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp +++ b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp @@ -37,6 +37,7 @@ #include "SkBitmapRef.h" #include "SkCanvas.h" #include "SkDevice.h" +#include "Tile.h" #include "TilesManager.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/android/Surface.cpp b/Source/WebCore/platform/graphics/android/Surface.cpp new file mode 100644 index 0000000..e6d12c1 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/Surface.cpp @@ -0,0 +1,346 @@ +/* + * 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. + */ + +#define LOG_TAG "Surface" +#define LOG_NDEBUG 1 + +#include "config.h" +#include "Surface.h" + +#include "AndroidLog.h" +#include "ClassTracker.h" +#include "LayerAndroid.h" +#include "GLWebViewState.h" +#include "SkCanvas.h" +#include "SurfaceBacking.h" +#include "TilesManager.h" + +// Surfaces with an area larger than 2048*2048 should never be unclipped +#define MAX_UNCLIPPED_AREA 4194304 + +namespace WebCore { + +Surface::Surface() + : m_surfaceBacking(0) + , m_needsTexture(false) + , m_hasText(false) +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("Surface"); +#endif +} + +Surface::~Surface() +{ + for (unsigned int i = 0; i < m_layers.size(); i++) + SkSafeUnref(m_layers[i]); + if (m_surfaceBacking) + SkSafeUnref(m_surfaceBacking); +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("Surface"); +#endif +} + +bool Surface::tryUpdateSurface(Surface* oldSurface) +{ + if (!needsTexture() || !oldSurface->needsTexture()) + return false; + + // merge surfaces based on first layer ID + if (getFirstLayer()->uniqueId() != oldSurface->getFirstLayer()->uniqueId()) + return false; + + m_surfaceBacking = oldSurface->m_surfaceBacking; + SkSafeRef(m_surfaceBacking); + + ALOGV("%p taking old SurfBack %p from surface %p, nt %d", + this, m_surfaceBacking, oldSurface, oldSurface->needsTexture()); + + if (!m_surfaceBacking) { + // no SurfBack to inval, so don't worry about it. + return true; + } + + if (singleLayer() && oldSurface->singleLayer()) { + // both are single matching layers, simply apply inval + SkRegion* layerInval = getFirstLayer()->getInvalRegion(); + m_surfaceBacking->markAsDirty(*layerInval); + } else { + SkRegion invalRegion; + bool fullInval = m_layers.size() != oldSurface->m_layers.size(); + if (!fullInval) { + for (unsigned int i = 0; i < m_layers.size(); i++) { + if (m_layers[i]->uniqueId() != oldSurface->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 surface 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; + } + } + } + + if (fullInval) + invalRegion.setRect(-1e8, -1e8, 2e8, 2e8); + + m_surfaceBacking->markAsDirty(invalRegion); + } + return true; +} + +void Surface::addLayer(LayerAndroid* layer, const TransformationMatrix& transform) +{ + m_layers.append(layer); + SkSafeRef(layer); + + m_needsTexture |= layer->needsTexture(); + m_hasText |= layer->hasText(); + + // calculate area size for comparison later + IntRect rect = layer->unclippedArea(); + SkPoint pos = layer->getPosition(); + rect.setLocation(IntPoint(pos.fX, pos.fY)); + + if (layer->needsTexture()) { + if (m_unclippedArea.isEmpty()) { + m_drawTransform = transform; + m_drawTransform.translate3d(-pos.fX, -pos.fY, 0); + m_unclippedArea = rect; + } else + m_unclippedArea.unite(rect); + ALOGV("Surf %p adding LA %p, size %d, %d %dx%d, now Surf size %d,%d %dx%d", + this, layer, rect.x(), rect.y(), rect.width(), rect.height(), + m_unclippedArea.x(), m_unclippedArea.y(), + m_unclippedArea.width(), m_unclippedArea.height()); + } +} + +IntRect Surface::visibleArea() +{ + if (singleLayer()) + return getFirstLayer()->visibleArea(); + + IntRect rect = m_unclippedArea; + + // clip with the viewport in documents coordinate + IntRect documentViewport(TilesManager::instance()->shader()->documentViewport()); + rect.intersect(documentViewport); + + // TODO: handle recursive layer clip + + return rect; +} + +IntRect Surface::unclippedArea() +{ + if (singleLayer()) + return getFirstLayer()->unclippedArea(); + return m_unclippedArea; +} + +bool Surface::useAggressiveRendering() +{ + // When the background is translucent, 0 < alpha < 255, we had to turn off + // low res to avoid artifacts from double drawing. + // TODO: avoid double drawing for low res tiles. + return isBase() + && (!m_background.alpha() + || !m_background.hasAlpha()); +} + +void Surface::prepareGL(bool layerTilesDisabled) +{ + bool tilesDisabled = layerTilesDisabled && !isBase(); + if (!m_surfaceBacking) { + ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d", + this, m_surfaceBacking, needsTexture()); + + if (!needsTexture()) + return; + + m_surfaceBacking = new SurfaceBacking(isBase()); + } + + if (tilesDisabled) { + m_surfaceBacking->discardTextures(); + } else { + bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors + IntRect prepareArea = computePrepareArea(); + IntRect fullArea = unclippedArea(); + + ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers", + this, m_surfaceBacking, m_layers.size()); + + m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom, + prepareArea, fullArea, + this, useAggressiveRendering()); + } +} + +bool Surface::drawGL(bool layerTilesDisabled) +{ + bool tilesDisabled = layerTilesDisabled && !isBase(); + if (!getFirstLayer()->visible()) + return false; + + if (!isBase()) { + // TODO: why are clipping regions wrong for base layer? + FloatRect drawClip = getFirstLayer()->drawClip(); + FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip); + TilesManager::instance()->shader()->clip(clippingRect); + } + + bool askRedraw = false; + if (m_surfaceBacking && !tilesDisabled) { + ALOGV("drawGL on Surf %p with SurfBack %p", this, m_surfaceBacking); + + // TODO: why this visibleArea is different from visibleRect at zooming for base? + IntRect drawArea = visibleArea(); + m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), + useAggressiveRendering(), background()); + } + + // draw member layers (draws image textures, glextras) + for (unsigned int i = 0; i < m_layers.size(); i++) + askRedraw |= m_layers[i]->drawGL(tilesDisabled); + + return askRedraw; +} + +void Surface::swapTiles() +{ + if (!m_surfaceBacking) + return; + + m_surfaceBacking->swapTiles(); +} + +bool Surface::isReady() +{ + if (!m_surfaceBacking) + return true; + + return m_surfaceBacking->isReady(); +} + +IntRect Surface::computePrepareArea() { + IntRect area; + + if (!getFirstLayer()->contentIsScrollable() + && !isBase() + && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { + + area = unclippedArea(); + + double total = ((double) area.width()) * ((double) area.height()); + if (total > MAX_UNCLIPPED_AREA) + area = visibleArea(); + } else { + area = visibleArea(); + } + + return area; +} + +void Surface::computeTexturesAmount(TexturesResult* result) +{ + if (!m_surfaceBacking || isBase()) + return; + + m_surfaceBacking->computeTexturesAmount(result, getFirstLayer()); +} + +bool Surface::isBase() +{ + // base layer surface + // - doesn't use layer tiles (disables blending, doesn't compute textures amount) + // - ignores clip rects + // - only prepares clippedArea + return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer; +} + +bool Surface::paint(Tile* tile, SkCanvas* canvas) +{ + if (singleLayer()) { + getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers); + + // TODO: double buffer by disabling SurfaceCollection swaps and position + // updates until painting complete + + // In single surface mode, draw layer content onto the base layer + if (isBase() + && getFirstLayer()->countChildren() + && getFirstLayer()->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) + getFirstLayer()->getChild(0)->drawCanvas(canvas, true, Layer::FlattenedLayers); + } else { + SkAutoCanvasRestore acr(canvas, true); + SkMatrix matrix; + GLUtils::toSkMatrix(matrix, m_drawTransform); + + SkMatrix inverse; + inverse.reset(); + matrix.invert(&inverse); + + SkMatrix canvasMatrix = canvas->getTotalMatrix(); + inverse.postConcat(canvasMatrix); + canvas->setMatrix(inverse); + + for (unsigned int i=0; idrawCanvas(canvas, false, Layer::MergedLayers); + } + return true; +} + +float Surface::opacity() +{ + if (singleLayer()) + return getFirstLayer()->drawOpacity(); + return 1.0; +} + +Color* Surface::background() +{ + if (!isBase() || !m_background.isValid()) + return 0; + return &m_background; +} + +const TransformationMatrix* Surface::drawTransform() +{ + // single layer surfaces query the layer's draw transform, while multi-layer + // surfaces copy the draw transform once, during initialization + // TODO: support fixed multi-layer surfaces by querying the changing drawTransform + if (singleLayer()) + return getFirstLayer()->drawTransform(); + + return &m_drawTransform; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/Surface.h b/Source/WebCore/platform/graphics/android/Surface.h new file mode 100644 index 0000000..27c997e --- /dev/null +++ b/Source/WebCore/platform/graphics/android/Surface.h @@ -0,0 +1,115 @@ +/* + * 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 Surface_h +#define Surface_h + +#include "Color.h" +#include "IntRect.h" +#include "TilePainter.h" +#include "Vector.h" + +class SkCanvas; +class SkRegion; + +namespace WebCore { + +class Tile; +class SurfaceBacking; +class LayerAndroid; +class TexturesResult; + +class Surface : public TilePainter { +public: + Surface(); + virtual ~Surface(); + + bool tryUpdateSurface(Surface* oldSurface); + + void addLayer(LayerAndroid* layer, const TransformationMatrix& transform); + void prepareGL(bool layerTilesDisabled); + bool drawGL(bool layerTilesDisabled); + void swapTiles(); + bool isReady(); + + void computeTexturesAmount(TexturesResult* result); + + LayerAndroid* getFirstLayer() { return m_layers[0]; } + bool needsTexture() { return m_needsTexture; } + bool hasText() { return m_hasText; } + bool isBase(); + void setBackground(Color background) { m_background = background; } + + // TilePainter methods + virtual bool paint(Tile* tile, SkCanvas* canvas); + virtual float opacity(); + virtual Color* background(); + +private: + IntRect computePrepareArea(); + IntRect visibleArea(); + IntRect unclippedArea(); + bool singleLayer() { return m_layers.size() == 1; } + void updateBackground(const Color& background); + bool useAggressiveRendering(); + + const TransformationMatrix* drawTransform(); + IntRect m_unclippedArea; + TransformationMatrix m_drawTransform; + + SurfaceBacking* m_surfaceBacking; + bool m_needsTexture; + bool m_hasText; + Vector m_layers; + + Color m_background; +}; + +class LayerMergeState { +public: + LayerMergeState(Vector* const allGroups) + : surfaceList(allGroups) + , currentSurface(0) + , nonMergeNestedLevel(-1) // start at -1 to ignore first LayerAndroid's clipping + , depth(0) + {} + + // vector storing all generated layer groups + Vector* const surfaceList; + + // currently merging group. if cleared, no more layers may join + Surface* currentSurface; + + // records depth within non-mergeable parents (clipping, fixed, scrolling) + // and disable merging therein. + int nonMergeNestedLevel; + + // counts layer tree depth for debugging + int depth; +}; + +} // namespace WebCore + +#endif //#define Surface_h diff --git a/Source/WebCore/platform/graphics/android/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/SurfaceBacking.cpp new file mode 100644 index 0000000..7c8f570 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceBacking.cpp @@ -0,0 +1,171 @@ +/* + * 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. + */ + +#define LOG_TAG "SurfaceBacking" +#define LOG_NDEBUG 1 + +#include "config.h" +#include "SurfaceBacking.h" + +#include "AndroidLog.h" +#include "Color.h" +#include "GLWebViewState.h" +#include "LayerAndroid.h" + +#define LOW_RES_PREFETCH_SCALE_MODIFIER 0.3f + +namespace WebCore { + +SurfaceBacking::SurfaceBacking(bool isBaseSurface) +{ + m_frontTexture = new TileGrid(isBaseSurface); + m_backTexture = new TileGrid(isBaseSurface); + m_scale = -1; + m_futureScale = -1; + m_zooming = false; +} + +SurfaceBacking::~SurfaceBacking() +{ + delete m_frontTexture; + delete m_backTexture; +} + +void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom, + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool aggressiveRendering) +{ + float scale = state->scale(); + if (scale > 1 && !allowZoom) + scale = 1; + + if (m_scale == -1) { + m_scale = scale; + m_futureScale = scale; + } + + if (m_futureScale != scale) { + m_futureScale = scale; + m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay; + m_zooming = true; + } + + bool useExpandPrefetch = aggressiveRendering; + ALOGV("Prepare SurfBack %p, scale %.2f, m_scale %.2f, futScale: %.2f, zooming: %d, f %p, b %p", + this, scale, m_scale, m_futureScale, m_zooming, + m_frontTexture, m_backTexture); + + if (!m_zooming) { + m_frontTexture->prepareGL(state, m_scale, + prepareArea, unclippedArea, painter, false, useExpandPrefetch); + if (aggressiveRendering) { + // prepare the back tiled texture to render content in low res + float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER; + m_backTexture->prepareGL(state, lowResPrefetchScale, + prepareArea, unclippedArea, painter, true, useExpandPrefetch); + m_backTexture->swapTiles(); + } + } else if (m_zoomUpdateTime < WTF::currentTime()) { + m_backTexture->prepareGL(state, m_futureScale, + prepareArea, unclippedArea, painter, false, useExpandPrefetch); + if (m_backTexture->isReady()) { + // zooming completed, swap the textures and new front tiles + swapTileGrids(); + + m_frontTexture->swapTiles(); + m_backTexture->discardTextures(); + + m_scale = m_futureScale; + m_zooming = false; + } + } +} + +void SurfaceBacking::drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, + bool aggressiveRendering, const Color* background) +{ + // draw low res prefetch page, if needed + if (aggressiveRendering && !m_zooming && m_frontTexture->isMissingContent()) + m_backTexture->drawGL(visibleArea, opacity, transform); + + m_frontTexture->drawGL(visibleArea, opacity, transform, background); +} + +void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea) +{ + m_backTexture->markAsDirty(dirtyArea); + m_frontTexture->markAsDirty(dirtyArea); +} + +void SurfaceBacking::swapTiles() +{ + m_backTexture->swapTiles(); + m_frontTexture->swapTiles(); +} + +void SurfaceBacking::computeTexturesAmount(TexturesResult* result, LayerAndroid* layer) +{ + // TODO: shouldn't use layer, as this SB 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 + TileGrid* 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->isPositionFixed()) + result->fixed += nbTexturesClipped; + + // Set kScrollableAndFixedLayers level + if (layer->contentIsScrollable() + || layer->isPositionFixed()) + result->scrollable += nbTexturesClipped; + + // Set kClippedTextures level + result->clipped += nbTexturesClipped; + + // Set kAllTextures level + if (layer->contentIsScrollable()) + result->full += nbTexturesClipped; + else + result->full += nbTexturesUnclipped; +} + +void SurfaceBacking::swapTileGrids() +{ + TileGrid* temp = m_frontTexture; + m_frontTexture = m_backTexture; + m_backTexture = temp; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/SurfaceBacking.h new file mode 100644 index 0000000..b04e462 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/SurfaceBacking.h @@ -0,0 +1,86 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SurfaceBacking_h +#define SurfaceBacking_h + +#include "SkRefCnt.h" +#include "TileGrid.h" + +namespace WebCore { + +class LayerAndroid; +class TexturesResult; +class TilePainter; + +class SurfaceBacking : public SkRefCnt { +// TODO: investigate webkit threadsafe ref counting +public: + SurfaceBacking(bool isBaseSurface); + ~SurfaceBacking(); + void prepareGL(GLWebViewState* state, bool allowZoom, + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool aggressiveRendering); + void swapTiles(); + void drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, bool aggressiveRendering, + const Color* background); + void markAsDirty(const SkRegion& dirtyArea); + void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer); + void discardTextures() + { + m_frontTexture->discardTextures(); + m_backTexture->discardTextures(); + } + bool isReady() + { + return !m_zooming && m_frontTexture->isReady() && m_scale > 0; + } + + int nbTextures(IntRect& area, float scale) + { + // TODO: consider the zooming case for the backTexture + if (!m_frontTexture) + return 0; + return m_frontTexture->nbTextures(area, scale); + } + +private: + void swapTileGrids(); + + // Delay before we schedule a new tile at the new scale factor + static const double s_zoomUpdateDelay = 0.2; // 200 ms + + TileGrid* m_frontTexture; + TileGrid* m_backTexture; + float m_scale; + float m_futureScale; + double m_zoomUpdateTime; + bool m_zooming; +}; + +} // namespace WebCore + +#endif // SurfaceBacking_h diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp index 78c3fbb..0bbaf91 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.cpp @@ -34,14 +34,14 @@ #include "ClassTracker.h" #include "GLWebViewState.h" #include "LayerAndroid.h" -#include "LayerGroup.h" +#include "Surface.h" #include "ScrollableLayerAndroid.h" #include "TilesManager.h" namespace WebCore { //////////////////////////////////////////////////////////////////////////////// -// TILED PAINTING / GROUPS // +// TILED PAINTING / SURFACES // //////////////////////////////////////////////////////////////////////////////// SurfaceCollection::SurfaceCollection(LayerAndroid* layer) @@ -55,18 +55,18 @@ SurfaceCollection::SurfaceCollection(LayerAndroid* layer) m_compositedRoot->updateLayerPositions(visibleRect); // TODO: updateGLPositionsAndScale? - // allocate groups for layers, merging where possible - ALOGV("new tree, allocating groups for tree %p", m_baseLayer); + // allocate surfaces for layers, merging where possible + ALOGV("new tree, allocating surfaces for tree %p", m_baseLayer); - LayerMergeState layerMergeState(&m_layerGroups); - m_compositedRoot->assignGroups(&layerMergeState); + LayerMergeState layerMergeState(&m_surfaces); + m_compositedRoot->assignSurfaces(&layerMergeState); - // set the layergroups' and tiledpages' update count, to be drawn on painted tiles + // set the layersurfaces' 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); - if (m_layerGroups[i]->isBase()) - m_layerGroups[i]->setBackground(getBackground()); + for (unsigned int i = 0; i < m_surfaces.size(); i++) { + m_surfaces[i]->setUpdateCount(updateCount); + if (m_surfaces[i]->isBase()) + m_surfaces[i]->setBackground(getBackground()); } #ifdef DEBUG_COUNT @@ -77,9 +77,9 @@ SurfaceCollection::SurfaceCollection(LayerAndroid* layer) SurfaceCollection::~SurfaceCollection() { SkSafeUnref(m_compositedRoot); - for (unsigned int i = 0; i < m_layerGroups.size(); i++) - SkSafeUnref(m_layerGroups[i]); - m_layerGroups.clear(); + for (unsigned int i = 0; i < m_surfaces.size(); i++) + SkSafeUnref(m_surfaces[i]); + m_surfaces.clear(); #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("SurfaceCollection"); @@ -91,8 +91,8 @@ void SurfaceCollection::prepareGL(const SkRect& visibleRect) 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); + for (unsigned int i = 0; i < m_surfaces.size(); i++) + m_surfaces[i]->prepareGL(layerTilesDisabled); } bool SurfaceCollection::drawGL(const SkRect& visibleRect) @@ -105,8 +105,8 @@ bool SurfaceCollection::drawGL(const SkRect& visibleRect) 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); + for (unsigned int i = 0; i < m_surfaces.size(); i++) + needsRedraw |= m_surfaces[i]->drawGL(layerTilesDisabled); return needsRedraw; } @@ -118,8 +118,8 @@ Color SurfaceCollection::getBackground() void SurfaceCollection::swapTiles() { - for (unsigned int i = 0; i < m_layerGroups.size(); i++) - m_layerGroups[i]->swapTiles(); + for (unsigned int i = 0; i < m_surfaces.size(); i++) + m_surfaces[i]->swapTiles(); } bool SurfaceCollection::isReady() @@ -130,9 +130,9 @@ bool SurfaceCollection::isReady() return true; } - for (unsigned int i = 0; i < m_layerGroups.size(); i++) { - if (!m_layerGroups[i]->isReady()) { - ALOGV("layer group %p isn't ready", m_layerGroups[i]); + for (unsigned int i = 0; i < m_surfaces.size(); i++) { + if (!m_surfaces[i]->isReady()) { + ALOGV("layer surface %p isn't ready", m_surfaces[i]); return false; } } @@ -141,8 +141,8 @@ bool SurfaceCollection::isReady() void SurfaceCollection::computeTexturesAmount(TexturesResult* result) { - for (unsigned int i = 0; i < m_layerGroups.size(); i++) - m_layerGroups[i]->computeTexturesAmount(result); + for (unsigned int i = 0; i < m_surfaces.size(); i++) + m_surfaces[i]->computeTexturesAmount(result); } //////////////////////////////////////////////////////////////////////////////// @@ -154,14 +154,14 @@ void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface) if (!drawingSurface) return; - for (unsigned int i = 0; i < m_layerGroups.size(); i++) { - LayerGroup* newLayerGroup = m_layerGroups[i]; - if (!newLayerGroup->needsTexture()) + for (unsigned int i = 0; i < m_surfaces.size(); i++) { + Surface* newSurface = m_surfaces[i]; + if (!newSurface->needsTexture()) continue; - for (unsigned int j = 0; j < drawingSurface->m_layerGroups.size(); j++) { - LayerGroup* oldLayerGroup = drawingSurface->m_layerGroups[j]; - if (newLayerGroup->tryUpdateLayerGroup(oldLayerGroup)) + for (unsigned int j = 0; j < drawingSurface->m_surfaces.size(); j++) { + Surface* oldSurface = drawingSurface->m_surfaces[j]; + if (newSurface->tryUpdateSurface(oldSurface)) break; } } diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/SurfaceCollection.h index e73ec9a..6450c9c 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollection.h +++ b/Source/WebCore/platform/graphics/android/SurfaceCollection.h @@ -29,7 +29,8 @@ #include "Color.h" #include "SkRect.h" #include "SkRefCnt.h" -#include "Vector.h" + +#include class SkCanvas; class SkRegion; @@ -37,7 +38,7 @@ class SkRegion; namespace WebCore { class LayerAndroid; -class LayerGroup; +class Surface; class TexturesResult; class SurfaceCollection : public SkRefCnt { @@ -67,7 +68,7 @@ public: private: void updateLayerPositions(const SkRect& visibleRect); LayerAndroid* m_compositedRoot; - Vector m_layerGroups; + WTF::Vector m_surfaces; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp index 91dba3c..8fb4d4b 100644 --- a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp +++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp @@ -30,7 +30,6 @@ #include "SurfaceCollectionManager.h" #include "AndroidLog.h" -#include "LayerGroup.h" #include "private/hwui/DrawGlInfo.h" #include "TilesManager.h" #include "SurfaceCollection.h" diff --git a/Source/WebCore/platform/graphics/android/TextureInfo.h b/Source/WebCore/platform/graphics/android/TextureInfo.h index 4684df2..7d182c3 100644 --- a/Source/WebCore/platform/graphics/android/TextureInfo.h +++ b/Source/WebCore/platform/graphics/android/TextureInfo.h @@ -31,7 +31,6 @@ #include #include #include -#include "BaseTile.h" using android::sp; namespace android { diff --git a/Source/WebCore/platform/graphics/android/TextureOwner.h b/Source/WebCore/platform/graphics/android/TextureOwner.h index 4f9e6ef..58ddca2 100644 --- a/Source/WebCore/platform/graphics/android/TextureOwner.h +++ b/Source/WebCore/platform/graphics/android/TextureOwner.h @@ -31,13 +31,13 @@ class Layer; namespace WebCore { -class BaseTileTexture; +class TileTexture; class GLWebViewState; class TextureOwner { public: virtual ~TextureOwner() { } - virtual bool removeTexture(BaseTileTexture* texture) = 0; + virtual bool removeTexture(TileTexture* texture) = 0; virtual bool samePageAs(Layer* root) { return false; } virtual bool isRepaintPending() = 0; virtual unsigned long long drawCount() = 0; diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp index 3279ec2..f884e52 100644 --- a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp +++ b/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp @@ -35,6 +35,7 @@ #include "GLUtils.h" #include "PaintTileOperation.h" #include "TilesManager.h" +#include "TransferQueue.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.h b/Source/WebCore/platform/graphics/android/TexturesGenerator.h index 35a3386..08f69ae 100644 --- a/Source/WebCore/platform/graphics/android/TexturesGenerator.h +++ b/Source/WebCore/platform/graphics/android/TexturesGenerator.h @@ -30,7 +30,7 @@ #include "QueuedOperation.h" #include "TilePainter.h" -#include "Vector.h" +#include #include @@ -56,7 +56,7 @@ public: private: QueuedOperation* popNext(); virtual bool threadLoop(); - Vector mRequestedOperations; + WTF::Vector mRequestedOperations; android::Mutex mRequestedOperationsLock; android::Condition mRequestedOperationsCond; bool m_waitForCompletion; diff --git a/Source/WebCore/platform/graphics/android/Tile.cpp b/Source/WebCore/platform/graphics/android/Tile.cpp new file mode 100644 index 0000000..1612337 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/Tile.cpp @@ -0,0 +1,538 @@ +/* + * Copyright 2010, 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. + */ + +#define LOG_TAG "Tile" +#define LOG_NDEBUG 1 + +#include "config.h" +#include "Tile.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "AndroidLog.h" +#include "GLUtils.h" +#include "RasterRenderer.h" +#include "TextureInfo.h" +#include "TileTexture.h" +#include "TilesManager.h" + +// If the dirty portion of a tile exceeds this ratio, fully repaint. +// Lower values give fewer partial repaints, thus fewer front-to-back +// texture copies (cost will vary by device). It's a tradeoff between +// the rasterization cost and the FBO texture recopy cost when using +// GPU for the transfer queue. +#define MAX_INVAL_AREA 0.6 + +namespace WebCore { + +Tile::Tile(bool isLayerTile) + : m_x(-1) + , m_y(-1) + , m_frontTexture(0) + , m_backTexture(0) + , m_scale(1) + , m_dirty(true) + , m_repaintPending(false) + , m_fullRepaint(true) + , m_isTexturePainted(false) + , m_isLayerTile(isLayerTile) + , m_drawCount(0) + , m_state(Unpainted) +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("Tile"); +#endif + m_renderer = BaseRenderer::createRenderer(); +} + +Tile::~Tile() +{ + if (m_backTexture) + m_backTexture->release(this); + if (m_frontTexture) + m_frontTexture->release(this); + + delete m_renderer; + +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("Tile"); +#endif +} + +// All the following functions must be called from the main GL thread. + +void Tile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile) +{ + // TODO: investigate whether below check/discard is necessary + if ((m_x != x) + || (m_y != y) + || (m_scale != scale)) { + // neither texture is relevant + discardTextures(); + } + + android::AutoMutex lock(m_atomicSync); + m_x = x; + m_y = y; + m_scale = scale; + m_drawCount = TilesManager::instance()->getDrawGLCount(); + if (isExpandedPrefetchTile) + m_drawCount--; // deprioritize expanded painting region +} + +void Tile::reserveTexture() +{ + TileTexture* texture = TilesManager::instance()->getAvailableTexture(this); + + android::AutoMutex lock(m_atomicSync); + if (texture && m_backTexture != texture) { + ALOGV("tile %p reserving texture %p, back was %p (front %p)", + this, texture, m_backTexture, m_frontTexture); + m_state = Unpainted; + m_backTexture = texture; + } + + if (m_state == UpToDate) { + ALOGV("moving tile %p to unpainted, since it reserved while up to date", this); + m_dirty = true; + m_state = Unpainted; + } +} + +bool Tile::removeTexture(TileTexture* texture) +{ + ALOGV("%p removeTexture %p, back %p front %p... page %p", + this, texture, m_backTexture, m_frontTexture, m_page); + // We update atomically, so paintBitmap() can see the correct value + android::AutoMutex lock(m_atomicSync); + if (m_frontTexture == texture) { + if (m_state == UpToDate) { + ALOGV("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture); + m_state = Unpainted; + } + + m_frontTexture = 0; + } + if (m_backTexture == texture) { + m_state = Unpainted; + m_backTexture = 0; + } + + // mark dirty regardless of which texture was taken - the back texture may + // have been ready to swap + m_dirty = true; + + return true; +} + +void Tile::markAsDirty(const SkRegion& dirtyArea) +{ + if (dirtyArea.isEmpty()) + return; + android::AutoMutex lock(m_atomicSync); + m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op); + + // Check if we actually intersect with the area + bool intersect = false; + SkRegion::Iterator cliperator(dirtyArea); + SkRect realTileRect; + SkRect dirtyRect; + while (!cliperator.done()) { + dirtyRect.set(cliperator.rect()); + if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(), + m_scale, dirtyRect, realTileRect)) { + intersect = true; + break; + } + cliperator.next(); + } + + if (!intersect) + return; + + m_dirty = true; + if (m_state == UpToDate) { + // We only mark a tile as unpainted in 'markAsDirty' if its status is + // UpToDate: marking dirty means we need to repaint, but don't stop the + // current paint + m_state = Unpainted; + } else if (m_state != Unpainted) { + // TODO: fix it so that they can paint while deferring the markAsDirty + // call (or block updates) + ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d, page %p", + this, m_x, m_y, isLayerTile(), m_state, m_page); + + // prefetch tiles can be marked dirty while in the process of painting, + // due to not using an update lock. force them to fail validate step. + m_state = Unpainted; + } +} + +bool Tile::isDirty() +{ + android::AutoMutex lock(m_atomicSync); + return m_dirty; +} + +bool Tile::isRepaintPending() +{ + android::AutoMutex lock(m_atomicSync); + return m_repaintPending; +} + +void Tile::setRepaintPending(bool pending) +{ + android::AutoMutex lock(m_atomicSync); + m_repaintPending = pending; +} + +bool Tile::drawGL(float opacity, const SkRect& rect, float scale, + const TransformationMatrix* transform) +{ + if (m_x < 0 || m_y < 0 || m_scale != scale) + return false; + + // No need to mutex protect reads of m_backTexture as it is only written to by + // the consumer thread. + if (!m_frontTexture) + return false; + + // Early return if set to un-usable in purpose! + m_atomicSync.lock(); + bool isTexturePainted = m_isTexturePainted; + m_atomicSync.unlock(); + + if (!isTexturePainted) + return false; + + m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform); + return true; +} + +bool Tile::isTileReady() +{ + // Return true if the tile's most recently drawn texture is up to date + android::AutoMutex lock(m_atomicSync); + TileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture; + + if (!texture) + return false; + + if (texture->owner() != this) + return false; + + if (m_dirty) + return false; + + if (m_state != ReadyToSwap && m_state != UpToDate) + return false; + + return true; +} + +bool Tile::intersectWithRect(int x, int y, int tileWidth, int tileHeight, + float scale, const SkRect& dirtyRect, + SkRect& realTileRect) +{ + // compute the rect to corresponds to pixels + realTileRect.fLeft = x * tileWidth; + realTileRect.fTop = y * tileHeight; + realTileRect.fRight = realTileRect.fLeft + tileWidth; + realTileRect.fBottom = realTileRect.fTop + tileHeight; + + // scale the dirtyRect for intersect computation. + SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale, + dirtyRect.height() * scale); + realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale); + + if (!realTileRect.intersect(realDirtyRect)) + return false; + return true; +} + +bool Tile::isTileVisible(const IntRect& viewTileBounds) +{ + return (m_x >= viewTileBounds.x() + && m_x < viewTileBounds.x() + viewTileBounds.width() + && m_y >= viewTileBounds.y() + && m_y < viewTileBounds.y() + viewTileBounds.height()); +} + +// This is called from the texture generation thread +void Tile::paintBitmap(TilePainter* painter) +{ + // We acquire the values below atomically. This ensures that we are reading + // values correctly across cores. Further, once we have these values they + // can be updated by other threads without consequence. + m_atomicSync.lock(); + bool dirty = m_dirty; + TileTexture* texture = m_backTexture; + SkRegion dirtyArea = m_dirtyArea; + float scale = m_scale; + const int x = m_x; + const int y = m_y; + + if (!dirty || !texture) { + m_atomicSync.unlock(); + return; + } + if (m_state != Unpainted) { + ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p", + this, m_state, m_frontTexture, m_backTexture); + } + m_state = PaintingStarted; + TextureInfo* textureInfo = texture->getTextureInfo(); + m_atomicSync.unlock(); + + // at this point we can safely check the ownership (if the texture got + // transferred to another Tile under us) + if (texture->owner() != this) { + return; + } + + // swap out the renderer if necessary + BaseRenderer::swapRendererIfNeeded(m_renderer); + // setup the common renderInfo fields; + TileRenderInfo renderInfo; + renderInfo.x = x; + renderInfo.y = y; + renderInfo.scale = scale; + renderInfo.tileSize = texture->getSize(); + renderInfo.tilePainter = painter; + renderInfo.baseTile = this; + renderInfo.textureInfo = textureInfo; + + const float tileWidth = renderInfo.tileSize.width(); + const float tileHeight = renderInfo.tileSize.height(); + + SkRegion::Iterator cliperator(dirtyArea); + + bool fullRepaint = false; + + if (m_fullRepaint + || textureInfo->m_width != tileWidth + || textureInfo->m_height != tileHeight) { + fullRepaint = true; + } + + // For now, only do full repaint + fullRepaint = true; + + if (!fullRepaint) { + // compute the partial inval area + SkIRect totalRect; + totalRect.set(0, 0, 0, 0); + float tileSurface = tileWidth * tileHeight; + float tileSurfaceCap = MAX_INVAL_AREA * tileSurface; + + // We join all the invals in the same tile for now + while (!fullRepaint && !cliperator.done()) { + SkRect realTileRect; + SkRect dirtyRect; + dirtyRect.set(cliperator.rect()); + bool intersect = intersectWithRect(x, y, tileWidth, tileHeight, + scale, dirtyRect, realTileRect); + if (intersect) { + // initialize finalRealRect to the rounded values of realTileRect + SkIRect finalRealRect; + realTileRect.roundOut(&finalRealRect); + + // stash the int values of the current width and height + const int iWidth = finalRealRect.width(); + const int iHeight = finalRealRect.height(); + + if (iWidth == tileWidth || iHeight == tileHeight) { + fullRepaint = true; + break; + } + + // translate the rect into tile space coordinates + finalRealRect.fLeft = finalRealRect.fLeft % static_cast(tileWidth); + finalRealRect.fTop = finalRealRect.fTop % static_cast(tileHeight); + finalRealRect.fRight = finalRealRect.fLeft + iWidth; + finalRealRect.fBottom = finalRealRect.fTop + iHeight; + totalRect.join(finalRealRect); + float repaintSurface = totalRect.width() * totalRect.height(); + + if (repaintSurface > tileSurfaceCap) { + fullRepaint = true; + break; + } + } + + cliperator.next(); + } + + if (!fullRepaint) { + renderInfo.invalRect = &totalRect; + m_renderer->renderTiledContent(renderInfo); + } + } + + // Do a full repaint if needed + if (fullRepaint) { + renderInfo.invalRect = 0; + m_renderer->renderTiledContent(renderInfo); + } + + m_atomicSync.lock(); + + if (texture == m_backTexture) { + m_isTexturePainted = true; + + // set the fullrepaint flags + m_fullRepaint = false; + + // The various checks to see if we are still dirty... + + m_dirty = false; + + if (m_scale != scale) + m_dirty = true; + + if (fullRepaint) + m_dirtyArea.setEmpty(); + else + m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op); + + if (!m_dirtyArea.isEmpty()) + m_dirty = true; + + ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty); + + validatePaint(); + } else { + ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p", + this, texture, m_state, m_frontTexture, m_backTexture); + } + + m_atomicSync.unlock(); +} + +void Tile::discardTextures() { + android::AutoMutex lock(m_atomicSync); + ALOGV("%p discarding bt %p, ft %p", + this, m_backTexture, m_frontTexture); + if (m_frontTexture) { + m_frontTexture->release(this); + m_frontTexture = 0; + } + if (m_backTexture) { + m_backTexture->release(this); + m_backTexture = 0; + } + m_dirtyArea.setEmpty(); + m_fullRepaint = true; + + m_dirty = true; + m_state = Unpainted; +} + +void Tile::discardBackTexture() { + android::AutoMutex lock(m_atomicSync); + if (m_backTexture) { + m_backTexture->release(this); + m_backTexture = 0; + } + m_state = Unpainted; + m_dirty = true; +} + +bool Tile::swapTexturesIfNeeded() { + android::AutoMutex lock(m_atomicSync); + if (m_state == ReadyToSwap) { + // discard old texture and swap the new one in its place + if (m_frontTexture) + m_frontTexture->release(this); + + m_frontTexture = m_backTexture; + m_backTexture = 0; + m_state = UpToDate; + ALOGV("display texture for %p at %d, %d front is now %p, back is %p", + this, m_x, m_y, m_frontTexture, m_backTexture); + + return true; + } + return false; +} + +void Tile::backTextureTransfer() { + android::AutoMutex lock(m_atomicSync); + if (m_state == PaintingStarted) + m_state = TransferredUnvalidated; + else if (m_state == ValidatedUntransferred) + m_state = ReadyToSwap; + else { + // shouldn't have transferred a tile in any other state, log + ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d", + this, m_x, m_y, m_state); + } +} + +void Tile::backTextureTransferFail() { + // transfer failed for some reason, mark dirty so it will (repaint and) be + // retransferred. + android::AutoMutex lock(m_atomicSync); + m_state = Unpainted; + m_dirty = true; + // whether validatePaint is called before or after, it won't do anything +} + +void Tile::validatePaint() { + // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap()) + + if (!m_dirty) { + // since after the paint, the tile isn't dirty, 'validate' it - this + // may happed before or after the transfer queue operation. Only + // when both have happened, mark as 'ReadyToSwap' + if (m_state == PaintingStarted) + m_state = ValidatedUntransferred; + else if (m_state == TransferredUnvalidated) { + // When the backTexture has been marked pureColor, we will skip the + // transfer and marked as ReadyToSwap, in this case, we don't want + // to reset m_dirty bit to true. + m_state = ReadyToSwap; + } else { + ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d", + this, m_x, m_y, m_state); + // failed transferring, in which case mark dirty (since + // paintBitmap() may have cleared m_dirty) + m_dirty = true; + } + + if (m_deferredDirty) { + ALOGV("Note: deferred dirty flag set, possibly a missed paint on tile %p", this); + m_deferredDirty = false; + } + } else { + ALOGV("Note: paint was unsuccessful."); + m_state = Unpainted; + } + +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/Tile.h b/Source/WebCore/platform/graphics/android/Tile.h new file mode 100644 index 0000000..022966b --- /dev/null +++ b/Source/WebCore/platform/graphics/android/Tile.h @@ -0,0 +1,193 @@ +/* + * Copyright 2010, 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 Tile_h +#define Tile_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "BaseRenderer.h" +#include "SkRect.h" +#include "SkRegion.h" +#include "TextureOwner.h" +#include "TilePainter.h" + +#include + +namespace WebCore { + +class TextureInfo; +class TileTexture; +class GLWebViewState; + +/** + * An individual tile that is used to construct part of a webpage's BaseLayer of + * content. Each tile is assigned to a TiledPage and is responsible for drawing + * and displaying their section of the page. The lifecycle of a tile is: + * + * 1. Each tile is created on the main GL thread and assigned to a specific + * location within a TiledPage. + * 2. When needed the tile is passed to the background thread where it paints + * the BaseLayer's most recent PictureSet to a bitmap which is then uploaded + * to the GPU. + * 3. After the bitmap is uploaded to the GPU the main GL thread then uses the + * tile's drawGL() function to display the tile to the screen. + * 4. Steps 2-3 are repeated as necessary. + * 5. The tile is destroyed when the user navigates to a new page. + * + */ +class Tile : public TextureOwner { +public: + + // eventually, m_dirty might be rolled into the state machine, but note + // that a tile that's continually marked dirty from animation should still + // progress through the state machine and be drawn periodically (esp. for + // layers) + + // /-> TransferredUnvalidated (TQ interrupts paint) -\ (TQ & paint done) + // Unpainted -> PaintingStarted -- -> ReadyToSwap -> UpToDate + // ^ \-> ValidatedUntransferred (paint finish before TQ) -/ + // | + // \--... (From any state when marked dirty. should usually come from UpToDate if the updates are locked) + // + + enum TextureState{ + // back texture is completely unpainted + Unpainted = 0, + // has started painting, but haven't been transferred or validated + PaintingStarted = 1, + // back texture painted, transferred before validating in PaintBitmap() + TransferredUnvalidated = 2, + // back texture painted, validated before transferring in TransferQueue + ValidatedUntransferred = 3, + // back texture has been blitted, will be swapped when next available + ReadyToSwap = 4, + // has been swapped, is ready to draw, all is well + UpToDate = 5, + }; + + Tile(bool isLayerTile = false); + ~Tile(); + + bool isLayerTile() { return m_isLayerTile; } + + void setContents(int x, int y, float scale, bool isExpandedPrefetchTile); + + void reserveTexture(); + + bool isTileReady(); + + // Return false when real draw didn't happen for any reason. + bool drawGL(float opacity, const SkRect& rect, float scale, + const TransformationMatrix* transform); + + // the only thread-safe function called by the background thread + void paintBitmap(TilePainter* painter); + + bool intersectWithRect(int x, int y, int tileWidth, int tileHeight, + float scale, const SkRect& dirtyRect, + SkRect& realTileRect); + bool isTileVisible(const IntRect& viewTileBounds); + + void markAsDirty(const SkRegion& dirtyArea); + bool isDirty(); + virtual bool isRepaintPending(); + void setRepaintPending(bool pending); + float scale() const { return m_scale; } + TextureState textureState() const { return m_state; } + + int x() const { return m_x; } + int y() const { return m_y; } + TileTexture* frontTexture() { return m_frontTexture; } + TileTexture* backTexture() { return m_backTexture; } + + // only used for prioritization - the higher, the more relevant the tile is + unsigned long long drawCount() { return m_drawCount; } + void discardTextures(); + void discardBackTexture(); + bool swapTexturesIfNeeded(); + void backTextureTransfer(); + void backTextureTransferFail(); + + // TextureOwner implementation + virtual bool removeTexture(TileTexture* texture); + +private: + void validatePaint(); + + int m_x; + int m_y; + + // The remaining variables can be updated throughout the lifetime of the object + + TileTexture* m_frontTexture; + TileTexture* m_backTexture; + float m_scale; + + // used to signal that the that the tile is out-of-date and needs to be + // redrawn in the backTexture + bool m_dirty; + + // currently only for debugging, to be used for tracking down dropped repaints + bool m_deferredDirty; + + // used to signal that a repaint is pending + bool m_repaintPending; + + // store the dirty region + SkRegion m_dirtyArea; + bool m_fullRepaint; + + // flag used to know if we have a texture that was painted at least once + bool m_isTexturePainted; + + // This mutex serves two purposes. (1) It ensures that certain operations + // happen atomically and (2) it makes sure those operations are synchronized + // across all threads and cores. + android::Mutex m_atomicSync; + + BaseRenderer* m_renderer; + + bool m_isLayerTile; + + // the most recent GL draw before this tile was prepared. used for + // prioritization and caching. tiles with old drawcounts and textures they + // own are used for new tiles and rendering + unsigned long long m_drawCount; + + // Tracks the state of painting for the tile. High level overview: + // 1) Unpainted - until paint starts (and if marked dirty, in most cases) + // 2) PaintingStarted - until paint completes + // 3) TransferredUnvalidated - if transferred first + // or ValidatedUntransferred - if validated first + // 4) ReadyToSwap - if painted and transferred, but not swapped + // 5) UpToDate - until marked dirty again + TextureState m_state; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) +#endif // Tile_h diff --git a/Source/WebCore/platform/graphics/android/TileGrid.cpp b/Source/WebCore/platform/graphics/android/TileGrid.cpp new file mode 100644 index 0000000..19a1815 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/TileGrid.cpp @@ -0,0 +1,371 @@ +/* + * 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. + */ + +#define LOG_TAG "TileGrid" +#define LOG_NDEBUG 1 + +#include "config.h" +#include "TileGrid.h" + +#include "AndroidLog.h" +#include "GLWebViewState.h" +#include "PaintTileOperation.h" +#include "Tile.h" +#include "TilesManager.h" + +#include + +#define EXPANDED_BOUNDS_INFLATE 1 +#define EXPANDED_PREFETCH_BOUNDS_Y_INFLATE 1 + +namespace WebCore { + +TileGrid::TileGrid(bool isBaseSurface) + : m_prevTileY(0) + , m_scale(1) + , m_isBaseSurface(isBaseSurface) +{ + m_dirtyRegion.setEmpty(); +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("TileGrid"); +#endif +} + +TileGrid::~TileGrid() +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("TileGrid"); +#endif + removeTiles(); +} + +bool TileGrid::isReady() +{ + bool tilesAllReady = true; + bool tilesVisible = false; + for (unsigned int i = 0; i < m_tiles.size(); i++) { + Tile* tile = m_tiles[i]; + if (tile->isTileVisible(m_area)) { + tilesVisible = true; + if (!tile->isTileReady()) { + tilesAllReady = false; + break; + } + } + } + // For now, if no textures are available, consider ourselves as ready + // in order to unblock the zooming process. + // FIXME: have a better system -- maybe keeping the last scale factor + // able to fully render everything + ALOGV("TT %p, ready %d, visible %d, texturesRemain %d", + this, tilesAllReady, tilesVisible, + TilesManager::instance()->layerTexturesRemain()); + + return !TilesManager::instance()->layerTexturesRemain() + || !tilesVisible || tilesAllReady; +} + +bool TileGrid::isMissingContent() +{ + for (unsigned int i = 0; i < m_tiles.size(); i++) + if (m_tiles[i]->isTileVisible(m_area) && !m_tiles[i]->frontTexture()) + return true; + return false; +} + +void TileGrid::swapTiles() +{ + int swaps = 0; + for (unsigned int i = 0; i < m_tiles.size(); i++) + if (m_tiles[i]->swapTexturesIfNeeded()) + swaps++; + ALOGV("TT %p swapping, swaps = %d", this, swaps); +} + +IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale) +{ + IntRect computedArea; + IntRect area(contentArea.x() * scale, + contentArea.y() * scale, + ceilf(contentArea.width() * scale), + ceilf(contentArea.height() * scale)); + + ALOGV("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height()); + + if (area.width() == 0 && area.height() == 0) { + computedArea.setWidth(0); + computedArea.setHeight(0); + return computedArea; + } + + int tileWidth = TilesManager::tileWidth(); + int tileHeight = TilesManager::tileHeight(); + + computedArea.setX(area.x() / tileWidth); + computedArea.setY(area.y() / tileHeight); + float right = (area.x() + area.width()) / (float) tileWidth; + float bottom = (area.y() + area.height()) / (float) tileHeight; + computedArea.setWidth(ceilf(right) - computedArea.x()); + computedArea.setHeight(ceilf(bottom) - computedArea.y()); + return computedArea; +} + +void TileGrid::prepareGL(GLWebViewState* state, float scale, + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool isLowResPrefetch, bool useExpandPrefetch) +{ + // first, how many tiles do we need + m_area = computeTilesArea(prepareArea, scale); + if (m_area.isEmpty()) + return; + + ALOGV("prepare TileGrid %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(), + prepareArea.width(), prepareArea.height(), + m_area.x(), m_area.y(), + m_area.width(), m_area.height()); + + bool goingDown = m_prevTileY < m_area.y(); + m_prevTileY = m_area.y(); + + if (scale != m_scale) + TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, m_scale)); + + m_scale = 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(m_dirtyRegion); + + // log inval region for the base surface + if (m_isBaseSurface && TilesManager::instance()->getProfiler()->enabled()) { + SkRegion::Iterator iterator(m_dirtyRegion); + while (!iterator.done()) { + SkIRect r = iterator.rect(); + TilesManager::instance()->getProfiler()->nextInval(r, scale); + iterator.next(); + } + } + m_dirtyRegion.setEmpty(); + } + + // prepare standard bounds (clearing ExpandPrefetch flag) + for (int i = 0; i < m_area.width(); i++) { + if (goingDown) { + for (int j = 0; j < m_area.height(); j++) + prepareTile(m_area.x() + i, m_area.y() + j, + painter, state, isLowResPrefetch, false); + } else { + for (int j = m_area.height() - 1; j >= 0; j--) + prepareTile(m_area.x() + i, m_area.y() + j, + painter, state, isLowResPrefetch, false); + } + } + + // prepare expanded bounds + if (useExpandPrefetch) { + IntRect fullArea = computeTilesArea(unclippedArea, scale); + IntRect expandedArea = m_area; + expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); + + if (isLowResPrefetch) + expandedArea.inflate(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); + + // clip painting area to content + expandedArea.intersect(fullArea); + + for (int i = expandedArea.x(); i < expandedArea.maxX(); i++) + for (int j = expandedArea.y(); j < expandedArea.maxY(); j++) + if (!m_area.contains(i, j)) + prepareTile(i, j, painter, state, isLowResPrefetch, true); + } +} + +void TileGrid::markAsDirty(const SkRegion& invalRegion) +{ + ALOGV("TT %p markAsDirty, current region empty %d, new empty %d", + this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty()); + m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); +} + +void TileGrid::prepareTile(int x, int y, TilePainter* painter, + GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch) +{ + Tile* tile = getTile(x, y); + if (!tile) { + bool isLayerTile = !m_isBaseSurface; + tile = new Tile(isLayerTile); + m_tiles.append(tile); + } + + ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter); + + tile->setContents(x, y, m_scale, isExpandPrefetch); + + // TODO: move below (which is largely the same for layers / tiled page) into + // prepareGL() function + + if (tile->isDirty() || !tile->frontTexture()) + tile->reserveTexture(); + + if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) { + ALOGV("painting TT %p's tile %d %d for LG %p", this, x, y, painter); + PaintTileOperation *operation = new PaintTileOperation(tile, painter, + state, isLowResPrefetch); + TilesManager::instance()->scheduleOperation(operation); + } +} + +Tile* TileGrid::getTile(int x, int y) +{ + for (unsigned int i = 0; i x() == x && tile->y() == y) + return tile; + } + return 0; +} + +int TileGrid::nbTextures(IntRect& area, float scale) +{ + IntRect tileBounds = computeTilesArea(area, scale); + int numberTextures = tileBounds.width() * tileBounds.height(); + + // add the number of dirty tiles in the bounds, as they take up double + // textures for double buffering + for (unsigned int i = 0; i isDirty() + && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX() + && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY()) + numberTextures++; + } + return numberTextures; +} + +void TileGrid::drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, + const Color* background) +{ + m_area = computeTilesArea(visibleArea, m_scale); + if (m_area.width() == 0 || m_area.height() == 0) + return; + + float invScale = 1 / m_scale; + const float tileWidth = TilesManager::tileWidth() * invScale; + const float tileHeight = TilesManager::tileHeight() * invScale; + + int drawn = 0; + + SkRegion missingRegion; + bool translucentBaseSurface = + background ? (background->hasAlpha() && background->alpha() > 0) : false; + if (translucentBaseSurface) { + SkIRect totalArea = SkIRect::MakeXYWH(m_area.x(), m_area.y(), + m_area.width(), m_area.height()); + missingRegion = SkRegion(totalArea); + } + + for (unsigned int i = 0; i < m_tiles.size(); i++) { + Tile* tile = m_tiles[i]; + + bool tileInView = tile->isTileVisible(m_area); + if (tileInView) { + SkRect rect; + rect.fLeft = tile->x() * tileWidth; + rect.fTop = tile->y() * tileHeight; + rect.fRight = rect.fLeft + tileWidth; + rect.fBottom = rect.fTop + tileHeight; + ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d", + tile, tile->isLayerTile(), tile->x(), tile->y(), + tile->scale(), m_scale, tile->isTileReady(), tile->isDirty()); + + bool success = tile->drawGL(opacity, rect, m_scale, transform); + if (translucentBaseSurface && success) { + // Cut the successful drawn tile area from the missing region. + missingRegion.op(SkIRect::MakeXYWH(tile->x(), tile->y(), 1, 1), + SkRegion::kDifference_Op); + } + if (tile->frontTexture()) + drawn++; + } + + if (translucentBaseSurface) + TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView); + } + + // Draw missing Regions with blend turned on + if (translucentBaseSurface) + drawMissingRegion(missingRegion, opacity, background); + + ALOGV("TT %p drew %d tiles, scale %f", + this, drawn, m_scale); +} + +void TileGrid::drawMissingRegion(const SkRegion& region, float opacity, + const Color* background) +{ + SkRegion::Iterator iterator(region); + const float tileWidth = TilesManager::tileWidth() / m_scale; + const float tileHeight = TilesManager::tileHeight() / m_scale; + ShaderProgram* shader = TilesManager::instance()->shader(); + while (!iterator.done()) { + SkIRect r = iterator.rect(); + SkRect rect; + rect.fLeft = r.x() * tileWidth; + rect.fTop = r.y() * tileHeight; + rect.fRight = rect.fLeft + tileWidth * r.width(); + rect.fBottom = rect.fTop + tileHeight * r.height(); + ALOGV("draw tile x y, %d %d (%d %d) opacity %f", r.x(), r.y(), + r.width(), r.height(), opacity); + // Skia is using pre-multiplied color. + Color postAlpha = Color(background->red() * background->alpha() / 255, + background->green() * background->alpha() / 255, + background->blue() * background->alpha() / 255, + background->alpha() ); + shader->drawQuad(rect, 0, opacity, postAlpha); + iterator.next(); + } +} + +void TileGrid::removeTiles() +{ + for (unsigned int i = 0; i < m_tiles.size(); i++) { + delete m_tiles[i]; + } + m_tiles.clear(); +} + +void TileGrid::discardTextures() +{ + ALOGV("TT %p discarding textures", this); + for (unsigned int i = 0; i < m_tiles.size(); i++) + m_tiles[i]->discardTextures(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TileGrid.h b/Source/WebCore/platform/graphics/android/TileGrid.h new file mode 100644 index 0000000..ffb6c7e --- /dev/null +++ b/Source/WebCore/platform/graphics/android/TileGrid.h @@ -0,0 +1,87 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TileGrid_h +#define TileGrid_h + +#include "IntRect.h" +#include "SkRegion.h" + +#include + +namespace WebCore { + +class Color; +class GLWebViewState; +class Tile; +class TilePainter; +class TransformationMatrix; + +class TileGrid { +public: + TileGrid(bool isBaseSurface); + virtual ~TileGrid(); + + static IntRect computeTilesArea(const IntRect& contentArea, float scale); + + void prepareGL(GLWebViewState* state, float scale, + const IntRect& prepareArea, const IntRect& unclippedArea, + TilePainter* painter, bool isLowResPrefetch = false, + bool useExpandPrefetch = false); + void swapTiles(); + void drawGL(const IntRect& visibleArea, float opacity, + const TransformationMatrix* transform, const Color* background = 0); + + void prepareTile(int x, int y, TilePainter* painter, + GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch); + void markAsDirty(const SkRegion& dirtyArea); + + Tile* getTile(int x, int y); + + void removeTiles(); + void discardTextures(); + + bool isReady(); + bool isMissingContent(); + + int nbTextures(IntRect& area, float scale); + +private: + void drawMissingRegion(const SkRegion& region, float opacity, const Color* tileBackground); + WTF::Vector m_tiles; + + IntRect m_area; + + SkRegion m_dirtyRegion; + + int m_prevTileY; + float m_scale; + + bool m_isBaseSurface; +}; + +} // namespace WebCore + +#endif // TileGrid_h diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h index a5dafa9..d992aee 100644 --- a/Source/WebCore/platform/graphics/android/TilePainter.h +++ b/Source/WebCore/platform/graphics/android/TilePainter.h @@ -33,14 +33,14 @@ class SkCanvas; namespace WebCore { -class BaseTile; +class Tile; class Color; class TilePainter : public SkRefCnt { // TODO: investigate webkit threadsafe ref counting public: virtual ~TilePainter() { } - virtual bool paint(BaseTile* tile, SkCanvas* canvas) = 0; + virtual bool paint(Tile* tile, SkCanvas* canvas) = 0; virtual float opacity() { return 1.0; } enum SurfaceType { Painted, Image }; virtual SurfaceType type() { return Painted; } diff --git a/Source/WebCore/platform/graphics/android/TileTexture.cpp b/Source/WebCore/platform/graphics/android/TileTexture.cpp new file mode 100644 index 0000000..7254149 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/TileTexture.cpp @@ -0,0 +1,140 @@ +/* + * Copyright 2010, 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. + */ + +#define LOG_TAG "TileTexture" +#define LOG_NDEBUG 1 + +#include "config.h" +#include "TileTexture.h" + +#include "AndroidLog.h" +#include "Tile.h" +#include "ClassTracker.h" +#include "GLUtils.h" +#include "GLWebViewState.h" +#include "TextureOwner.h" +#include "TilesManager.h" + +namespace WebCore { + +TileTexture::TileTexture(uint32_t w, uint32_t h) + : m_owner(0) + , m_isPureColor(false) +{ + m_size.set(w, h); + m_ownTextureId = 0; + +#ifdef DEBUG_COUNT + ClassTracker::instance()->increment("TileTexture"); +#endif +} + +TileTexture::~TileTexture() +{ +#ifdef DEBUG_COUNT + ClassTracker::instance()->decrement("TileTexture"); +#endif +} + +void TileTexture::requireGLTexture() +{ + if (!m_ownTextureId) + m_ownTextureId = GLUtils::createTileGLTexture(m_size.width(), m_size.height()); +} + +void TileTexture::discardGLTexture() +{ + if (m_ownTextureId) + GLUtils::deleteTexture(&m_ownTextureId); + + if (m_owner) { + // clear both Tile->Texture and Texture->Tile links + m_owner->removeTexture(this); + release(m_owner); + } +} + +bool TileTexture::acquire(TextureOwner* owner, bool force) +{ + if (m_owner == owner) + return true; + + return setOwner(owner, force); +} + +bool TileTexture::setOwner(TextureOwner* owner, bool force) +{ + bool proceed = true; + if (m_owner && m_owner != owner) + proceed = m_owner->removeTexture(this); + + if (proceed) { + m_owner = owner; + return true; + } + + return false; +} + +bool TileTexture::release(TextureOwner* owner) +{ + ALOGV("texture %p releasing tile %p, m_owner %p", this, owner, m_owner); + if (m_owner != owner) + return false; + + m_owner = 0; + return true; +} + +void TileTexture::transferComplete() +{ + if (m_owner) { + Tile* owner = static_cast(m_owner); + owner->backTextureTransfer(); + } else + ALOGE("ERROR: owner missing after transfer of texture %p", this); +} + +void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, + const TransformationMatrix* transform) +{ + ShaderProgram* shader = TilesManager::instance()->shader(); + if (isLayer && transform) { + if (isPureColor()) { + shader->drawLayerQuad(*transform, rect, 0, opacity, + true, GL_TEXTURE_2D, pureColor()); + } else { + shader->drawLayerQuad(*transform, rect, m_ownTextureId, + opacity, true); + } + } else { + if (isPureColor()) + shader->drawQuad(rect, 0, opacity, pureColor()); + else + shader->drawQuad(rect, m_ownTextureId, opacity); + } +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TileTexture.h b/Source/WebCore/platform/graphics/android/TileTexture.h new file mode 100644 index 0000000..e35f8df --- /dev/null +++ b/Source/WebCore/platform/graphics/android/TileTexture.h @@ -0,0 +1,100 @@ +/* + * Copyright 2010, 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 TileTexture_h +#define TileTexture_h + +#include "TextureInfo.h" +#include "Color.h" +#include "SkBitmap.h" +#include "SkRect.h" +#include "SkSize.h" + +#include + +class SkCanvas; + +namespace WebCore { + +class TextureOwner; +class Tile; +class TransformationMatrix; + +class TileTexture { +public: + // This object is to be constructed on the consumer's thread and must have + // a width and height greater than 0. + TileTexture(uint32_t w, uint32_t h); + virtual ~TileTexture(); + + // allows consumer thread to assign ownership of the texture to the tile. It + // returns false if ownership cannot be transferred because the tile is busy + bool acquire(TextureOwner* owner, bool force = false); + bool release(TextureOwner* owner); + + // set the texture owner if not busy. Return false if busy, true otherwise. + bool setOwner(TextureOwner* owner, bool force = false); + + // private member accessor functions + TextureOwner* owner() { return m_owner; } // only used by the consumer thread + + const SkSize& getSize() const { return m_size; } + + // OpenGL ID of backing texture, 0 when not allocated + GLuint m_ownTextureId; + // these are used for dynamically (de)allocating backing graphics memory + void requireGLTexture(); + void discardGLTexture(); + + void transferComplete(); + + TextureInfo* getTextureInfo() { return &m_ownTextureInfo; } + + // Make sure the following pureColor getter/setter are only read/written + // in UI thread. Therefore no need for a lock. + void setPure(bool pure) { m_isPureColor = pure; } + bool isPureColor() {return m_isPureColor; } + void setPureColor(const Color& color) { m_pureColor = color; setPure(true); } + Color pureColor() { return m_pureColor; } + + void drawGL(bool isLayer, const SkRect& rect, float opacity, + const TransformationMatrix* transform); +private: + TextureInfo m_ownTextureInfo; + SkSize m_size; + SkBitmap::Config m_config; + + // Tile owning the texture, only modified by UI thread + TextureOwner* m_owner; + + // When the whole tile is single color, skip the transfer queue and draw + // it directly through shader. + bool m_isPureColor; + Color m_pureColor; +}; + +} // namespace WebCore + +#endif // TileTexture_h diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp deleted file mode 100644 index 7087dc7..0000000 --- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp +++ /dev/null @@ -1,491 +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. - */ - -#define LOG_TAG "TiledTexture" -#define LOG_NDEBUG 1 - -#include "config.h" -#include "TiledTexture.h" - -#include "AndroidLog.h" -#include "PaintTileOperation.h" -#include "SkCanvas.h" -#include "SkPicture.h" -#include "TilesManager.h" - -#include - -#define LOW_RES_PREFETCH_SCALE_MODIFIER 0.3f -#define EXPANDED_BOUNDS_INFLATE 1 -#define EXPANDED_PREFETCH_BOUNDS_Y_INFLATE 1 - -namespace WebCore { - -TiledTexture::~TiledTexture() -{ -#ifdef DEBUG_COUNT - ClassTracker::instance()->decrement("TiledTexture"); -#endif - removeTiles(); -} - -bool TiledTexture::isReady() -{ - bool tilesAllReady = true; - bool tilesVisible = false; - for (unsigned int i = 0; i < m_tiles.size(); i++) { - BaseTile* tile = m_tiles[i]; - if (tile->isTileVisible(m_area)) { - tilesVisible = true; - if (!tile->isTileReady()) { - tilesAllReady = false; - break; - } - } - } - // For now, if no textures are available, consider ourselves as ready - // in order to unblock the zooming process. - // FIXME: have a better system -- maybe keeping the last scale factor - // able to fully render everything - ALOGV("TT %p, ready %d, visible %d, texturesRemain %d", - this, tilesAllReady, tilesVisible, - TilesManager::instance()->layerTexturesRemain()); - - return !TilesManager::instance()->layerTexturesRemain() - || !tilesVisible || tilesAllReady; -} - -bool TiledTexture::isMissingContent() -{ - for (unsigned int i = 0; i < m_tiles.size(); i++) - if (m_tiles[i]->isTileVisible(m_area) && !m_tiles[i]->frontTexture()) - return true; - return false; -} - -void TiledTexture::swapTiles() -{ - int swaps = 0; - for (unsigned int i = 0; i < m_tiles.size(); i++) - if (m_tiles[i]->swapTexturesIfNeeded()) - swaps++; - ALOGV("TT %p swapping, swaps = %d", this, swaps); -} - -IntRect TiledTexture::computeTilesArea(const IntRect& contentArea, float scale) -{ - IntRect computedArea; - IntRect area(contentArea.x() * scale, - contentArea.y() * scale, - ceilf(contentArea.width() * scale), - ceilf(contentArea.height() * scale)); - - ALOGV("TT %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height()); - - if (area.width() == 0 && area.height() == 0) { - computedArea.setWidth(0); - computedArea.setHeight(0); - return computedArea; - } - - int tileWidth = TilesManager::tileWidth(); - int tileHeight = TilesManager::tileHeight(); - - computedArea.setX(area.x() / tileWidth); - computedArea.setY(area.y() / tileHeight); - float right = (area.x() + area.width()) / (float) tileWidth; - float bottom = (area.y() + area.height()) / (float) tileHeight; - computedArea.setWidth(ceilf(right) - computedArea.x()); - computedArea.setHeight(ceilf(bottom) - computedArea.y()); - return computedArea; -} - -void TiledTexture::prepareGL(GLWebViewState* state, float scale, - const IntRect& prepareArea, const IntRect& unclippedArea, - TilePainter* painter, bool isLowResPrefetch, bool useExpandPrefetch) -{ - // first, how many tiles do we need - m_area = computeTilesArea(prepareArea, scale); - if (m_area.isEmpty()) - return; - - ALOGV("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(), - prepareArea.width(), prepareArea.height(), - m_area.x(), m_area.y(), - m_area.width(), m_area.height()); - - bool goingDown = m_prevTileY < m_area.y(); - m_prevTileY = m_area.y(); - - if (scale != m_scale) - TilesManager::instance()->removeOperationsForFilter(new ScaleFilter(painter, m_scale)); - - m_scale = 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(m_dirtyRegion); - - // log inval region for the base surface - if (m_isBaseSurface && TilesManager::instance()->getProfiler()->enabled()) { - SkRegion::Iterator iterator(m_dirtyRegion); - while (!iterator.done()) { - SkIRect r = iterator.rect(); - TilesManager::instance()->getProfiler()->nextInval(r, scale); - iterator.next(); - } - } - m_dirtyRegion.setEmpty(); - } - - // prepare standard bounds (clearing ExpandPrefetch flag) - for (int i = 0; i < m_area.width(); i++) { - if (goingDown) { - for (int j = 0; j < m_area.height(); j++) - prepareTile(m_area.x() + i, m_area.y() + j, - painter, state, isLowResPrefetch, false); - } else { - for (int j = m_area.height() - 1; j >= 0; j--) - prepareTile(m_area.x() + i, m_area.y() + j, - painter, state, isLowResPrefetch, false); - } - } - - // prepare expanded bounds - if (useExpandPrefetch) { - IntRect fullArea = computeTilesArea(unclippedArea, scale); - IntRect expandedArea = m_area; - expandedArea.inflate(EXPANDED_BOUNDS_INFLATE); - - if (isLowResPrefetch) - expandedArea.inflate(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE); - - // clip painting area to content - expandedArea.intersect(fullArea); - - for (int i = expandedArea.x(); i < expandedArea.maxX(); i++) - for (int j = expandedArea.y(); j < expandedArea.maxY(); j++) - if (!m_area.contains(i, j)) - prepareTile(i, j, painter, state, isLowResPrefetch, true); - } -} - -void TiledTexture::markAsDirty(const SkRegion& invalRegion) -{ - ALOGV("TT %p markAsDirty, current region empty %d, new empty %d", - this, m_dirtyRegion.isEmpty(), invalRegion.isEmpty()); - m_dirtyRegion.op(invalRegion, SkRegion::kUnion_Op); -} - -void TiledTexture::prepareTile(int x, int y, TilePainter* painter, - GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch) -{ - BaseTile* tile = getTile(x, y); - if (!tile) { - bool isLayerTile = !m_isBaseSurface; - tile = new BaseTile(isLayerTile); - m_tiles.append(tile); - } - - ALOGV("preparing tile %p at %d, %d, painter is %p", tile, x, y, painter); - - tile->setContents(x, y, m_scale, isExpandPrefetch); - - // TODO: move below (which is largely the same for layers / tiled page) into - // prepareGL() function - - if (tile->isDirty() || !tile->frontTexture()) - tile->reserveTexture(); - - if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending()) { - ALOGV("painting TT %p's tile %d %d for LG %p", this, x, y, painter); - PaintTileOperation *operation = new PaintTileOperation(tile, painter, - state, isLowResPrefetch); - TilesManager::instance()->scheduleOperation(operation); - } -} - -BaseTile* TiledTexture::getTile(int x, int y) -{ - for (unsigned int i = 0; i x() == x && tile->y() == y) - return tile; - } - return 0; -} - -int TiledTexture::nbTextures(IntRect& area, float scale) -{ - IntRect tileBounds = computeTilesArea(area, scale); - int numberTextures = tileBounds.width() * tileBounds.height(); - - // add the number of dirty tiles in the bounds, as they take up double - // textures for double buffering - for (unsigned int i = 0; i isDirty() - && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX() - && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY()) - numberTextures++; - } - return numberTextures; -} - -void TiledTexture::drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform, - const Color* background) -{ - m_area = computeTilesArea(visibleArea, m_scale); - if (m_area.width() == 0 || m_area.height() == 0) - return; - - float invScale = 1 / m_scale; - const float tileWidth = TilesManager::tileWidth() * invScale; - const float tileHeight = TilesManager::tileHeight() * invScale; - - int drawn = 0; - - SkRegion missingRegion; - bool translucentBaseSurface = - background ? (background->hasAlpha() && background->alpha() > 0) : false; - if (translucentBaseSurface) { - SkIRect totalArea = SkIRect::MakeXYWH(m_area.x(), m_area.y(), - m_area.width(), m_area.height()); - missingRegion = SkRegion(totalArea); - } - - for (unsigned int i = 0; i < m_tiles.size(); i++) { - BaseTile* tile = m_tiles[i]; - - bool tileInView = tile->isTileVisible(m_area); - if (tileInView) { - SkRect rect; - rect.fLeft = tile->x() * tileWidth; - rect.fTop = tile->y() * tileHeight; - rect.fRight = rect.fLeft + tileWidth; - rect.fBottom = rect.fTop + tileHeight; - ALOGV("tile %p (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d", - tile, tile->isLayerTile(), tile->x(), tile->y(), - tile->scale(), m_scale, tile->isTileReady(), tile->isDirty()); - - bool success = tile->drawGL(opacity, rect, m_scale, transform); - if (translucentBaseSurface && success) { - // Cut the successful drawn tile area from the missing region. - missingRegion.op(SkIRect::MakeXYWH(tile->x(), tile->y(), 1, 1), - SkRegion::kDifference_Op); - } - if (tile->frontTexture()) - drawn++; - } - - if (translucentBaseSurface) - TilesManager::instance()->getProfiler()->nextTile(tile, invScale, tileInView); - } - - // Draw missing Regions with blend turned on - if (translucentBaseSurface) - drawMissingRegion(missingRegion, opacity, background); - - ALOGV("TT %p drew %d tiles, scale %f", - this, drawn, m_scale); -} - -void TiledTexture::drawMissingRegion(const SkRegion& region, float opacity, - const Color* background) -{ - SkRegion::Iterator iterator(region); - const float tileWidth = TilesManager::tileWidth() / m_scale; - const float tileHeight = TilesManager::tileHeight() / m_scale; - ShaderProgram* shader = TilesManager::instance()->shader(); - while (!iterator.done()) { - SkIRect r = iterator.rect(); - SkRect rect; - rect.fLeft = r.x() * tileWidth; - rect.fTop = r.y() * tileHeight; - rect.fRight = rect.fLeft + tileWidth * r.width(); - rect.fBottom = rect.fTop + tileHeight * r.height(); - ALOGV("draw tile x y, %d %d (%d %d) opacity %f", r.x(), r.y(), - r.width(), r.height(), opacity); - // Skia is using pre-multiplied color. - Color postAlpha = Color(background->red() * background->alpha() / 255, - background->green() * background->alpha() / 255, - background->blue() * background->alpha() / 255, - background->alpha() ); - shader->drawQuad(rect, 0, opacity, postAlpha); - iterator.next(); - } -} - -void TiledTexture::removeTiles() -{ - for (unsigned int i = 0; i < m_tiles.size(); i++) { - delete m_tiles[i]; - } - m_tiles.clear(); -} - -void TiledTexture::discardTextures() -{ - ALOGV("TT %p discarding textures", this); - for (unsigned int i = 0; i < m_tiles.size(); i++) - m_tiles[i]->discardTextures(); -} - -DualTiledTexture::DualTiledTexture(bool isBaseSurface) -{ - m_frontTexture = new TiledTexture(isBaseSurface); - m_backTexture = new TiledTexture(isBaseSurface); - m_scale = -1; - m_futureScale = -1; - m_zooming = false; -} - -DualTiledTexture::~DualTiledTexture() -{ - delete m_frontTexture; - delete m_backTexture; -} - -void DualTiledTexture::prepareGL(GLWebViewState* state, bool allowZoom, - const IntRect& prepareArea, const IntRect& unclippedArea, - TilePainter* painter, bool aggressiveRendering) -{ - float scale = state->scale(); - if (scale > 1 && !allowZoom) - scale = 1; - - if (m_scale == -1) { - m_scale = scale; - m_futureScale = scale; - } - - if (m_futureScale != scale) { - m_futureScale = scale; - m_zoomUpdateTime = WTF::currentTime() + DualTiledTexture::s_zoomUpdateDelay; - m_zooming = true; - } - - bool useExpandPrefetch = aggressiveRendering; - ALOGV("Prepare DTT %p with scale %.2f, m_scale %.2f, futureScale: %.2f, zooming: %d, f %p, b %p", - this, scale, m_scale, m_futureScale, m_zooming, - m_frontTexture, m_backTexture); - - if (!m_zooming) { - m_frontTexture->prepareGL(state, m_scale, - prepareArea, unclippedArea, painter, false, useExpandPrefetch); - if (aggressiveRendering) { - // prepare the back tiled texture to render content in low res - float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER; - m_backTexture->prepareGL(state, lowResPrefetchScale, - prepareArea, unclippedArea, painter, true, useExpandPrefetch); - m_backTexture->swapTiles(); - } - } else if (m_zoomUpdateTime < WTF::currentTime()) { - m_backTexture->prepareGL(state, m_futureScale, - prepareArea, unclippedArea, painter, false, useExpandPrefetch); - if (m_backTexture->isReady()) { - // zooming completed, swap the textures and new front tiles - swapTiledTextures(); - - m_frontTexture->swapTiles(); - m_backTexture->discardTextures(); - - m_scale = m_futureScale; - m_zooming = false; - } - } -} - -void DualTiledTexture::drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform, - bool aggressiveRendering, const Color* background) -{ - // draw low res prefetch page, if needed - if (aggressiveRendering && !m_zooming && m_frontTexture->isMissingContent()) - m_backTexture->drawGL(visibleArea, opacity, transform); - - m_frontTexture->drawGL(visibleArea, opacity, transform, background); -} - -void DualTiledTexture::markAsDirty(const SkRegion& dirtyArea) -{ - m_backTexture->markAsDirty(dirtyArea); - m_frontTexture->markAsDirty(dirtyArea); -} - -void DualTiledTexture::swapTiles() -{ - m_backTexture->swapTiles(); - m_frontTexture->swapTiles(); -} - -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->isPositionFixed()) - result->fixed += nbTexturesClipped; - - // Set kScrollableAndFixedLayers level - if (layer->contentIsScrollable() - || layer->isPositionFixed()) - result->scrollable += nbTexturesClipped; - - // Set kClippedTextures level - result->clipped += nbTexturesClipped; - - // Set kAllTextures level - if (layer->contentIsScrollable()) - result->full += nbTexturesClipped; - else - result->full += nbTexturesUnclipped; -} - -void DualTiledTexture::swapTiledTextures() -{ - TiledTexture* temp = m_frontTexture; - m_frontTexture = m_backTexture; - m_backTexture = temp; -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h deleted file mode 100644 index 7a6c499..0000000 --- a/Source/WebCore/platform/graphics/android/TiledTexture.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2011, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TiledTexture_h -#define TiledTexture_h - -#include "BaseTile.h" -#include "BaseTileTexture.h" -#include "ClassTracker.h" -#include "IntRect.h" -#include "LayerAndroid.h" -#include "SkRefCnt.h" -#include "SkRegion.h" -#include "TextureOwner.h" -#include "TilePainter.h" - -class SkCanvas; - -namespace WebCore { - -class TiledTexture { -public: - TiledTexture(bool isBaseSurface) - : m_prevTileY(0) - , m_scale(1) - , m_isBaseSurface(isBaseSurface) - { - m_dirtyRegion.setEmpty(); -#ifdef DEBUG_COUNT - ClassTracker::instance()->increment("TiledTexture"); -#endif - } - - virtual ~TiledTexture(); - - static IntRect computeTilesArea(const IntRect& contentArea, float scale); - - void prepareGL(GLWebViewState* state, float scale, - const IntRect& prepareArea, const IntRect& unclippedArea, - TilePainter* painter, bool isLowResPrefetch = false, - bool useExpandPrefetch = false); - void swapTiles(); - void drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform, const Color* background = 0); - - void prepareTile(int x, int y, TilePainter* painter, - GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch); - void markAsDirty(const SkRegion& dirtyArea); - - BaseTile* getTile(int x, int y); - - void removeTiles(); - void discardTextures(); - - bool isReady(); - bool isMissingContent(); - - int nbTextures(IntRect& area, float scale); - -private: - void drawMissingRegion(const SkRegion& region, float opacity, const Color* tileBackground); - Vector m_tiles; - - IntRect m_area; - - SkRegion m_dirtyRegion; - - int m_prevTileY; - float m_scale; - - bool m_isBaseSurface; -}; - -class DualTiledTexture : public SkRefCnt { -// TODO: investigate webkit threadsafe ref counting -public: - DualTiledTexture(bool isBaseSurface); - ~DualTiledTexture(); - void prepareGL(GLWebViewState* state, bool allowZoom, - const IntRect& prepareArea, const IntRect& unclippedArea, - TilePainter* painter, bool aggressiveRendering); - void swapTiles(); - void drawGL(const IntRect& visibleArea, float opacity, - const TransformationMatrix* transform, bool aggressiveRendering, - const Color* background); - void markAsDirty(const SkRegion& dirtyArea); - void computeTexturesAmount(TexturesResult* result, LayerAndroid* layer); - void discardTextures() - { - m_frontTexture->discardTextures(); - m_backTexture->discardTextures(); - } - bool isReady() - { - return !m_zooming && m_frontTexture->isReady() && m_scale > 0; - } - - int nbTextures(IntRect& area, float scale) - { - // TODO: consider the zooming case for the backTexture - if (!m_frontTexture) - return 0; - return m_frontTexture->nbTextures(area, scale); - } - -private: - void swapTiledTextures(); - - // Delay before we schedule a new tile at the new scale factor - static const double s_zoomUpdateDelay = 0.2; // 200 ms - - TiledTexture* m_frontTexture; - TiledTexture* m_backTexture; - float m_scale; - float m_futureScale; - double m_zoomUpdateTime; - bool m_zooming; -}; - -} // namespace WebCore - -#endif // TiledTexture_h diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index eeedc07..109dc88 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -32,10 +32,14 @@ #if USE(ACCELERATED_COMPOSITING) #include "AndroidLog.h" -#include "BaseTile.h" +#include "GLWebViewState.h" #include "SkCanvas.h" #include "SkDevice.h" #include "SkPaint.h" +#include "Tile.h" +#include "TileTexture.h" +#include "TransferQueue.h" + #include #include #include @@ -108,12 +112,12 @@ void TilesManager::allocateTiles() ALOGV("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_maxTextureCount); int nbTexturesAllocated = 0; for (int i = 0; i < nbTexturesToAllocate; i++) { - BaseTileTexture* texture = new BaseTileTexture( + TileTexture* texture = new TileTexture( tileWidth(), tileHeight()); // the atomic load ensures that the texture has been fully initialized // before we pass a pointer for other threads to operate on - BaseTileTexture* loadedTexture = - reinterpret_cast( + TileTexture* loadedTexture = + reinterpret_cast( android_atomic_acquire_load(reinterpret_cast(&texture))); m_textures.append(loadedTexture); nbTexturesAllocated++; @@ -124,12 +128,12 @@ void TilesManager::allocateTiles() nbLayersTexturesToAllocate, m_maxLayerTextureCount); int nbLayersTexturesAllocated = 0; for (int i = 0; i < nbLayersTexturesToAllocate; i++) { - BaseTileTexture* texture = new BaseTileTexture( + TileTexture* texture = new TileTexture( tileWidth(), tileHeight()); // the atomic load ensures that the texture has been fully initialized // before we pass a pointer for other threads to operate on - BaseTileTexture* loadedTexture = - reinterpret_cast( + TileTexture* loadedTexture = + reinterpret_cast( android_atomic_acquire_load(reinterpret_cast(&texture))); m_tilesTextures.append(loadedTexture); nbLayersTexturesAllocated++; @@ -160,7 +164,7 @@ void TilesManager::discardTextures(bool allTextures, bool glTextures) } void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount, - WTF::Vector& textures, + WTF::Vector& textures, bool deallocateGLTextures) { const unsigned int max = textures.size(); @@ -175,14 +179,14 @@ void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount, discardedIndex.append(i); } else if (owner) { // simply detach textures from owner - static_cast(owner)->discardTextures(); + static_cast(owner)->discardTextures(); } dealloc++; } } bool base = textures == m_textures; - // Clean up the vector of BaseTileTextures and reset the max texture count. + // Clean up the vector of TileTextures and reset the max texture count. if (discardedIndex.size()) { android::Mutex::Autolock lock(m_texturesLock); for (int i = discardedIndex.size() - 1; i >= 0; i--) @@ -208,13 +212,13 @@ void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextur { *nbTextures = m_textures.size(); for (unsigned int i = 0; i < m_textures.size(); i++) { - BaseTileTexture* texture = m_textures[i]; + TileTexture* texture = m_textures[i]; if (texture->m_ownTextureId) *nbAllocatedTextures += 1; } *nbLayerTextures = m_tilesTextures.size(); for (unsigned int i = 0; i < m_tilesTextures.size(); i++) { - BaseTileTexture* texture = m_tilesTextures[i]; + TileTexture* texture = m_tilesTextures[i]; if (texture->m_ownTextureId) *nbAllocatedLayerTextures += 1; } @@ -225,10 +229,10 @@ void TilesManager::printTextures() #ifdef DEBUG ALOGV("++++++"); for (unsigned int i = 0; i < m_textures.size(); i++) { - BaseTileTexture* texture = m_textures[i]; - BaseTile* o = 0; + TileTexture* texture = m_textures[i]; + Tile* o = 0; if (texture->owner()) - o = (BaseTile*) texture->owner(); + o = (Tile*) texture->owner(); int x = -1; int y = -1; if (o) { @@ -251,7 +255,7 @@ void TilesManager::gatherTextures() m_layerTexturesRemain = true; } -BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) +TileTexture* TilesManager::getAvailableTexture(Tile* owner) { android::Mutex::Autolock lock(m_texturesLock); @@ -266,7 +270,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) return owner->backTexture(); } - WTF::Vector* availableTexturePool; + WTF::Vector* availableTexturePool; if (owner->isLayerTile()) { availableTexturePool = &m_availableTilesTextures; } else { @@ -281,12 +285,12 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) // 4. Otherwise, use the least recently prepared tile, but ignoring tiles // drawn in the last frame to avoid flickering - BaseTileTexture* farthestTexture = 0; + TileTexture* farthestTexture = 0; unsigned long long oldestDrawCount = getDrawGLCount() - 1; const unsigned int max = availableTexturePool->size(); for (unsigned int i = 0; i < max; i++) { - BaseTileTexture* texture = (*availableTexturePool)[i]; - BaseTile* currentOwner = static_cast(texture->owner()); + TileTexture* texture = (*availableTexturePool)[i]; + Tile* currentOwner = static_cast(texture->owner()); if (!currentOwner) { // unused texture! take it! farthestTexture = texture; @@ -307,7 +311,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner) } if (farthestTexture) { - BaseTile* previousOwner = static_cast(farthestTexture->owner()); + Tile* previousOwner = static_cast(farthestTexture->owner()); if (farthestTexture->acquire(owner)) { if (previousOwner) { previousOwner->removeTexture(farthestTexture); diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h index 05fc1af..650e0f1 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/TilesManager.h @@ -28,21 +28,26 @@ #if USE(ACCELERATED_COMPOSITING) -#include "BaseTile.h" -#include "BaseTileTexture.h" -#include "ImageTexture.h" +/* #include "Tile.h" */ +/* #include "TileTexture.h" */ +/* #include "ImageTexture.h" */ #include "LayerAndroid.h" #include "ShaderProgram.h" -#include "SkBitmapRef.h" +/* #include "SkBitmapRef.h" */ #include "TexturesGenerator.h" #include "TilesProfiler.h" -#include "TransferQueue.h" +/* #include "TransferQueue.h" */ #include "VideoLayerManager.h" #include #include namespace WebCore { +class OperationFilter; +class Tile; +class TileTexture; +class TransferQueue; + class TilesManager { public: // May only be called from the UI thread @@ -74,7 +79,7 @@ public: void gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures, int* nbLayerTextures, int* nbAllocatedLayerTextures); - BaseTileTexture* getAvailableTexture(BaseTile* owner); + TileTexture* getAvailableTexture(Tile* owner); void printTextures(); @@ -161,14 +166,14 @@ private: TilesManager(); void discardTexturesVector(unsigned long long sparedDrawCount, - WTF::Vector& textures, + WTF::Vector& textures, bool deallocateGLTextures); - Vector m_textures; - Vector m_availableTextures; + WTF::Vector m_textures; + WTF::Vector m_availableTextures; - Vector m_tilesTextures; - Vector m_availableTilesTextures; + WTF::Vector m_tilesTextures; + WTF::Vector m_availableTilesTextures; bool m_layerTexturesRemain; bool m_highEndGfx; diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp b/Source/WebCore/platform/graphics/android/TilesProfiler.cpp index 2cc6873..4f0c6b5 100644 --- a/Source/WebCore/platform/graphics/android/TilesProfiler.cpp +++ b/Source/WebCore/platform/graphics/android/TilesProfiler.cpp @@ -32,6 +32,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "AndroidLog.h" +#include "Tile.h" #include "TilesManager.h" #include @@ -92,7 +93,7 @@ void TilesProfiler::nextFrame(int left, int top, int right, int bottom, float sc scale, true, (int)(timeDelta * 1000))); } -void TilesProfiler::nextTile(BaseTile* tile, float scale, bool inView) +void TilesProfiler::nextTile(Tile* tile, float scale, bool inView) { if (!m_enabled || (m_records.size() > MAX_PROF_FRAMES) || (m_records.size() == 0)) return; diff --git a/Source/WebCore/platform/graphics/android/TilesProfiler.h b/Source/WebCore/platform/graphics/android/TilesProfiler.h index a13d471..b39ae2f 100644 --- a/Source/WebCore/platform/graphics/android/TilesProfiler.h +++ b/Source/WebCore/platform/graphics/android/TilesProfiler.h @@ -28,12 +28,14 @@ #if USE(ACCELERATED_COMPOSITING) -#include "BaseTile.h" #include "IntRect.h" -#include "Vector.h" +#include "SkRect.h" +#include namespace WebCore { +class Tile; + struct TileProfileRecord { TileProfileRecord(int left, int top, int right, int bottom, float scale, int isReady, int level) { this->left = left; @@ -58,7 +60,7 @@ public: float stop(); void clear(); void nextFrame(int left, int top, int right, int bottom, float scale); - void nextTile(BaseTile* tile, float scale, bool inView); + void nextTile(Tile* tile, float scale, bool inView); void nextInval(const SkIRect& rect, float scale); int numFrames() { return m_records.size(); @@ -78,7 +80,7 @@ private: bool m_enabled; unsigned int m_goodTiles; unsigned int m_badTiles; - Vector > m_records; + WTF::Vector > m_records; double m_time; }; diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index a3552ac..469438f 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -32,8 +32,9 @@ #if USE(ACCELERATED_COMPOSITING) #include "AndroidLog.h" -#include "BaseTile.h" +#include "Tile.h" #include "GLUtils.h" +#include "TileTexture.h" #include "TilesManager.h" #include #include @@ -124,28 +125,28 @@ void TransferQueue::initGLResources(int width, int height) } // When bliting, if the item from the transfer queue is mismatching b/t the -// BaseTile and the content, then the item is considered as obsolete, and +// Tile and the content, then the item is considered as obsolete, and // the content is discarded. bool TransferQueue::checkObsolete(const TileTransferData* data) { - BaseTile* baseTilePtr = data->savedBaseTilePtr; + Tile* baseTilePtr = data->savedTilePtr; if (!baseTilePtr) { - ALOGV("Invalid savedBaseTilePtr , such that the tile is obsolete"); + ALOGV("Invalid savedTilePtr , such that the tile is obsolete"); return true; } - BaseTileTexture* baseTileTexture = baseTilePtr->backTexture(); - if (!baseTileTexture || baseTileTexture != data->savedBaseTileTexturePtr) { + TileTexture* baseTileTexture = baseTilePtr->backTexture(); + if (!baseTileTexture || baseTileTexture != data->savedTileTexturePtr) { ALOGV("Invalid baseTileTexture %p (vs expected %p), such that the tile is obsolete", - baseTileTexture, data->savedBaseTileTexturePtr); + baseTileTexture, data->savedTileTexturePtr); return true; } return false; } -void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, - BaseTileTexture* frontTex, +void TransferQueue::blitTileFromQueue(GLuint fboID, TileTexture* destTex, + TileTexture* frontTex, GLuint srcTexId, GLenum srcTexTarget, int index) { @@ -327,10 +328,10 @@ void TransferQueue::updatePureColorTiles() for (unsigned int i = 0 ; i < m_pureColorTileQueue.size(); i++) { TileTransferData* data = &m_pureColorTileQueue[i]; if (data->status == pendingBlit) { - BaseTileTexture* destTexture = 0; - bool obsoleteBaseTile = checkObsolete(data); - if (!obsoleteBaseTile) { - destTexture = data->savedBaseTilePtr->backTexture(); + TileTexture* destTexture = 0; + bool obsoleteTile = checkObsolete(data); + if (!obsoleteTile) { + destTexture = data->savedTilePtr->backTexture(); destTexture->setPureColor(data->pureColor); destTexture->transferComplete(); } @@ -342,8 +343,8 @@ void TransferQueue::updatePureColorTiles() m_pureColorTileQueue.clear(); } -// Call on UI thread to copy from the shared Surface Texture to the BaseTile's texture. -void TransferQueue::updateDirtyBaseTiles() +// Call on UI thread to copy from the shared Surface Texture to the Tile's texture. +void TransferQueue::updateDirtyTiles() { android::Mutex::Autolock lock(m_transferQueueItemLocks); @@ -355,22 +356,22 @@ void TransferQueue::updateDirtyBaseTiles() updatePureColorTiles(); // Start from the oldest item, we call the updateTexImage to retrive - // the texture and blit that into each BaseTile's texture. + // the texture and blit that into each Tile's texture. const int nextItemIndex = getNextTransferQueueIndex(); int index = nextItemIndex; bool usedFboForUpload = false; for (int k = 0; k < m_transferQueueSize ; k++) { if (m_transferQueue[index].status == pendingBlit) { - bool obsoleteBaseTile = checkObsolete(&m_transferQueue[index]); + bool obsoleteTile = checkObsolete(&m_transferQueue[index]); // Save the needed info, update the Surf Tex, clean up the item in // the queue. Then either move on to next item or copy the content. - BaseTileTexture* destTexture = 0; - BaseTileTexture* frontTexture = 0; - if (!obsoleteBaseTile) { - destTexture = m_transferQueue[index].savedBaseTilePtr->backTexture(); + TileTexture* destTexture = 0; + TileTexture* frontTexture = 0; + if (!obsoleteTile) { + destTexture = m_transferQueue[index].savedTilePtr->backTexture(); // while destTexture is guaranteed to not be null, frontTexture // might be (first transfer) - frontTexture = m_transferQueue[index].savedBaseTilePtr->frontTexture(); + frontTexture = m_transferQueue[index].savedTilePtr->frontTexture(); } if (m_transferQueue[index].uploadType == GpuUpload) { @@ -378,9 +379,9 @@ void TransferQueue::updateDirtyBaseTiles() if (result != OK) ALOGE("unexpected error: updateTexImage return %d", result); } - m_transferQueue[index].savedBaseTilePtr = 0; + m_transferQueue[index].savedTilePtr = 0; m_transferQueue[index].status = emptyItem; - if (obsoleteBaseTile) { + if (obsoleteTile) { ALOGV("Warning: the texture is obsolete for this baseTile"); index = (index + 1) % m_transferQueueSize; continue; @@ -409,7 +410,7 @@ void TransferQueue::updateDirtyBaseTiles() destTexture->transferComplete(); ALOGV("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d", - m_transferQueue[index].savedBaseTilePtr, + m_transferQueue[index].savedTilePtr, destTexture, destTexture->m_ownTextureId); } @@ -422,7 +423,7 @@ void TransferQueue::updateDirtyBaseTiles() if (usedFboForUpload) { glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO restoreGLState(); - GLUtils::checkGlError("updateDirtyBaseTiles"); + GLUtils::checkGlError("updateDirtyTiles"); } m_emptyItemCount = m_transferQueueSize; @@ -435,7 +436,7 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo, if (!tryUpdateQueueWithBitmap(renderInfo, bitmap)) { // failed placing bitmap in queue, discard tile's texture so it will be // re-enqueued (and repainted) - BaseTile* tile = renderInfo->baseTile; + Tile* tile = renderInfo->baseTile; if (tile) tile->backTextureTransferFail(); } @@ -492,8 +493,8 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo, TextureUploadType type, TileTransferData* data) { - data->savedBaseTileTexturePtr = renderInfo->baseTile->backTexture(); - data->savedBaseTilePtr = renderInfo->baseTile; + data->savedTileTexturePtr = renderInfo->baseTile->backTexture(); + data->savedTilePtr = renderInfo->baseTile; data->status = pendingBlit; data->uploadType = type; @@ -516,7 +517,7 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo, m_transferQueueIndex = (m_transferQueueIndex + 1) % m_transferQueueSize; int index = m_transferQueueIndex; - if (m_transferQueue[index].savedBaseTilePtr + if (m_transferQueue[index].savedTilePtr || m_transferQueue[index].status != emptyItem) { ALOGV("ERROR update a tile which is dirty already @ index %d", index); } @@ -550,7 +551,7 @@ void TransferQueue::setTextureUploadType(TextureUploadType type) } // Note: this need to be called within the lock and on the UI thread. -// Only called by updateDirtyBaseTiles() and emptyQueue() for now +// Only called by updateDirtyTiles() and emptyQueue() for now void TransferQueue::cleanupPendingDiscard() { int index = getNextTransferQueueIndex(); @@ -568,8 +569,8 @@ void TransferQueue::cleanupPendingDiscard() // since tiles in the queue may be from another webview, remove // their textures so that they will be repainted / retransferred - BaseTile* tile = m_transferQueue[index].savedBaseTilePtr; - BaseTileTexture* texture = m_transferQueue[index].savedBaseTileTexturePtr; + Tile* tile = m_transferQueue[index].savedTilePtr; + TileTexture* texture = m_transferQueue[index].savedTileTexturePtr; if (tile && texture && texture->owner() == tile) { // since tile destruction removes textures on the UI thread, the // texture->owner ptr guarantees the tile is valid @@ -577,8 +578,8 @@ void TransferQueue::cleanupPendingDiscard() ALOGV("transfer queue discarded tile %p, removed texture", tile); } - m_transferQueue[index].savedBaseTilePtr = 0; - m_transferQueue[index].savedBaseTileTexturePtr = 0; + m_transferQueue[index].savedTilePtr = 0; + m_transferQueue[index].savedTileTexturePtr = 0; m_transferQueue[index].status = emptyItem; } index = (index + 1) % m_transferQueueSize; diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h index b00ea17..65ff116 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/TransferQueue.h @@ -28,13 +28,17 @@ #if USE(ACCELERATED_COMPOSITING) -#include "BaseTile.h" -#include "BaseTileTexture.h" +#include "GLUtils.h" #include "ShaderProgram.h" -#include +#include "SkBitmap.h" +#include +#include namespace WebCore { +class Tile; +class TileTexture; + struct GLState { GLint viewport[4]; GLboolean scissor[1]; @@ -43,7 +47,7 @@ struct GLState { }; -// While in the queue, the BaseTile can be re-used, the updated bitmap +// While in the queue, the Tile can be re-used, the updated bitmap // can be discarded. In order to track this obsolete base tiles, we save // the Tile's Info to make the comparison. // At the time of base tile's dtor or webview destroy, we want to discard @@ -69,8 +73,8 @@ class TileTransferData { public: TileTransferData() : status(emptyItem) - , savedBaseTilePtr(0) - , savedBaseTileTexturePtr(0) + , savedTilePtr(0) + , savedTileTexturePtr(0) , uploadType(DEFAULT_UPLOAD_TYPE) , bitmap(0) , m_syncKHR(EGL_NO_SYNC_KHR) @@ -84,8 +88,8 @@ public: } TransferItemStatus status; - BaseTile* savedBaseTilePtr; - BaseTileTexture* savedBaseTileTexturePtr; + Tile* savedTilePtr; + TileTexture* savedTileTexturePtr; IntRect invalRect; TextureUploadType uploadType; // This is only useful in Cpu upload code path, so it will be dynamically @@ -113,7 +117,7 @@ public: // This will be called by the browser through nativeSetProperty void setTextureUploadType(TextureUploadType type); void cleanupGLResources(); - void updateDirtyBaseTiles(); + void updateDirtyTiles(); void initGLResources(int width, int height); @@ -143,7 +147,7 @@ public: // a lock to protect its access TileTransferData* m_transferQueue; - sp m_ANW; + android::sp m_ANW; // EGL wrapper around m_ANW for use by the GaneshRenderer EGLSurface m_eglSurface; @@ -170,8 +174,8 @@ private: // pendingDiscard items. void cleanupPendingDiscard(); - void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, - BaseTileTexture* frontTex, + void blitTileFromQueue(GLuint fboID, TileTexture* destTex, + TileTexture* frontTex, GLuint srcTexId, GLenum srcTexTarget, int index); @@ -191,7 +195,7 @@ private: bool m_hasGLContext; GLState m_GLStateBeforeBlit; - sp m_sharedSurfaceTexture; + android::sp m_sharedSurfaceTexture; int m_emptyItemCount; diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp index 756bf28..6669d49 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.cpp @@ -30,6 +30,7 @@ #include "VideoLayerAndroid.h" #include "AndroidLog.h" +#include "ShaderProgram.h" #include "TilesManager.h" #include #include diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h index 29b1bdc..dd88a85 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h @@ -30,7 +30,6 @@ #include "GLUtils.h" #include "LayerAndroid.h" -#include "ShaderProgram.h" #include namespace android { diff --git a/Source/WebCore/platform/graphics/android/VideoLayerManager.h b/Source/WebCore/platform/graphics/android/VideoLayerManager.h index c8e420e..6c02534 100644 --- a/Source/WebCore/platform/graphics/android/VideoLayerManager.h +++ b/Source/WebCore/platform/graphics/android/VideoLayerManager.h @@ -30,6 +30,7 @@ #include "IntRect.h" #include #include +#include #if USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp index bfce349..3fdc3e6 100644 --- a/Source/WebKit/android/jni/ViewStateSerializer.cpp +++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp @@ -40,6 +40,7 @@ #include "PictureLayerContent.h" #include "PictureSet.h" #include "ScrollableLayerAndroid.h" +#include "SkFlattenable.h" #include "SkPicture.h" #include "TilesManager.h" diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 9907e6f..a4381e6 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -30,8 +30,10 @@ #include "AndroidAnimation.h" #include "AndroidLog.h" #include "BaseLayerAndroid.h" +#include "BaseRenderer.h" #include "DrawExtra.h" #include "Frame.h" +#include "GLWebViewState.h" #include "GraphicsJNI.h" #include "HTMLInputElement.h" #include "IntPoint.h" @@ -51,6 +53,7 @@ #include "SkRect.h" #include "SkTime.h" #include "TilesManager.h" +#include "TransferQueue.h" #include "WebCoreJni.h" #include "WebRequestContext.h" #include "WebViewCore.h" diff --git a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp index 513d251..92dbbcd 100644 --- a/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp +++ b/Source/WebKit/android/plugins/ANPSurfaceInterface.cpp @@ -47,7 +47,7 @@ static struct ANPSurfaceInterfaceJavaGlue { jfieldID surfacePointer; } gSurfaceJavaGlue; -static inline sp getSurface(JNIEnv* env, jobject view) { +static inline sp getSurface(JNIEnv* env, jobject view) { if (!env || !view) { return NULL; } @@ -80,7 +80,7 @@ static inline sp getSurface(JNIEnv* env, jobject view) { env->DeleteLocalRef(holder); env->DeleteLocalRef(surface); - return sp((Surface*) surfacePointer); + return sp((android::Surface*) surfacePointer); } static inline ANPBitmapFormat convertPixelFormat(PixelFormat format) { @@ -96,9 +96,9 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec return false; } - sp surface = getSurface(env, surfaceView); + sp surface = getSurface(env, surfaceView); - if (!bitmap || !Surface::isValid(surface)) { + if (!bitmap || !android::Surface::isValid(surface)) { return false; } @@ -112,7 +112,7 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec dirtyRegion.set(Rect(0x3FFF, 0x3FFF)); } - Surface::SurfaceInfo info; + android::Surface::SurfaceInfo info; status_t err = surface->lock(&info, &dirtyRegion); if (err < 0) { return false; @@ -150,9 +150,9 @@ static void anp_unlock(JNIEnv* env, jobject surfaceView) { return; } - sp surface = getSurface(env, surfaceView); + sp surface = getSurface(env, surfaceView); - if (!Surface::isValid(surface)) { + if (!android::Surface::isValid(surface)) { return; } -- cgit v1.1