[chromium] Use region reported painted opaque for draw culling
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 01:42:30 +0000 (01:42 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 01:42:30 +0000 (01:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76015

Patch by Dana Jansens <danakj@chromium.org> on 2012-01-18
Reviewed by James Robinson.

Source/WebCore:

New unit tests in CCQuadCullerTest.cpp and CCTiledLayerImplTest.cpp

* platform/graphics/chromium/TiledLayerChromium.cpp:
(WebCore::TiledLayerChromium::pushPropertiesTo):
(WebCore::TiledLayerChromium::prepareToUpdateTiles):
* platform/graphics/chromium/cc/CCDrawQuad.h:
(WebCore::CCDrawQuad::opaqueRect):
(WebCore::CCDrawQuad::needsBlending):
* platform/graphics/chromium/cc/CCQuadCuller.cpp:
(WebCore::CCQuadCuller::cullOccludedQuads):
* platform/graphics/chromium/cc/CCTileDrawQuad.cpp:
(WebCore::CCTileDrawQuad::create):
(WebCore::CCTileDrawQuad::CCTileDrawQuad):
* platform/graphics/chromium/cc/CCTileDrawQuad.h:
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::DrawableTile::opaqueRect):
(WebCore::DrawableTile::setOpaqueRect):
(WebCore::CCTiledLayerImpl::appendQuads):
(WebCore::CCTiledLayerImpl::pushTileProperties):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:

Source/WebKit/chromium:

* tests/CCQuadCullerTest.cpp:
(WebCore::TestDrawQuad::TestDrawQuad):
(WebCore::TestDrawQuad::create):
(WebCore::setQuads):
(WebCore::TEST):
* tests/CCTiledLayerImplTest.cpp:
(WebCore::createLayer):
(WebCore::TEST):
(WebCore::getQuads):
(WebCore::coverageVisibleRectOnTileBoundaries):
(WebCore::coverageVisibleRectIntersectsTiles):
(WebCore::coverageVisibleRectIntersectsBounds):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105366 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/cc/CCDrawQuad.h
Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSolidColorDrawQuad.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTileDrawQuad.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTileDrawQuad.h
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCQuadCullerTest.cpp
Source/WebKit/chromium/tests/CCTiledLayerImplTest.cpp

index 73d9ff8..c1a4654 100644 (file)
@@ -1,3 +1,31 @@
+2012-01-18  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Use region reported painted opaque for draw culling
+        https://bugs.webkit.org/show_bug.cgi?id=76015
+
+        Reviewed by James Robinson.
+
+        New unit tests in CCQuadCullerTest.cpp and CCTiledLayerImplTest.cpp
+
+        * platform/graphics/chromium/TiledLayerChromium.cpp:
+        (WebCore::TiledLayerChromium::pushPropertiesTo):
+        (WebCore::TiledLayerChromium::prepareToUpdateTiles):
+        * platform/graphics/chromium/cc/CCDrawQuad.h:
+        (WebCore::CCDrawQuad::opaqueRect):
+        (WebCore::CCDrawQuad::needsBlending):
+        * platform/graphics/chromium/cc/CCQuadCuller.cpp:
+        (WebCore::CCQuadCuller::cullOccludedQuads):
+        * platform/graphics/chromium/cc/CCTileDrawQuad.cpp:
+        (WebCore::CCTileDrawQuad::create):
+        (WebCore::CCTileDrawQuad::CCTileDrawQuad):
+        * platform/graphics/chromium/cc/CCTileDrawQuad.h:
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
+        (WebCore::DrawableTile::opaqueRect):
+        (WebCore::DrawableTile::setOpaqueRect):
+        (WebCore::CCTiledLayerImpl::appendQuads):
+        (WebCore::CCTiledLayerImpl::pushTileProperties):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.h:
+
 2012-01-18  Victoria Kirst  <vrk@chromium.org>
 
         HTMLMediaElement should fire 'progress' event before 'idle' if it was previously loading
index 713b4e0..9739113 100644 (file)
@@ -67,6 +67,7 @@ public:
 
     IntRect m_dirtyRect;
     IntRect m_updateRect;
+    IntRect m_opaqueRect;
 private:
     OwnPtr<LayerTextureUpdater::Texture> m_texture;
 };
