summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2012-02-23 13:10:41 -0800
committerChris Craik <ccraik@google.com>2012-02-28 16:18:19 -0800
commitd8be9016b7fda67a91b4ee17b3b2e7ba692ee553 (patch)
tree071de9016650d451a21cb3bb1c2fee3c914b33b6 /Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
parent7a5ba79e8c522b61d1dba7cb6766ee6bc756386f (diff)
downloadexternal_webkit-d8be9016b7fda67a91b4ee17b3b2e7ba692ee553.zip
external_webkit-d8be9016b7fda67a91b4ee17b3b2e7ba692ee553.tar.gz
external_webkit-d8be9016b7fda67a91b4ee17b3b2e7ba692ee553.tar.bz2
layer rendering cleanup/rewrite
* added 'LayerGroup' class separate the painting/tiled features of a layer (eventually multiple layers) tiled drawing/preparing/counting details are abstracted out of LayerAndroid * added 'SurfaceCollection' class incorporates both the BaseLayerAndroid/LayerAndroid tree, as well as the vector of tiled LayerGroup * renamed 'TreeManager' to 'SurfaceManager' * Removes PaintedSurface was mostly a thin wrapper around DualTiledTexture * Combines TilePainter/SurfacePainter * Simplified ref counting Change-Id: I92c5c75f48d92e0e28812c56de00102399fc02ee
Diffstat (limited to 'Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp')
-rw-r--r--Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp287
1 files changed, 287 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
new file mode 100644
index 0000000..8ffcabd
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/SurfaceCollectionManager.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SurfaceCollectionManager.h"
+
+#include "BaseLayerAndroid.h"
+#include "LayerGroup.h"
+#include "TilesManager.h"
+#include "SurfaceCollection.h"
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "SurfaceCollectionManager", __VA_ARGS__)
+
+#ifdef DEBUG
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "SurfaceCollectionManager", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+SurfaceCollectionManager::SurfaceCollectionManager(GLWebViewState* state)
+ : m_state(state)
+ , m_drawingCollection(0)
+ , m_paintingCollection(0)
+ , m_queuedCollection(0)
+ , m_fastSwapMode(false)
+{
+}
+
+SurfaceCollectionManager::~SurfaceCollectionManager()
+{
+ clearCollections();
+}
+
+// the painting collection has finished painting:
+// discard the drawing collection
+// swap the painting collection in place of the drawing collection
+// and start painting the queued collection
+void SurfaceCollectionManager::swap()
+{
+ // swap can't be called unless painting just finished
+ ASSERT(m_paintingCollection);
+
+ android::Mutex::Autolock lock(m_paintSwapLock);
+
+ XLOG("SWAPPING, D %p, P %p, Q %p",
+ m_drawingCollection, m_paintingCollection, m_queuedCollection);
+
+ // if we have a drawing collection, discard it since the painting collection is done
+ if (m_drawingCollection) {
+ XLOG("destroying drawing collection %p", m_drawingCollection);
+ SkSafeUnref(m_drawingCollection);
+ }
+
+ // painting collection becomes the drawing collection
+ XLOG("drawing collection %p", m_paintingCollection);
+ m_paintingCollection->setIsDrawing(); // initialize animations
+
+ if (m_queuedCollection) {
+ // start painting with the queued collection
+ XLOG("now painting collection %p", m_queuedCollection);
+ m_queuedCollection->setIsPainting(m_paintingCollection);
+ }
+ m_drawingCollection = m_paintingCollection;
+ m_paintingCollection = m_queuedCollection;
+ m_queuedCollection = 0;
+
+ XLOG("SWAPPING COMPLETE, D %p, P %p, Q %p",
+ m_drawingCollection, m_paintingCollection, m_queuedCollection);
+}
+
+// clear all of the content in the three collections held by the collection manager
+void SurfaceCollectionManager::clearCollections()
+{
+ XLOG("SurfaceCollectionManager %p removing PS from state %p", this, m_state);
+
+ SkSafeUnref(m_drawingCollection);
+ m_drawingCollection = 0;
+ SkSafeUnref(m_paintingCollection);
+ m_paintingCollection = 0;
+ SkSafeUnref(m_queuedCollection);
+ m_queuedCollection = 0;
+}
+
+// a new layer collection has arrived, queue it if we're painting something already,
+// or start painting it if we aren't. Returns true if the manager has two collections
+// already queued.
+bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* newCollection,
+ bool brandNew)
+{
+ XLOG("updateWithSurfaceCollection - %p, has children %d, has animations %d",
+ newCollection, newCollection->hasCompositedLayers(),
+ newCollection->hasCompositedAnimations);
+
+ // can't have a queued collection unless have a painting collection too
+ ASSERT(m_paintingCollection || !m_queuedCollection);
+
+ android::Mutex::Autolock lock(m_paintSwapLock);
+
+ if (!newCollection || brandNew) {
+ clearCollections();
+ if (brandNew) {
+ m_paintingCollection = newCollection;
+ m_paintingCollection->setIsPainting(m_drawingCollection);
+ }
+ return false;
+ }
+
+ if (m_queuedCollection || m_paintingCollection) {
+ // currently painting, so defer this new collection
+ if (m_queuedCollection) {
+ // already have a queued collection, copy over invals so the regions are
+ // eventually repainted and let the old queued collection be discarded
+ m_queuedCollection->mergeInvalsInto(newCollection);
+
+ if (!TilesManager::instance()->useDoubleBuffering()) {
+ // not double buffering, count discarded collection/webkit paint as an update
+ TilesManager::instance()->incContentUpdates();
+ }
+
+ XLOG("DISCARDING collection - %p, has children %d, has animations %d",
+ newCollection, newCollection->hasCompositedLayers(),
+ newCollection->hasCompositedAnimations());
+ }
+ SkSafeUnref(m_queuedCollection);
+ m_queuedCollection = newCollection;
+ } else {
+ // don't have painting collection, paint this one!
+ m_paintingCollection = newCollection;
+ m_paintingCollection->setIsPainting(m_drawingCollection);
+ }
+ return m_drawingCollection && TilesManager::instance()->useDoubleBuffering();
+}
+
+void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y)
+{
+ if (m_queuedCollection)
+ m_queuedCollection->updateScrollableLayer(layerId, x, y);
+ if (m_paintingCollection)
+ m_paintingCollection->updateScrollableLayer(layerId, x, y);
+ if (m_drawingCollection)
+ m_drawingCollection->updateScrollableLayer(layerId, x, y);
+}
+
+bool SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
+ SkRect& visibleRect, float scale,
+ bool enterFastSwapMode,
+ bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
+ TexturesResult* texturesResultPtr)
+{
+ m_fastSwapMode |= enterFastSwapMode;
+
+ XLOG("drawGL, D %p, P %p, Q %p, fastSwap %d",
+ m_drawingCollection, m_paintingCollection, m_queuedCollection, m_fastSwapMode);
+
+ bool ret = false;
+ bool didCollectionSwap = false;
+ if (m_paintingCollection) {
+ XLOG("preparing painting collection %p", m_paintingCollection);
+
+ m_paintingCollection->evaluateAnimations(currentTime);
+
+ m_paintingCollection->prepareGL(visibleRect, scale, currentTime);
+ m_paintingCollection->computeTexturesAmount(texturesResultPtr);
+
+ if (!TilesManager::instance()->useDoubleBuffering() || m_paintingCollection->isReady()) {
+ XLOG("have painting collection %p ready, swapping!", m_paintingCollection);
+ didCollectionSwap = true;
+ TilesManager::instance()->incContentUpdates();
+ if (collectionsSwappedPtr)
+ *collectionsSwappedPtr = true;
+ if (newCollectionHasAnimPtr)
+ *newCollectionHasAnimPtr = m_paintingCollection->hasCompositedAnimations();
+ swap();
+ }
+ } else if (m_drawingCollection) {
+ XLOG("preparing drawing collection %p", m_drawingCollection);
+ m_drawingCollection->prepareGL(visibleRect, scale, currentTime);
+ m_drawingCollection->computeTexturesAmount(texturesResultPtr);
+ }
+
+ if (m_drawingCollection) {
+ bool drawingReady = didCollectionSwap || m_drawingCollection->isReady();
+
+ // call the page swap callback if registration happened without more collections enqueued
+ if (collectionsSwappedPtr && drawingReady && !m_paintingCollection)
+ *collectionsSwappedPtr = true;
+
+ if (didCollectionSwap || m_fastSwapMode || (drawingReady && !m_paintingCollection))
+ m_drawingCollection->swapTiles();
+
+ if (drawingReady) {
+ // exit fast swap mode, as content is up to date
+ m_fastSwapMode = false;
+ } else {
+ // drawing isn't ready, must redraw
+ ret = true;
+ }
+
+ m_drawingCollection->evaluateAnimations(currentTime);
+ XLOG("drawing collection %p", m_drawingCollection);
+ ret |= m_drawingCollection->drawGL(visibleRect, scale);
+ } else {
+ // Dont have a drawing collection, draw white background
+ Color defaultBackground = Color::white;
+ m_state->drawBackground(defaultBackground);
+ }
+
+ if (m_paintingCollection) {
+ XLOG("still have painting collection %p", m_paintingCollection);
+ return true;
+ }
+
+ return ret;
+}
+
+// draw for base tile - called on TextureGeneration thread
+void SurfaceCollectionManager::drawCanvas(SkCanvas* canvas, bool drawLayers)
+{
+ SurfaceCollection* paintingCollection = 0;
+ m_paintSwapLock.lock();
+ paintingCollection = m_paintingCollection ? m_paintingCollection : m_drawingCollection;
+ SkSafeRef(paintingCollection);
+ m_paintSwapLock.unlock();
+
+ if (!paintingCollection)
+ return;
+
+ paintingCollection->drawCanvas(canvas, drawLayers);
+
+ SkSafeUnref(paintingCollection);
+}
+
+// TODO: refactor this functionality elsewhere
+int SurfaceCollectionManager::baseContentWidth()
+{
+ if (m_paintingCollection)
+ return m_paintingCollection->baseContentWidth();
+ else if (m_drawingCollection)
+ return m_drawingCollection->baseContentWidth();
+ return 0;
+}
+
+int SurfaceCollectionManager::baseContentHeight()
+{
+ if (m_paintingCollection)
+ return m_paintingCollection->baseContentHeight();
+ else if (m_drawingCollection)
+ return m_drawingCollection->baseContentHeight();
+ return 0;
+}
+
+} // namespace WebCore