Index: ui/cc/cc/CCTiledLayerImpl.cpp |
diff --git a/ui/cc/cc/CCTiledLayerImpl.cpp b/ui/cc/cc/CCTiledLayerImpl.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..45c070cdafc1185c941c74f698d69c5d44274040 |
--- /dev/null |
+++ b/ui/cc/cc/CCTiledLayerImpl.cpp |
@@ -0,0 +1,248 @@ |
+/* |
+ * Copyright (C) 2011 Google Inc. All rights reserved. |
+ * |
+ * Redistribution and use in source and binary forms, with or without |
+ * modification, are permitted provided that the following conditions |
+ * are met: |
+ * |
+ * 1. Redistributions of source code must retain the above copyright |
+ * notice, this list of conditions and the following disclaimer. |
+ * 2. 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS 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" |
+ |
+#if USE(ACCELERATED_COMPOSITING) |
+ |
+#include "cc/CCTiledLayerImpl.h" |
+ |
+#include "SkColor.h" |
+#include "TextStream.h" |
+#include "cc/CCCheckerboardDrawQuad.h" |
+#include "cc/CCDebugBorderDrawQuad.h" |
+#include "cc/CCLayerTilingData.h" |
+#include "cc/CCQuadCuller.h" |
+#include "cc/CCSolidColorDrawQuad.h" |
+#include "cc/CCTileDrawQuad.h" |
+#include <wtf/text/WTFString.h> |
+ |
+using namespace std; |
+using WebKit::WebTransformationMatrix; |
+ |
+namespace WebCore { |
+ |
+static const int debugTileBorderWidth = 1; |
+static const int debugTileBorderAlpha = 100; |
+static const int debugTileBorderColorRed = 80; |
+static const int debugTileBorderColorGreen = 200; |
+static const int debugTileBorderColorBlue = 200; |
+static const int debugTileBorderMissingTileColorRed = 255; |
+static const int debugTileBorderMissingTileColorGreen = 0; |
+static const int debugTileBorderMissingTileColorBlue = 0; |
+ |
+class ManagedTexture; |
+ |
+class DrawableTile : public CCLayerTilingData::Tile { |
+ WTF_MAKE_NONCOPYABLE(DrawableTile); |
+public: |
+ static PassOwnPtr<DrawableTile> create() { return adoptPtr(new DrawableTile()); } |
+ |
+ Platform3DObject textureId() const { return m_textureId; } |
+ void setTextureId(Platform3DObject textureId) { m_textureId = textureId; } |
+ |
+private: |
+ DrawableTile() : m_textureId(0) { } |
+ |
+ Platform3DObject m_textureId; |
+}; |
+ |
+CCTiledLayerImpl::CCTiledLayerImpl(int id) |
+ : CCLayerImpl(id) |
+ , m_skipsDraw(true) |
+ , m_contentsSwizzled(false) |
+{ |
+} |
+ |
+CCTiledLayerImpl::~CCTiledLayerImpl() |
+{ |
+} |
+ |
+unsigned CCTiledLayerImpl::contentsTextureId() const |
+{ |
+ // This function is only valid for single texture layers, e.g. masks. |
+ ASSERT(m_tiler); |
+ ASSERT(m_tiler->numTilesX() == 1); |
+ ASSERT(m_tiler->numTilesY() == 1); |
+ |
+ DrawableTile* tile = tileAt(0, 0); |
+ Platform3DObject textureId = tile ? tile->textureId() : 0; |
+ ASSERT(textureId); |
+ |
+ return textureId; |
+} |
+ |
+void CCTiledLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const |
+{ |
+ CCLayerImpl::dumpLayerProperties(ts, indent); |
+ writeIndent(ts, indent); |
+ ts << "skipsDraw: " << (!m_tiler || m_skipsDraw) << "\n"; |
+} |
+ |
+bool CCTiledLayerImpl::hasTileAt(int i, int j) const |
+{ |
+ return m_tiler->tileAt(i, j); |
+} |
+ |
+bool CCTiledLayerImpl::hasTextureIdForTileAt(int i, int j) const |
+{ |
+ return hasTileAt(i, j) && tileAt(i, j)->textureId(); |
+} |
+ |
+DrawableTile* CCTiledLayerImpl::tileAt(int i, int j) const |
+{ |
+ return static_cast<DrawableTile*>(m_tiler->tileAt(i, j)); |
+} |
+ |
+DrawableTile* CCTiledLayerImpl::createTile(int i, int j) |
+{ |
+ OwnPtr<DrawableTile> tile(DrawableTile::create()); |
+ DrawableTile* addedTile = tile.get(); |
+ m_tiler->addTile(tile.release(), i, j); |
+ return addedTile; |
+} |
+ |
+WebTransformationMatrix CCTiledLayerImpl::quadTransform() const |
+{ |
+ WebTransformationMatrix transform = drawTransform(); |
+ |
+ if (contentBounds().isEmpty()) |
+ return transform; |
+ |
+ transform.scaleNonUniform(bounds().width() / static_cast<double>(contentBounds().width()), |
+ bounds().height() / static_cast<double>(contentBounds().height())); |
+ |
+ // Tiler draws with a different origin from other layers. |
+ transform.translate(-contentBounds().width() / 2.0, -contentBounds().height() / 2.0); |
+ return transform; |
+} |
+ |
+void CCTiledLayerImpl::appendQuads(CCQuadCuller& quadList, const CCSharedQuadState* sharedQuadState, bool& hadMissingTiles) |
+{ |
+ const IntRect& layerRect = visibleLayerRect(); |
+ |
+ if (!m_tiler || m_tiler->hasEmptyBounds() || layerRect.isEmpty()) |
+ return; |
+ |
+ int left, top, right, bottom; |
+ m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom); |
+ |
+ if (hasDebugBorders()) { |
+ for (int j = top; j <= bottom; ++j) { |
+ for (int i = left; i <= right; ++i) { |
+ DrawableTile* tile = tileAt(i, j); |
+ IntRect tileRect = m_tiler->tileBounds(i, j); |
+ SkColor borderColor; |
+ |
+ if (m_skipsDraw || !tile || !tile->textureId()) |
+ borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderMissingTileColorRed, debugTileBorderMissingTileColorGreen, debugTileBorderMissingTileColorBlue); |
+ else |
+ borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderColorRed, debugTileBorderColorGreen, debugTileBorderColorBlue); |
+ quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState, tileRect, borderColor, debugTileBorderWidth)); |
+ } |
+ } |
+ } |
+ |
+ if (m_skipsDraw) |
+ return; |
+ |
+ for (int j = top; j <= bottom; ++j) { |
+ for (int i = left; i <= right; ++i) { |
+ DrawableTile* tile = tileAt(i, j); |
+ IntRect tileRect = m_tiler->tileBounds(i, j); |
+ IntRect displayRect = tileRect; |
+ tileRect.intersect(layerRect); |
+ |
+ // Skip empty tiles. |
+ if (tileRect.isEmpty()) |
+ continue; |
+ |
+ if (!tile || !tile->textureId()) { |
+ if (drawCheckerboardForMissingTiles()) |
+ hadMissingTiles |= quadList.append(CCCheckerboardDrawQuad::create(sharedQuadState, tileRect)); |
+ else |
+ hadMissingTiles |= quadList.append(CCSolidColorDrawQuad::create(sharedQuadState, tileRect, backgroundColor())); |
+ continue; |
+ } |
+ |
+ IntRect tileOpaqueRect = tile->opaqueRect(); |
+ tileOpaqueRect.intersect(layerRect); |
+ |
+ // Keep track of how the top left has moved, so the texture can be |
+ // offset the same amount. |
+ IntSize displayOffset = tileRect.minXMinYCorner() - displayRect.minXMinYCorner(); |
+ IntPoint textureOffset = m_tiler->textureOffset(i, j) + displayOffset; |
+ float tileWidth = static_cast<float>(m_tiler->tileSize().width()); |
+ float tileHeight = static_cast<float>(m_tiler->tileSize().height()); |
+ IntSize textureSize(tileWidth, tileHeight); |
+ |
+ bool useAA = m_tiler->hasBorderTexels() && !sharedQuadState->isLayerAxisAlignedIntRect(); |
+ |
+ bool leftEdgeAA = !i && useAA; |
+ bool topEdgeAA = !j && useAA; |
+ bool rightEdgeAA = i == m_tiler->numTilesX() - 1 && useAA; |
+ bool bottomEdgeAA = j == m_tiler->numTilesY() - 1 && useAA; |
+ |
+ const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GL_LINEAR : GL_NEAREST; |
+ quadList.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tileOpaqueRect, tile->textureId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA)); |
+ } |
+ } |
+} |
+ |
+void CCTiledLayerImpl::setTilingData(const CCLayerTilingData& tiler) |
+{ |
+ if (m_tiler) |
+ m_tiler->reset(); |
+ else |
+ m_tiler = CCLayerTilingData::create(tiler.tileSize(), tiler.hasBorderTexels() ? CCLayerTilingData::HasBorderTexels : CCLayerTilingData::NoBorderTexels); |
+ *m_tiler = tiler; |
+} |
+ |
+void CCTiledLayerImpl::pushTileProperties(int i, int j, Platform3DObject textureId, const IntRect& opaqueRect) |
+{ |
+ DrawableTile* tile = tileAt(i, j); |
+ if (!tile) |
+ tile = createTile(i, j); |
+ tile->setTextureId(textureId); |
+ tile->setOpaqueRect(opaqueRect); |
+} |
+ |
+Region CCTiledLayerImpl::visibleContentOpaqueRegion() const |
+{ |
+ if (m_skipsDraw) |
+ return Region(); |
+ if (opaque()) |
+ return visibleLayerRect(); |
+ return m_tiler->opaqueRegionInLayerRect(visibleLayerRect()); |
+} |
+ |
+void CCTiledLayerImpl::didLoseContext() |
+{ |
+ m_tiler->reset(); |
+} |
+ |
+} // namespace WebCore |
+ |
+#endif // USE(ACCELERATED_COMPOSITING) |