@@ -272,7 +273,7 @@ void TiledLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
         if (tile->isDirty())
             continue;
 
-        tiledLayer->syncTextureId(i, j, tile->managedTexture()->textureId());
+        tiledLayer->pushTileProperties(i, j, tile->managedTexture()->textureId(), tile->m_opaqueRect);
     }
 }
 
@@ -412,8 +413,8 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
     // However, we can't free the memory backing the GraphicsContext until the paint finishes,
     // so we grab a local reference here to hold the updater alive until the paint completes.
     RefPtr<LayerTextureUpdater> protector(textureUpdater());
-    IntRect opaqueRect; // FIXME: unused. remove this and store in the layer to pass to impl for draw culling
-    textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale(), &opaqueRect);
+    IntRect paintedOpaqueRect;
+    textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale(), &paintedOpaqueRect);
     for (int j = top; j <= bottom; ++j) {
         for (int i = left; i <= right; ++i) {
             UpdatableTile* tile = tileAt(i, j);
@@ -422,12 +423,21 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
             if (!tile)
                 CRASH();
 
+            IntRect tileRect = m_tiler->tileRect(tile);
+
+            // Save what was painted opaque in the tile. If everything painted in the tile was opaque, and the area is a subset of an
+            // already opaque area, keep the old area.
+            IntRect tilePaintedRect = intersection(tileRect, m_paintRect);
+            IntRect tilePaintedOpaqueRect = intersection(tileRect, paintedOpaqueRect);
+            if (tilePaintedOpaqueRect != tilePaintedRect || !tile->m_opaqueRect.contains(tilePaintedOpaqueRect))
+                tile->m_opaqueRect = tilePaintedOpaqueRect;
+
             // Use m_updateRect as copyAndClearDirty above moved the existing dirty rect to m_updateRect.
             const IntRect& dirtyRect = tile->m_updateRect;
             if (dirtyRect.isEmpty())
                 continue;
 
-            IntRect sourceRect = m_tiler->tileRect(tile);
+            IntRect sourceRect = tileRect;
             sourceRect.intersect(dirtyRect);
             // Paint rect not guaranteed to line up on tile boundaries, so
             // make sure that sourceRect doesn't extend outside of it.
index acc7c02..5656351 100644 (file)
@@ -51,9 +51,16 @@ public:
     const IntRect& layerRect() const { return m_sharedQuadState->layerRect(); }
     const IntRect& clipRect() const { return m_sharedQuadState->clipRect(); }
     float opacity() const { return m_sharedQuadState->opacity(); }
-    // For the purposes of culling, are the contents of this quad opaque?
-    bool drawsOpaque() const { return m_sharedQuadState->isOpaque() && m_quadOpaque && opacity() == 1; }
-    bool needsBlending() const { return !m_sharedQuadState->isOpaque() || m_needsBlending || opacity() != 1; }
+    // For the purposes of culling, what part of the contents of this quad are opaque?
+    IntRect opaqueRect() const
+    {
+        if (opacity() != 1)
+            return IntRect();
+        if (m_sharedQuadState->isOpaque() && m_quadOpaque)
+            return m_quadRect;
+        return m_opaqueRect;
+    }
+    bool needsBlending() const { return m_needsBlending || opaqueRect() != m_quadRect; }
     bool isLayerAxisAlignedIntRect() const { return m_sharedQuadState->isLayerAxisAlignedIntRect(); }
 
     enum Material {
@@ -90,6 +97,10 @@ protected:
     // variables.
     bool m_quadOpaque;
     bool m_needsBlending;
+
+    // Be default, this rect is empty. It is used when the shared quad state and above
+    // variables determine that the quad is not fully opaque but may be partially opaque.
+    IntRect m_opaqueRect;
 };
 
 }
index 079aa7f..4f1e036 100644 (file)
@@ -77,8 +77,8 @@ void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList)
 
         bool keepQuad = !regionContainsRect(opaqueCoverageThusFar, quadRect);
 
