summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/LayerGroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/android/LayerGroup.cpp')
-rw-r--r--Source/WebCore/platform/graphics/android/LayerGroup.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/android/LayerGroup.cpp b/Source/WebCore/platform/graphics/android/LayerGroup.cpp
new file mode 100644
index 0000000..e9f8967
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/LayerGroup.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LayerGroup.h"
+
+#include "ClassTracker.h"
+#include "LayerAndroid.h"
+#include "TiledTexture.h"
+#include "TilesManager.h"
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/text/CString.h>
+
+#undef XLOGC
+#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "LayerGroup", __VA_ARGS__)
+
+#ifdef DEBUG
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "LayerGroup", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+// LayerGroups with an area larger than 2048*2048 should never be unclipped
+#define MAX_UNCLIPPED_AREA 4194304
+
+#define TEMP_LAYER m_layers[0]
+
+namespace WebCore {
+
+LayerGroup::LayerGroup()
+ : m_hasText(false)
+ , m_dualTiledTexture(0)
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->increment("LayerGroup");
+#endif
+}
+
+LayerGroup::~LayerGroup()
+{
+ for (unsigned int i = 0; i < m_layers.size(); i++)
+ SkSafeUnref(m_layers[i]);
+ if (m_dualTiledTexture)
+ SkSafeUnref(m_dualTiledTexture);
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("LayerGroup");
+#endif
+}
+
+void LayerGroup::initializeGroup(LayerAndroid* newLayer, const SkRegion& newLayerInval,
+ LayerAndroid* oldLayer)
+{
+ if (!newLayer->needsTexture())
+ return;
+
+ XLOG("init on LG %p, layer %p, oldlayer %p", this, newLayer, oldLayer);
+ if (oldLayer && oldLayer->group() && oldLayer->group()->m_dualTiledTexture) {
+ // steal DTT from old group, and apply new inval
+ m_dualTiledTexture = oldLayer->group()->m_dualTiledTexture;
+ SkSafeRef(m_dualTiledTexture);
+ m_dualTiledTexture->markAsDirty(newLayerInval);
+ } else
+ m_dualTiledTexture = new DualTiledTexture();
+ }
+
+void LayerGroup::addLayer(LayerAndroid* layer)
+{
+ m_layers.append(layer);
+ SkSafeRef(layer);
+}
+
+void LayerGroup::prepareGL(bool layerTilesDisabled)
+{
+ if (!m_dualTiledTexture)
+ return;
+
+ if (layerTilesDisabled) {
+ m_dualTiledTexture->discardTextures();
+ } else {
+ XLOG("prepareGL on LG %p with DTT %p", this, m_dualTiledTexture);
+ bool allowZoom = m_hasText; // only allow for scale > 1 if painting vectors
+ IntRect prepareArea = computePrepareArea();
+ m_dualTiledTexture->prepareGL(TEMP_LAYER->state(), TEMP_LAYER->hasText(),
+ prepareArea, this);
+ }
+}
+
+bool LayerGroup::drawGL(bool layerTilesDisabled)
+{
+ if (!TEMP_LAYER->visible())
+ return false;
+
+ FloatRect drawClip = TEMP_LAYER->drawClip();
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip);
+ TilesManager::instance()->shader()->clip(clippingRect);
+
+ bool askRedraw = false;
+ if (m_dualTiledTexture && !layerTilesDisabled) {
+ XLOG("drawGL on LG %p with DTT %p", this, m_dualTiledTexture);
+ IntRect visibleArea = TEMP_LAYER->visibleArea();
+ askRedraw |= m_dualTiledTexture->drawGL(visibleArea, opacity());
+ }
+ askRedraw |= TEMP_LAYER->drawGL(layerTilesDisabled);
+
+ return askRedraw;
+}
+
+void LayerGroup::swapTiles()
+{
+ if (!m_dualTiledTexture)
+ return;
+
+ m_dualTiledTexture->swapTiles();
+}
+
+bool LayerGroup::isReady()
+{
+ if (!m_dualTiledTexture)
+ return true;
+
+ return m_dualTiledTexture->isReady();
+}
+
+IntRect LayerGroup::computePrepareArea() {
+ IntRect area;
+
+ if (!TEMP_LAYER->contentIsScrollable()
+ && TEMP_LAYER->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
+ area = TEMP_LAYER->unclippedArea();
+
+ double total = ((double) area.width()) * ((double) area.height());
+ if (total > MAX_UNCLIPPED_AREA)
+ area = TEMP_LAYER->visibleArea();
+ } else {
+ area = TEMP_LAYER->visibleArea();
+ }
+
+ return area;
+}
+
+void LayerGroup::computeTexturesAmount(TexturesResult* result)
+{
+ if (!m_dualTiledTexture)
+ return;
+
+ // TODO: don't calculate through layer recursion, use the group list
+ m_dualTiledTexture->computeTexturesAmount(result, TEMP_LAYER);
+}
+
+bool LayerGroup::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* pictureUsed)
+{
+ SkPicture *picture = TEMP_LAYER->picture();
+ if (!picture) {
+ XLOGC("LG %p couldn't paint, no picture in layer %p", this, TEMP_LAYER);
+ return false;
+ }
+
+ canvas->drawPicture(*picture);
+
+ return true;
+}
+
+const TransformationMatrix* LayerGroup::transform()
+{
+ return TEMP_LAYER->drawTransform();
+}
+
+float LayerGroup::opacity()
+{
+ return TEMP_LAYER->getOpacity();
+}
+
+} // namespace WebCore