-        if (keepQuad && drawQuad->drawsOpaque() && drawQuad->isLayerAxisAlignedIntRect())
-            opaqueCoverageThusFar.unite(Region(quadRect));
+        if (keepQuad && drawQuad->isLayerAxisAlignedIntRect())
+            opaqueCoverageThusFar.unite(drawQuad->quadTransform().mapRect(drawQuad->opaqueRect()));
 
         if (keepQuad)
             culledList.append(quadList[i].release());
index d1c729a..74e623c 100644 (file)
@@ -40,6 +40,8 @@ CCSolidColorDrawQuad::CCSolidColorDrawQuad(const CCSharedQuadState* sharedQuadSt
 {
     if (m_color.alpha() != 1)
         m_quadOpaque = false;
+    else
+        m_opaqueRect = quadRect;
 }
 
 }
index df83050..b35b6f6 100644 (file)
 
 namespace WebCore {
 
-PassOwnPtr<CCTileDrawQuad> CCTileDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA)
+PassOwnPtr<CCTileDrawQuad> CCTileDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, const IntRect& opaqueRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA)
 {
-    return adoptPtr(new CCTileDrawQuad(sharedQuadState, quadRect, textureId, textureOffset, textureSize, textureFilter, swizzleContents, leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA));
+    return adoptPtr(new CCTileDrawQuad(sharedQuadState, quadRect, opaqueRect, textureId, textureOffset, textureSize, textureFilter, swizzleContents, leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA));
 }
 
-CCTileDrawQuad::CCTileDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA)
+CCTileDrawQuad::CCTileDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, const IntRect& opaqueRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA)
     : CCDrawQuad(sharedQuadState, CCDrawQuad::TiledContent, quadRect)
     , m_textureId(textureId)
     , m_textureOffset(textureOffset)
@@ -48,6 +48,7 @@ CCTileDrawQuad::CCTileDrawQuad(const CCSharedQuadState* sharedQuadState, const I
 {
     if (isAntialiased())
         m_needsBlending = true;
+    m_opaqueRect = opaqueRect;
 }
 
 }
index 12e53db..33501a8 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 class CCTileDrawQuad : public CCDrawQuad {
     WTF_MAKE_NONCOPYABLE(CCTileDrawQuad);
 public:
-    static PassOwnPtr<CCTileDrawQuad> create(const CCSharedQuadState*, const IntRect& quadRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA);
+    static PassOwnPtr<CCTileDrawQuad> create(const CCSharedQuadState*, const IntRect& quadRect, const IntRect& opaqueRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA);
 
     Platform3DObject textureId() const { return m_textureId; }
     IntPoint textureOffset() const { return m_textureOffset; }
@@ -51,7 +51,7 @@ public:
     bool isAntialiased() const { return leftEdgeAA() || topEdgeAA() || rightEdgeAA() || bottomEdgeAA(); }
 
 private:
-    CCTileDrawQuad(const CCSharedQuadState*, const IntRect& quadRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA);
+    CCTileDrawQuad(const CCSharedQuadState*, const IntRect& quadRect, const IntRect& opaqueRect, Platform3DObject textureId, const IntPoint& textureOffset, const IntSize& textureSize, GC3Dint textureFilter, bool swizzleContents, bool leftEdgeAA, bool topEdgeAA, bool rightEdgeAA, bool bottomEdgeAA);
 
     Platform3DObject m_textureId;
     IntPoint m_textureOffset;
index 5849ef1..48e2c54 100644 (file)
@@ -51,8 +51,13 @@ public:
 
     Platform3DObject textureId() const { return m_textureId; }
     void setTextureId(Platform3DObject textureId) { m_textureId = textureId; }
+
+    const IntRect& opaqueRect() const { return m_opaqueRect; }
+    void setOpaqueRect(const IntRect& opaqueRect) { m_opaqueRect = opaqueRect; }
+
 private:
     Platform3DObject m_textureId;
+    IntRect m_opaqueRect;
 };
 
 CCTiledLayerImpl::CCTiledLayerImpl(int id)
@@ -159,7 +164,7 @@ void CCTiledLayerImpl::appendQuads(CCQuadList& quadList, const CCSharedQuadState
             bool bottomEdgeAA = j == m_tiler->numTilesY() - 1 && useAA;
 
             const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST;
-            quadList.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tile->textureId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA));
+            quadList.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tile->opaqueRect(), tile->textureId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA));
 
             if (hasDebugBorders()) {
                 Color color(debugBorderColor().red(), debugBorderColor().green(), debugBorderColor().blue(), debugTileBorderAlpha);
@@ -178,14 +183,15 @@ void CCTiledLayerImpl::setTilingData(const CCLayerTilingData& tiler)
     *m_tiler = tiler;
 }
 
-void CCTiledLayerImpl::syncTextureId(int i, int j, Platform3DObject textureId)
+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);
 }
 
-}
+} // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)
index 478b034..7ad7159 100644 (file)
@@ -51,7 +51,7 @@ public:
 
     void setSkipsDraw(bool skipsDraw) { m_skipsDraw = skipsDraw; }
     void setTilingData(const CCLayerTilingData& tiler);
-    void syncTextureId(int, int, Platform3DObject textureId);
+    void pushTileProperties(int, int, Platform3DObject textureId, const IntRect& opaqueRect);
 
     void setContentsSwizzled(bool contentsSwizzled) { m_contentsSwizzled = contentsSwizzled; }
     bool contentsSwizzled() const { return m_contentsSwizzled; }
index aee3dd1..fce5e0d 100644 (file)
@@ -1,3 +1,23 @@
+2012-01-18  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Use region reported painted opaque for draw culling
+        https://bugs.webkit.org/show_bug.cgi?id=76015
+
+        Reviewed by James Robinson.
+
+        * tests/CCQuadCullerTest.cpp:
+        (WebCore::TestDrawQuad::TestDrawQuad):
+        (WebCore::TestDrawQuad::create):
+        (WebCore::setQuads):
+        (WebCore::TEST):
+        * tests/CCTiledLayerImplTest.cpp:
+        (WebCore::createLayer):
+        (WebCore::TEST):
+        (WebCore::getQuads):
+        (WebCore::coverageVisibleRectOnTileBoundaries):
+        (WebCore::coverageVisibleRectIntersectsTiles):
+        (WebCore::coverageVisibleRectIntersectsBounds):
+
 2012-01-18  Joshua Bell  <jsbell@chromium.org>
 
         IndexedDB: Fix InjectIDBKeyTest.SubProperty test failure
index ed15e6c..5ecbb59 100644 (file)
@@ -38,35 +38,36 @@ class CCQuadCullerTest : public testing::Test {
 
 class TestDrawQuad : public CCDrawQuad {
 public:
-    TestDrawQuad(const CCSharedQuadState* state, Material m, const IntRect& rect)
+    TestDrawQuad(const CCSharedQuadState* state, Material m, const IntRect& rect, const IntRect& opaqueRect)
     : CCDrawQuad(state, m, rect)
     {
+        m_opaqueRect = opaqueRect;
     }
 
-    static PassOwnPtr<TestDrawQuad> create(const CCSharedQuadState* state, Material m, const IntRect& rect)
+    static PassOwnPtr<TestDrawQuad> create(const CCSharedQuadState* state, Material m, const IntRect& rect, const IntRect& opaqueRect)
     {
-        return adoptPtr(new TestDrawQuad(state, m, rect));
+        return adoptPtr(new TestDrawQuad(state, m, rect, opaqueRect));
     }
 };
 
-void setQuads(CCSharedQuadState* rootState, CCSharedQuadState* childState, CCQuadList& quadList)
+void setQuads(CCSharedQuadState* rootState, CCSharedQuadState* childState, CCQuadList& quadList, const IntRect& childOpaqueRect = IntRect())
 {
     quadList.clear();
 
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 0), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(200, 0), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(0, 100), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 100), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(200, 100), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(0, 200), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 200), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(200, 200), IntSize(100, 100))));
-
-    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 0), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(0, 100), IntSize(100, 100))));
-    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 100), IntSize(100, 100))));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 0), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(200, 0), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(0, 100), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 100), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(200, 100), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(0, 200), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 200), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(rootState, CCDrawQuad::TiledContent, IntRect(IntPoint(200, 200), IntSize(100, 100)), childOpaqueRect));
+
+    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 0), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(0, 100), IntSize(100, 100)), childOpaqueRect));
+    quadList.append(TestDrawQuad::create(childState, CCDrawQuad::TiledContent, IntRect(IntPoint(100, 100), IntSize(100, 100)), childOpaqueRect));
 }
 
 #define DECLARE_AND_INITIALIZE_TEST_QUADS               \
@@ -146,6 +147,54 @@ TEST(CCQuadCullerTest, verifyCullChildLinesUpBottomRight)
     EXPECT_EQ(quadList.size(), 9u);
 }
 
+TEST(CCQuadCullerTest, verifyCullSubRegion)
+{
+    DECLARE_AND_INITIALIZE_TEST_QUADS
+
+    childTransform.translate(50, 50);
+
+    OwnPtr<CCSharedQuadState> rootState = CCSharedQuadState::create(TransformationMatrix(), TransformationMatrix(), rootRect, IntRect(), 1.0, true);
+    OwnPtr<CCSharedQuadState> childState = CCSharedQuadState::create(childTransform, TransformationMatrix(), childRect, IntRect(), 1.0, false);
+    IntRect childOpaqueRect(childRect.x() + childRect.width() / 4, childRect.y() + childRect.height() / 4, childRect.width() / 2, childRect.height() / 2);
+
+    setQuads(rootState.get(), childState.get(), quadList, childOpaqueRect);
+    EXPECT_EQ(quadList.size(), 13u);
+    CCQuadCuller::cullOccludedQuads(quadList);
+    EXPECT_EQ(quadList.size(), 12u);
+}
+
+TEST(CCQuadCullerTest, verifyCullSubRegion2)
+{
+    DECLARE_AND_INITIALIZE_TEST_QUADS
+
+    childTransform.translate(50, 10);
+
+    OwnPtr<CCSharedQuadState> rootState = CCSharedQuadState::create(TransformationMatrix(), TransformationMatrix(), rootRect, IntRect(), 1.0, true);
+    OwnPtr<CCSharedQuadState> childState = CCSharedQuadState::create(childTransform, TransformationMatrix(), childRect, IntRect(), 1.0, false);
+    IntRect childOpaqueRect(childRect.x() + childRect.width() / 4, childRect.y() + childRect.height() / 4, childRect.width() / 2, childRect.height() * 3 / 4);
+
+    setQuads(rootState.get(), childState.get(), quadList, childOpaqueRect);
+    EXPECT_EQ(quadList.size(), 13u);
+    CCQuadCuller::cullOccludedQuads(quadList);
+    EXPECT_EQ(quadList.size(), 12u);
+}
+
+TEST(CCQuadCullerTest, verifyCullSubRegionCheckOvercull)
+{
+    DECLARE_AND_INITIALIZE_TEST_QUADS
+
+    childTransform.translate(50, 49);
+
+    OwnPtr<CCSharedQuadState> rootState = CCSharedQuadState::create(TransformationMatrix(), TransformationMatrix(), rootRect, IntRect(), 1.0, true);
+    OwnPtr<CCSharedQuadState> childState = CCSharedQuadState::create(childTransform, TransformationMatrix(), childRect, IntRect(), 1.0, false);
+    IntRect childOpaqueRect(childRect.x() + childRect.width() / 4, childRect.y() + childRect.height() / 4, childRect.width() / 2, childRect.height() / 2);
+
+    setQuads(rootState.get(), childState.get(), quadList, childOpaqueRect);
+    EXPECT_EQ(quadList.size(), 13u);
+    CCQuadCuller::cullOccludedQuads(quadList);
+    EXPECT_EQ(quadList.size(), 13u);
+}
+
 TEST(CCQuadCullerTest, verifyNonAxisAlignedQuadsDontOcclude)
 {
     DECLARE_AND_INITIALIZE_TEST_QUADS
index a2eea94..17850f2 100644 (file)
@@ -46,11 +46,12 @@ static PassRefPtr<CCTiledLayerImpl> createLayer(const IntSize& tileSize, const I
     layer->setTilingData(*tiler);
     layer->setSkipsDraw(false);
     layer->setVisibleLayerRect(IntRect(IntPoint(), layerSize));
+    layer->setDrawOpacity(1);
 
     int textureId = 1;
     for (int i = 0; i < tiler->numTilesX(); ++i)
         for (int j = 0; j < tiler->numTilesY(); ++j)
-            layer->syncTextureId(i, j, static_cast<Platform3DObject>(textureId++));
+            layer->pushTileProperties(i, j, static_cast<Platform3DObject>(textureId++), IntRect(0, 0, 1, 1));
 
     return layer.release();
 }
@@ -134,7 +135,7 @@ TEST(CCTiledLayerImplTest, checkerboarding)
 
     for (int i = 0; i < numTilesX; ++i)
         for (int j = 0; j < numTilesY; ++j)
-            layer->syncTextureId(i, j, static_cast<Platform3DObject>(0));
+            layer->pushTileProperties(i, j, static_cast<Platform3DObject>(0), IntRect());
 
     // All checkerboarding
     {
@@ -155,7 +156,7 @@ static bool completelyContains(const Region& container, const IntRect& rect)
     return tester.isEmpty();
 }
 
-static void getQuads(CCQuadList& quads, IntSize tileSize, const IntSize& layerSize, CCLayerTilingData::BorderTexelOption borderTexelOption, const IntRect& visibleLayerRect)
+static PassOwnPtr<CCSharedQuadState> getQuads(CCQuadList& quads, IntSize tileSize, const IntSize& layerSize, CCLayerTilingData::BorderTexelOption borderTexelOption, const IntRect& visibleLayerRect)
 {
     RefPtr<CCTiledLayerImpl> layer = createLayer(tileSize, layerSize, borderTexelOption);
     layer->setVisibleLayerRect(visibleLayerRect);
@@ -163,6 +164,7 @@ static void getQuads(CCQuadList& quads, IntSize tileSize, const IntSize& layerSi
 
     OwnPtr<CCSharedQuadState> sharedQuadState = layer->createSharedQuadState();
     layer->appendQuads(quads, sharedQuadState.get());
+    return sharedQuadState.release(); // The shared data must be owned as long as the quad list exists.
 }
 
 // Align with expected and actual output
@@ -200,7 +202,8 @@ static void coverageVisibleRectOnTileBoundaries(CCLayerTilingData::BorderTexelOp
 
     IntSize layerSize(1000, 1000);
     CCQuadList quads;
-    getQuads(quads, IntSize(100, 100), layerSize, borders, IntRect(IntPoint(), layerSize));
+    OwnPtr<CCSharedQuadState> sharedState;
+    sharedState = getQuads(quads, IntSize(100, 100), layerSize, borders, IntRect(IntPoint(), layerSize));
     verifyQuadsExactlyCoverRect(quads, IntRect(IntPoint(), layerSize));
 }
 WITH_AND_WITHOUT_BORDER_TEST(coverageVisibleRectOnTileBoundaries);
@@ -216,7 +219,8 @@ static void coverageVisibleRectIntersectsTiles(CCLayerTilingData::BorderTexelOpt
 
     IntSize layerSize(250, 250);
     CCQuadList quads;
-    getQuads(quads, IntSize(50, 50), IntSize(250, 250), CCLayerTilingData::NoBorderTexels, visibleLayerRect);
+    OwnPtr<CCSharedQuadState> sharedState;
+    sharedState = getQuads(quads, IntSize(50, 50), IntSize(250, 250), CCLayerTilingData::NoBorderTexels, visibleLayerRect);
     verifyQuadsExactlyCoverRect(quads, visibleLayerRect);
 }
 WITH_AND_WITHOUT_BORDER_TEST(coverageVisibleRectIntersectsTiles);
@@ -228,7 +232,8 @@ static void coverageVisibleRectIntersectsBounds(CCLayerTilingData::BorderTexelOp
     IntSize layerSize(220, 210);
     IntRect visibleLayerRect(IntPoint(), layerSize);
     CCQuadList quads;
-    getQuads(quads, IntSize(100, 100), layerSize, CCLayerTilingData::NoBorderTexels, visibleLayerRect);
+    OwnPtr<CCSharedQuadState> sharedState;
+    sharedState = getQuads(quads, IntSize(100, 100), layerSize, CCLayerTilingData::NoBorderTexels, visibleLayerRect);
     verifyQuadsExactlyCoverRect(quads, visibleLayerRect);
 }
 WITH_AND_WITHOUT_BORDER_TEST(coverageVisibleRectIntersectsBounds);
@@ -240,7 +245,8 @@ TEST(CCTiledLayerImplTest, textureInfoForLayerNoBorders)
     IntSize tileSize(50, 50);
     IntSize layerSize(250, 250);
     CCQuadList quads;
-    getQuads(quads, tileSize, layerSize, CCLayerTilingData::NoBorderTexels, IntRect(IntPoint(), layerSize));
+    OwnPtr<CCSharedQuadState> sharedState;
+    sharedState = getQuads(quads, tileSize, layerSize, CCLayerTilingData::NoBorderTexels, IntRect(IntPoint(), layerSize));
 
     for (size_t i = 0; i < quads.size(); ++i) {
         ASSERT_EQ(quads[i]->material(), CCDrawQuad::TiledContent) << quadString << i;
@@ -249,8 +255,26 @@ TEST(CCTiledLayerImplTest, textureInfoForLayerNoBorders)
         EXPECT_NE(quad->textureId(), 0u) << quadString << i;
         EXPECT_EQ(quad->textureOffset(), IntPoint()) << quadString << i;
         EXPECT_EQ(quad->textureSize(), tileSize) << quadString << i;
+        EXPECT_EQ(IntRect(0, 0, 1, 1), quad->opaqueRect()) << quadString << i;
     }
 }
 
+TEST(CCTiledLayerImplTest, tileOpaqueRectForLayerNoBorders)
+{
+    DebugScopedSetImplThread scopedImplThread;
+
+    IntSize tileSize(50, 50);
+    IntSize layerSize(250, 250);
+    CCQuadList quads;
+    OwnPtr<CCSharedQuadState> sharedState;
+    sharedState = getQuads(quads, tileSize, layerSize, CCLayerTilingData::NoBorderTexels, IntRect(IntPoint(), layerSize));
+
+    for (size_t i = 0; i < quads.size(); ++i) {
+        ASSERT_EQ(quads[i]->material(), CCDrawQuad::TiledContent) << quadString << i;
+        CCTileDrawQuad* quad = static_cast<CCTileDrawQuad*>(quads[i].get());
+
+        EXPECT_EQ(IntRect(0, 0, 1, 1), quad->opaqueRect()) << quadString << i;
+    }
+}
 
 } // namespace