[chromium] Use opaque paints in CCOcclusionTracker
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Mar 2012 20:22:55 +0000 (20:22 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Mar 2012 20:22:55 +0000 (20:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80173

Patch by Dana Jansens <danakj@chromium.org> on 2012-03-09
Reviewed by Adrienne Walker.

Source/WebCore:

Use tracked opaque paints in the tiles when tracking occlusion in
CCOcclusionTracker. Moves the Tile::m_opaqueRect up to the super-
class in CCLayerTilingData rather than having it declared in both
TiledLayerChromium and CCTiledLayerImpl. This lets the CCLayerTilingData
class compute the opaque region for its tiles, sharing code between the
two tiled layer implementations.

Use of this feature is guarded behind a runtime flag and turned off for
paint culling. We will enable it in the future once we're comfortable
with the paint culling.

Unit test: CCOcclusionTrackerTest.opaqueContentsRegionEmpty
           CCOcclusionTrackerTest.opaqueContentsRegionNonEmpty
           TiledLayerChromiumTest.opaqueContentsRegion

All existing CCOcclusionTrackerTest.* duplicated with opaque painted
rects.

* platform/graphics/chromium/LayerChromium.h:
(WebCore::LayerChromium::opaqueContentsRegion):
(LayerChromium):
* platform/graphics/chromium/TiledLayerChromium.cpp:
(UpdatableTile):
(WebCore::TiledLayerChromium::pushPropertiesTo):
(WebCore::TiledLayerChromium::prepareToUpdateTiles):
(WebCore::TiledLayerChromium::addSelfToOccludedScreenSpace):
(WebCore::TiledLayerChromium::opaqueContentsRegion):
(WebCore):
* platform/graphics/chromium/TiledLayerChromium.h:
* platform/graphics/chromium/cc/CCLayerImpl.h:
(WebCore::CCLayerImpl::opaqueContentsRegion):
(CCLayerImpl):
* platform/graphics/chromium/cc/CCLayerTilingData.cpp:
(WebCore::CCLayerTilingData::opaqueRegionInLayerRect):
(WebCore):
* platform/graphics/chromium/cc/CCLayerTilingData.h:
(WebCore):
(Tile):
(WebCore::CCLayerTilingData::Tile::opaqueRect):
(WebCore::CCLayerTilingData::Tile::setOpaqueRect):
(CCLayerTilingData):
* platform/graphics/chromium/cc/CCOcclusionTracker.cpp:
(WebCore::::CCOcclusionTrackerBase):
(WebCore::computeOcclusionBehindLayer):
(WebCore::::markOccludedBehindLayer):
* platform/graphics/chromium/cc/CCOcclusionTracker.h:
(CCOcclusionTrackerBase):
(WebCore::CCOcclusionTrackerBase::setUsePaintTracking):
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(DrawableTile):
(WebCore::CCTiledLayerImpl::opaqueContentsRegion):
(WebCore):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:
(CCTiledLayerImpl):

Source/WebKit/chromium:

* tests/CCOcclusionTrackerTest.cpp:
(WebCore::LayerChromiumWithForcedDrawsContent::opaqueContentsRegion):
(LayerChromiumWithForcedDrawsContent):
(WebCore::LayerChromiumWithForcedDrawsContent::setOpaquePaintRect):
(WebCore::setLayerPropertiesForTesting):
(WebCore):
(WebCore::layerAddedToOccludedRegion):
(WebCore::layerAddedToOccludedRegionWithRotation):
(WebCore::layerAddedToOccludedRegionWithTranslation):
(WebCore::layerAddedToOccludedRegionWithRotatedSurface):
(WebCore::layerAddedToOccludedRegionWithSurfaceAlreadyOnStack):
(WebCore::layerAddedToOccludedRegionWithRotatedOffAxisSurface):
(WebCore::layerAddedToOccludedRegionWithMultipleOpaqueLayers):
(WebCore::surfaceOcclusionWithOverlappingSiblingSurfaces):
(WebCore::surfaceOcclusionInScreenSpace):
(WebCore::surfaceOcclusionInScreenSpaceDifferentTransforms):
(WebCore::occlusionInteractionWithFilters):
(WebCore::layerScissorRectOverTile):
(WebCore::screenScissorRectOverTile):
(WebCore::layerScissorRectOverCulledTile):
(WebCore::screenScissorRectOverCulledTile):
(WebCore::layerScissorRectOverPartialTiles):
(WebCore::screenScissorRectOverPartialTiles):
(WebCore::layerScissorRectOverNoTiles):
(WebCore::screenScissorRectOverNoTiles):
(WebCore::layerScissorRectForLayerOffOrigin):
(WebCore::damageRectOverTile):
(WebCore::damageRectOverCulledTile):
(WebCore::damageRectOverPartialTiles):
(WebCore::damageRectOverNoTiles):
(WebCore::TEST):
* tests/TiledLayerChromiumTest.cpp:
(WTF::TEST):
(WTF):

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerChromium.h
Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTilingData.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp
Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.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/CCOcclusionTrackerTest.cpp
Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp

index 2b965b2843fae6d184b59229cc5104b8400c9c2d..ccec6da41f19c623007b9370da555d957c095eb0 100644 (file)
@@ -1,3 +1,65 @@
+2012-03-09  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Use opaque paints in CCOcclusionTracker
+        https://bugs.webkit.org/show_bug.cgi?id=80173
+
+        Reviewed by Adrienne Walker.
+
+        Use tracked opaque paints in the tiles when tracking occlusion in
+        CCOcclusionTracker. Moves the Tile::m_opaqueRect up to the super-
+        class in CCLayerTilingData rather than having it declared in both
+        TiledLayerChromium and CCTiledLayerImpl. This lets the CCLayerTilingData
+        class compute the opaque region for its tiles, sharing code between the
+        two tiled layer implementations.
+
+        Use of this feature is guarded behind a runtime flag and turned off for
+        paint culling. We will enable it in the future once we're comfortable
+        with the paint culling.
+
+        Unit test: CCOcclusionTrackerTest.opaqueContentsRegionEmpty
+                   CCOcclusionTrackerTest.opaqueContentsRegionNonEmpty
+                   TiledLayerChromiumTest.opaqueContentsRegion
+
+        All existing CCOcclusionTrackerTest.* duplicated with opaque painted
+        rects.
+
+        * platform/graphics/chromium/LayerChromium.h:
+        (WebCore::LayerChromium::opaqueContentsRegion):
+        (LayerChromium):
+        * platform/graphics/chromium/TiledLayerChromium.cpp:
+        (UpdatableTile):
+        (WebCore::TiledLayerChromium::pushPropertiesTo):
+        (WebCore::TiledLayerChromium::prepareToUpdateTiles):
+        (WebCore::TiledLayerChromium::addSelfToOccludedScreenSpace):
+        (WebCore::TiledLayerChromium::opaqueContentsRegion):
+        (WebCore):
+        * platform/graphics/chromium/TiledLayerChromium.h:
+        * platform/graphics/chromium/cc/CCLayerImpl.h:
+        (WebCore::CCLayerImpl::opaqueContentsRegion):
+        (CCLayerImpl):
+        * platform/graphics/chromium/cc/CCLayerTilingData.cpp:
+        (WebCore::CCLayerTilingData::opaqueRegionInLayerRect):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCLayerTilingData.h:
+        (WebCore):
+        (Tile):
+        (WebCore::CCLayerTilingData::Tile::opaqueRect):
+        (WebCore::CCLayerTilingData::Tile::setOpaqueRect):
+        (CCLayerTilingData):
+        * platform/graphics/chromium/cc/CCOcclusionTracker.cpp:
+        (WebCore::::CCOcclusionTrackerBase):
+        (WebCore::computeOcclusionBehindLayer):
+        (WebCore::::markOccludedBehindLayer):
+        * platform/graphics/chromium/cc/CCOcclusionTracker.h:
+        (CCOcclusionTrackerBase):
+        (WebCore::CCOcclusionTrackerBase::setUsePaintTracking):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
+        (DrawableTile):
+        (WebCore::CCTiledLayerImpl::opaqueContentsRegion):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.h:
+        (CCTiledLayerImpl):
+
 2012-03-09  Antti Koivisto  <antti@apple.com>
 
         Presentation attribute cache
index dd55cdcd916af6bfa2c86490fca7b6cbf5b1fb67..36cff810d5679d8e930893eab1584b23d39f8be1 100644 (file)
@@ -227,6 +227,8 @@ public:
 
     void setAnimationEvent(const CCAnimationEvent&, double wallClockTime);
 
+    virtual Region opaqueContentsRegion() const { return Region(); };
+
 protected:
     friend class CCLayerImpl;
     friend class LayerTilerChromium;
index 05f1bf4646a0657c7c6c99a5836c0f4aea1b3d2b..0259a23d386dd3d1ac8a98bc284e2382c54c63e1 100644 (file)
@@ -72,7 +72,6 @@ public:
 
     IntRect m_dirtyRect;
     IntRect m_updateRect;
-    IntRect m_opaqueRect;
     bool m_partialUpdate;
 private:
     explicit UpdatableTile(PassOwnPtr<LayerTextureUpdater::Texture> texture)
@@ -268,7 +267,7 @@ void TiledLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
         if (tile->isDirtyForCurrentFrame())
             continue;
 
-        tiledLayer->pushTileProperties(i, j, tile->managedTexture()->textureId(), tile->m_opaqueRect);
+        tiledLayer->pushTileProperties(i, j, tile->managedTexture()->textureId(), tile->opaqueRect());
     }
     for (Vector<UpdatableTile*>::const_iterator iter = invalidTiles.begin(); iter != invalidTiles.end(); ++iter)
         m_tiler->takeTile((*iter)->i(), (*iter)->j());
@@ -503,12 +502,12 @@ void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int
             IntRect tilePaintedRect = intersection(tileRect, m_paintRect);
             IntRect tilePaintedOpaqueRect = intersection(tileRect, paintedOpaqueRect);
             if (!tilePaintedRect.isEmpty()) {
-                IntRect paintInsideTileOpaqueRect = intersection(tile->m_opaqueRect, tilePaintedRect);
+                IntRect paintInsideTileOpaqueRect = intersection(tile->opaqueRect(), tilePaintedRect);
                 bool paintInsideTileOpaqueRectIsNonOpaque = !tilePaintedOpaqueRect.contains(paintInsideTileOpaqueRect);
-                bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect.isEmpty() && !tile->m_opaqueRect.contains(tilePaintedOpaqueRect);
+                bool opaquePaintNotInsideTileOpaqueRect = !tilePaintedOpaqueRect.isEmpty() && !tile->opaqueRect().contains(tilePaintedOpaqueRect);
 
                 if (paintInsideTileOpaqueRectIsNonOpaque || opaquePaintNotInsideTileOpaqueRect)
-                    tile->m_opaqueRect = tilePaintedOpaqueRect;
+                    tile->setOpaqueRect(tilePaintedOpaqueRect);
             }
 
             // sourceRect starts as a full-sized tile with border texels included.
@@ -554,6 +553,14 @@ void TiledLayerChromium::reserveTextures()
     }
 }
 
+Region TiledLayerChromium::opaqueContentsRegion() const
+{
+    if (m_skipsDraw)
+        return Region();
+
+    return m_tiler->opaqueRegionInLayerRect(visibleLayerRect());
+}
+
 void TiledLayerChromium::resetUpdateState()
 {
     // Reset m_updateRect for all tiles.
index c936e6dec7430f6a343571845a0fc3d97760fea0..6ff901dfdbff762f046363b34a48452c04d12100 100644 (file)
@@ -66,6 +66,8 @@ public:
 
     virtual void reserveTextures();
 
+    virtual Region opaqueContentsRegion() const;
+
 protected:
     TiledLayerChromium();
 
index 2a2d9e84874b731af25897f55098d035e89d9eb5..f1c7b4ee517221c488a6afc932fb08cc9f794c31 100644 (file)
@@ -215,6 +215,8 @@ public:
 
     CCLayerAnimationControllerImpl* layerAnimationController() { return m_layerAnimationController.get(); }
 
+    virtual Region opaqueContentsRegion() const { return Region(); };
+
     // Indicates that the context previously used to render this layer
     // was lost and that a new one has been created. Won't be called
     // until the new context has been created successfully.
index cfefbd2b801d206926865c13552862f646402827..19d0251dc0acf9e382ec0f1fdfe7d03de6bd90b8 100644 (file)
@@ -112,6 +112,24 @@ IntRect CCLayerTilingData::tileRect(const Tile* tile) const
     return tileRect;
 }
 
+Region CCLayerTilingData::opaqueRegionInLayerRect(const IntRect& layerRect) const
+{
+    Region opaqueRegion;
+    int left, top, right, bottom;
+    layerRectToTileIndices(layerRect, left, top, right, bottom);
+    for (int j = top; j <= bottom; ++j) {
+        for (int i = left; i <= right; ++i) {
+            Tile* tile = tileAt(i, j);
+            if (!tile)
+                continue;
+
+            IntRect tileOpaqueRect = intersection(layerRect, tile->opaqueRect());
+            opaqueRegion.unite(tileOpaqueRect);
+        }
+    }
+    return opaqueRegion;
+}
+
 void CCLayerTilingData::setBounds(const IntSize& size)
 {
     m_tilingData.setTotalSize(size.width(), size.height());
index 869d42e15ac630a531fb53d42d96d40763fd86ee..9e18695e8c1422b6c6c7ff53736cbaa4994fe3bb 100644 (file)
@@ -30,6 +30,7 @@
 #if USE(ACCELERATED_COMPOSITING)
 
 #include "IntRect.h"
+#include "Region.h"
 #include "TilingData.h"
 #include <wtf/HashMap.h>
 #include <wtf/HashTraits.h>
@@ -69,9 +70,13 @@ public:
         int i() const { return m_i; }
         int j() const { return m_j; }
         void moveTo(int i, int j) { m_i = i; m_j = j; }
+
+        const IntRect& opaqueRect() const { return m_opaqueRect; }
+        void setOpaqueRect(const IntRect& opaqueRect) { m_opaqueRect = opaqueRect; }
     private:
         int m_i;
         int m_j;
+        IntRect m_opaqueRect;
     };
     // Default hash key traits for integers disallow 0 and -1 as a key, so
     // use a custom hash trait which disallows -1 and -2 instead.
@@ -96,6 +101,8 @@ public:
     void layerRectToTileIndices(const IntRect&, int &left, int &top, int &right, int &bottom) const;
     IntRect tileRect(const Tile*) const;
 
+    Region opaqueRegionInLayerRect(const IntRect&) const;
+
     void reset();
 
 protected:
index 14e28280d51da9834c9da122d6291fa9b06c0295..34bce118100fa5fa38d9352820d5708e9feddca2 100644 (file)
@@ -540,6 +540,7 @@ void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList
     typedef CCLayerIterator<LayerChromium, Vector<RefPtr<LayerChromium> >, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
 
     CCOcclusionTracker occlusionTracker(IntRect(IntPoint(), viewportSize()));
+    occlusionTracker.setUsePaintTracking(false); // FIXME: Remove this to turn on paint tracking for paint culling
 
     CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
     for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
index 6585454ffcb760ed8d1f5f3d3a492c377e4368c8..f1c93388250f5b425e5eeb16ce6580781b329c29 100644 (file)
@@ -42,6 +42,7 @@ template<typename LayerType, typename RenderSurfaceType>
 CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace)
     : m_scissorRectInScreenSpace(scissorRectInScreenSpace)
     , m_surfaceDamageClient(0)
+    , m_usePaintTracking(true) // FIXME: Remove this when paint tracking is on for paint culling.
 {
 }
 
@@ -49,6 +50,7 @@ template<typename LayerType, typename RenderSurfaceType>
 CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::CCOcclusionTrackerBase(IntRect scissorRectInScreenSpace, const DamageClientType* surfaceDamageClient)
     : m_scissorRectInScreenSpace(scissorRectInScreenSpace)
     , m_surfaceDamageClient(surfaceDamageClient)
+    , m_usePaintTracking(true) // FIXME: Remove this when paint tracking is on for paint culling.
 {
 }
 
@@ -184,8 +186,9 @@ static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerTy
     return transform;
 }
 
+// FIXME: Remove usePaintTracking when paint tracking is on for paint culling.
 template<typename LayerType>
-static inline Region computeOcclusionBehindLayer(const LayerType* layer, const TransformationMatrix& transform)
+static inline Region computeOcclusionBehindLayer(const LayerType* layer, const TransformationMatrix& transform, bool usePaintTracking)
 {
     Region opaqueRegion;
 
@@ -196,7 +199,14 @@ static inline Region computeOcclusionBehindLayer(const LayerType* layer, const T
 
     if (layer->opaque())
         opaqueRegion = enclosedIntRect(unoccludedQuad.boundingBox());
-    // FIXME: Capture opaque paints: else opaqueRegion = layer->opaqueContentsRegion(transform);
+    else if (usePaintTracking && transform.isIdentity())
+        opaqueRegion = layer->opaqueContentsRegion();
+    else if (usePaintTracking) {
+        Region contentRegion = layer->opaqueContentsRegion();
+        Vector<IntRect> contentRects = contentRegion.rects();
+        for (size_t i = 0; i < contentRects.size(); ++i)
+            opaqueRegion.unite(enclosedIntRect(transform.mapRect(FloatRect(contentRects[i]))));
+    }
     return opaqueRegion;
 }
 
@@ -214,8 +224,9 @@ void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::markOccludedBehindLay
     TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
     TransformationMatrix contentToTargetSurface = contentToTargetSurfaceTransform<LayerType>(layer);
 
-    m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpace));
-    m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurface));
+    // FIXME: Remove m_usePaintTracking when paint tracking is on for paint culling.
+    m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpace, m_usePaintTracking));
+    m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurface, m_usePaintTracking));
 }
 
 static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion)
index b7c0e3b28fc07313ae6e120dd93ad376fbdc0d87..19fc2c1dd0dac8255b5642824327803b12aeee34 100644 (file)
@@ -77,6 +77,9 @@ public:
     // Gives an unoccluded sub-rect of |contentRect| in the content space of the layer. Used when considering occlusion for a layer that paints/draws something.
     IntRect unoccludedContentRect(const LayerType*, const IntRect& contentRect) const;
 
+    // FIXME: Remove this when paint tracking is on for paint culling.
+    void setUsePaintTracking(bool use) { m_usePaintTracking = use; }
+
     // FIXME: Remove these in future, they are to make CLs for transitioning to this easier.
     const Region& currentOcclusionInScreenSpace() const;
     const Region& currentOcclusionInTargetSurface() const;
@@ -103,6 +106,7 @@ protected:
 private:
     IntRect m_scissorRectInScreenSpace;
     const DamageClientType* m_surfaceDamageClient;
+    bool m_usePaintTracking; // FIXME: Remove this when paint tracking is on for paint culling.
 };
 
 typedef CCOcclusionTrackerBase<LayerChromium, RenderSurfaceChromium> CCOcclusionTracker;
index 47d0a708c32c765f8511856e4e2f0e827021a089..e8d2a6c45a9f66a4b9ee1f7e614278eaa71e29f4 100644 (file)
@@ -52,14 +52,10 @@ 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:
     DrawableTile() : m_textureId(0) { }
 
     Platform3DObject m_textureId;
-    IntRect m_opaqueRect;
 };
 
 CCTiledLayerImpl::CCTiledLayerImpl(int id)
@@ -203,6 +199,14 @@ void CCTiledLayerImpl::pushTileProperties(int i, int j, Platform3DObject texture
     tile->setOpaqueRect(opaqueRect);
 }
 
+Region CCTiledLayerImpl::opaqueContentsRegion() const
+{
+    if (m_skipsDraw)
+        return Region();
+
+    return m_tiler->opaqueRegionInLayerRect(visibleLayerRect());
+}
+
 } // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)
index 7e637cffb4cc7bf7bdaaf9d609bd2a356149ff03..84fe47621795c2749f052b467047bdcdb05fe257 100644 (file)
@@ -56,6 +56,8 @@ public:
     void setContentsSwizzled(bool contentsSwizzled) { m_contentsSwizzled = contentsSwizzled; }
     bool contentsSwizzled() const { return m_contentsSwizzled; }
 
+    virtual Region opaqueContentsRegion() const;
+
     typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexAlpha> Program;
     // Shader program that swaps red and blue components of texture.
     // Used when texture format does not match native color format.
index e2ea9a44f1b55bf2e1ad301ef5605636e6e86075..9155993a516fee8265bc2b2ad0e0a0792d1aff34 100644 (file)
@@ -1,3 +1,45 @@
+2012-03-09  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Use opaque paints in CCOcclusionTracker
+        https://bugs.webkit.org/show_bug.cgi?id=80173
+
+        Reviewed by Adrienne Walker.
+
+        * tests/CCOcclusionTrackerTest.cpp:
+        (WebCore::LayerChromiumWithForcedDrawsContent::opaqueContentsRegion):
+        (LayerChromiumWithForcedDrawsContent):
+        (WebCore::LayerChromiumWithForcedDrawsContent::setOpaquePaintRect):
+        (WebCore::setLayerPropertiesForTesting):
+        (WebCore):
+        (WebCore::layerAddedToOccludedRegion):
+        (WebCore::layerAddedToOccludedRegionWithRotation):
+        (WebCore::layerAddedToOccludedRegionWithTranslation):
+        (WebCore::layerAddedToOccludedRegionWithRotatedSurface):
+        (WebCore::layerAddedToOccludedRegionWithSurfaceAlreadyOnStack):
+        (WebCore::layerAddedToOccludedRegionWithRotatedOffAxisSurface):
+        (WebCore::layerAddedToOccludedRegionWithMultipleOpaqueLayers):
+        (WebCore::surfaceOcclusionWithOverlappingSiblingSurfaces):
+        (WebCore::surfaceOcclusionInScreenSpace):
+        (WebCore::surfaceOcclusionInScreenSpaceDifferentTransforms):
+        (WebCore::occlusionInteractionWithFilters):
+        (WebCore::layerScissorRectOverTile):
+        (WebCore::screenScissorRectOverTile):
+        (WebCore::layerScissorRectOverCulledTile):
+        (WebCore::screenScissorRectOverCulledTile):
+        (WebCore::layerScissorRectOverPartialTiles):
+        (WebCore::screenScissorRectOverPartialTiles):
+        (WebCore::layerScissorRectOverNoTiles):
+        (WebCore::screenScissorRectOverNoTiles):
+        (WebCore::layerScissorRectForLayerOffOrigin):
+        (WebCore::damageRectOverTile):
+        (WebCore::damageRectOverCulledTile):
+        (WebCore::damageRectOverPartialTiles):
+        (WebCore::damageRectOverNoTiles):
+        (WebCore::TEST):
+        * tests/TiledLayerChromiumTest.cpp:
+        (WTF::TEST):
+        (WTF):
+
 2012-03-09  Jon Lee  <jonlee@apple.com>
 
         Add support for ENABLE(LEGACY_NOTIFICATIONS)
index 765b491ac569bed170378016227962ee73a3ffbc..26d52523be134c2efc978b34a0bd4c3320509cac 100644 (file)
@@ -45,16 +45,6 @@ using namespace WebCore;
 
 namespace {
 
-void setLayerPropertiesForTesting(LayerChromium* layer, const TransformationMatrix& transform, const TransformationMatrix& sublayerTransform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool opaque)
-{
-    layer->setTransform(transform);
-    layer->setSublayerTransform(sublayerTransform);
-    layer->setAnchorPoint(anchor);
-    layer->setPosition(position);
-    layer->setBounds(bounds);
-    layer->setOpaque(opaque);
-}
-
 class LayerChromiumWithForcedDrawsContent : public LayerChromium {
 public:
     LayerChromiumWithForcedDrawsContent()
@@ -63,8 +53,40 @@ public:
     }
 
     virtual bool drawsContent() const { return true; }
+    virtual Region opaqueContentsRegion() const
+    {
+        return intersection(m_opaquePaintRect, visibleLayerRect());
+    }
+
+    void setOpaquePaintRect(const IntRect& opaquePaintRect) { m_opaquePaintRect = opaquePaintRect; }
+
+private:
+    IntRect m_opaquePaintRect;
 };
 
+void setLayerPropertiesForTesting(LayerChromium* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
+{
+    layer->setTransform(transform);
+    layer->setSublayerTransform(TransformationMatrix());
+    layer->setAnchorPoint(FloatPoint(0, 0));
+    layer->setPosition(position);
+    layer->setBounds(bounds);
+}
+
+void setLayerPropertiesForTesting(LayerChromiumWithForcedDrawsContent* layer, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque, bool opaqueLayers)
+{
+    setLayerPropertiesForTesting(layer, transform, position, bounds);
+    if (opaqueLayers)
+        layer->setOpaque(opaque);
+    else {
+        layer->setOpaque(false);
+        if (opaque)
+            layer->setOpaquePaintRect(IntRect(IntPoint(), bounds));
+        else
+            layer->setOpaquePaintRect(IntRect());
+    }
+}
+
 // A subclass to expose the total current occlusion.
 class TestCCOcclusionTracker : public CCOcclusionTracker {
 public:
@@ -110,7 +132,17 @@ private:
     FloatRect m_damageRect;
 };
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegion)
+#define TEST_OPAQUE_AND_PAINTED_OPAQUE(FULLTESTNAME, SHORTTESTNAME) \
+    TEST(FULLTESTNAME, opaqueLayer)                                 \
+    {                                                               \
+        SHORTTESTNAME(true);                                        \
+    }                                                               \
+    TEST(FULLTESTNAME, opaquePaintRect)                             \
+    {                                                               \
+        SHORTTESTNAME(false);                                       \
+    }
+
+void layerAddedToOccludedRegion(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -119,8 +151,8 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegion)
     parent->createRenderSurface();
     parent->addChild(layer);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -167,7 +199,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegion)
     EXPECT_EQ_RECT(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 31, 70, 70)));
 }
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotation)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegion, layerAddedToOccludedRegion);
+
+void layerAddedToOccludedRegionWithRotation(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -181,8 +215,8 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotation)
     layerTransform.rotate(90);
     layerTransform.translate(-250, -250);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(layer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -229,7 +263,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotation)
     EXPECT_EQ_RECT(IntRect(29, 31, 70, 70), occlusion.unoccludedContentRect(parent.get(), IntRect(29, 31, 70, 70)));
 }
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithTranslation)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithRotation, layerAddedToOccludedRegionWithRotation);
+
+void layerAddedToOccludedRegionWithTranslation(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -241,8 +277,8 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithTranslation)
     TransformationMatrix layerTransform;
     layerTransform.translate(20, 20);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(layer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -301,7 +337,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithTranslation)
     occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
 }
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotatedSurface)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithTranslation, layerAddedToOccludedRegionWithTranslation);
+
+void layerAddedToOccludedRegionWithRotatedSurface(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -317,9 +355,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotatedSurface)
     childTransform.rotate(90);
     childTransform.translate(-250, -250);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true, opaqueLayers);
 
     child->setMasksToBounds(true);
 
@@ -408,7 +446,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotatedSurface)
      */
 }
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithSurfaceAlreadyOnStack)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithRotatedSurface, layerAddedToOccludedRegionWithRotatedSurface);
+
+void layerAddedToOccludedRegionWithSurfaceAlreadyOnStack(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -426,13 +466,13 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithSurfaceAlreadyOnStack
     childTransform.rotate(90);
     childTransform.translate(-250, -250);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(10, 10), IntSize(500, 500), true, opaqueLayers);
 
     // |child2| makes |parent|'s surface get considered by CCOcclusionTracker first, instead of |child|'s. This exercises different code in
     // leaveToTargetRenderSurface, as the target surface has already been seen.
-    setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(60, 20), true);
+    setLayerPropertiesForTesting(child2.get(), identityMatrix, FloatPoint(30, 30), IntSize(60, 20), true, opaqueLayers);
 
     child->setMasksToBounds(true);
 
@@ -574,7 +614,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithSurfaceAlreadyOnStack
      */
 }
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotatedOffAxisSurface)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithSurfaceAlreadyOnStack, layerAddedToOccludedRegionWithSurfaceAlreadyOnStack);
+
+void layerAddedToOccludedRegionWithRotatedOffAxisSurface(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -595,9 +637,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotatedOffAxisSurface
     TransformationMatrix layerTransform;
     layerTransform.translate(10, 10);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false);
-    setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
+    setLayerPropertiesForTesting(layer.get(), layerTransform, FloatPoint(0, 0), IntSize(500, 500), true, opaqueLayers);
 
     child->setMasksToBounds(true);
 
@@ -656,7 +698,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithRotatedOffAxisSurface
     EXPECT_EQ_RECT(IntRect(75, 55, 1, 1), occlusion.unoccludedContentRect(parent.get(), IntRect(75, 55, 1, 1)));
 }
 
-TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithMultipleOpaqueLayers)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithRotatedOffAxisSurface, layerAddedToOccludedRegionWithRotatedOffAxisSurface);
+
+void layerAddedToOccludedRegionWithMultipleOpaqueLayers(bool opaqueLayers)
 {
     // This is similar to the previous test but now we make a few opaque layers inside of |child| so that the occluded parts of child are not a simple rect.
     const TransformationMatrix identityMatrix;
@@ -674,10 +718,10 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithMultipleOpaqueLayers)
     childTransform.rotate(90);
     childTransform.translate(-250, -250);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false);
-    setLayerPropertiesForTesting(layer1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 440), true);
-    setLayerPropertiesForTesting(layer2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(10, 450), IntSize(500, 60), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
+    setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(10, 10), IntSize(500, 440), true, opaqueLayers);
+    setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(10, 450), IntSize(500, 60), true, opaqueLayers);
 
     child->setMasksToBounds(true);
 
@@ -760,7 +804,9 @@ TEST(CCOcclusionTrackerTest, layerAddedToOccludedRegionWithMultipleOpaqueLayers)
      */
 }
 
-TEST(CCOcclusionTrackerTest, surfaceOcclusionWithOverlappingSiblingSurfaces)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerAddedToOccludedRegionWithMultipleOpaqueLayers, layerAddedToOccludedRegionWithMultipleOpaqueLayers);
+
+void surfaceOcclusionWithOverlappingSiblingSurfaces(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -780,11 +826,11 @@ TEST(CCOcclusionTrackerTest, surfaceOcclusionWithOverlappingSiblingSurfaces)
     childTransform.rotate(90);
     childTransform.translate(-250, -250);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child1.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false);
-    setLayerPropertiesForTesting(layer1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), true);
-    setLayerPropertiesForTesting(child2.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(20, 40), IntSize(500, 500), false);
-    setLayerPropertiesForTesting(layer2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child1.get(), childTransform, FloatPoint(30, 30), IntSize(500, 500));
+    setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(0, 0), IntSize(500, 500), true, opaqueLayers);
+    setLayerPropertiesForTesting(child2.get(), childTransform, FloatPoint(20, 40), IntSize(500, 500));
+    setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(0, 0), IntSize(500, 500), true, opaqueLayers);
 
     child1->setMasksToBounds(true);
     child2->setMasksToBounds(true);
@@ -878,7 +924,9 @@ TEST(CCOcclusionTrackerTest, surfaceOcclusionWithOverlappingSiblingSurfaces)
      */
 }
 
-TEST(CCOcclusionTrackerTest, surfaceOcclusionInScreenSpace)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_surfaceOcclusionWithOverlappingSiblingSurfaces, surfaceOcclusionWithOverlappingSiblingSurfaces);
+
+void surfaceOcclusionInScreenSpace(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -899,11 +947,11 @@ TEST(CCOcclusionTrackerTest, surfaceOcclusionInScreenSpace)
     childTransform.translate(-250, -250);
 
     // The owning layers have very different bounds from the surfaces that they own.
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child1.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(10, 10), false);
-    setLayerPropertiesForTesting(layer1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(-10, -10), IntSize(510, 510), true);
-    setLayerPropertiesForTesting(child2.get(), childTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(20, 40), IntSize(10, 10), false);
-    setLayerPropertiesForTesting(layer2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(-10, -10), IntSize(510, 510), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child1.get(), childTransform, FloatPoint(30, 30), IntSize(10, 10));
+    setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true, opaqueLayers);
+    setLayerPropertiesForTesting(child2.get(), childTransform, FloatPoint(20, 40), IntSize(10, 10));
+    setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true, opaqueLayers);
 
     // Make them both render surfaces
     FilterOperations filters;
@@ -1010,7 +1058,9 @@ TEST(CCOcclusionTrackerTest, surfaceOcclusionInScreenSpace)
      */
 }
 
-TEST(CCOcclusionTrackerTest, surfaceOcclusionInScreenSpaceDifferentTransforms)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_surfaceOcclusionInScreenSpace, surfaceOcclusionInScreenSpace);
+
+void surfaceOcclusionInScreenSpaceDifferentTransforms(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -1036,11 +1086,11 @@ TEST(CCOcclusionTrackerTest, surfaceOcclusionInScreenSpaceDifferentTransforms)
     child2Transform.translate(-250, -250);
 
     // The owning layers have very different bounds from the surfaces that they own.
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(child1.get(), child1Transform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 20), IntSize(10, 10), false);
-    setLayerPropertiesForTesting(layer1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(-10, -20), IntSize(510, 520), true);
-    setLayerPropertiesForTesting(child2.get(), child2Transform, identityMatrix, FloatPoint(0, 0), FloatPoint(20, 40), IntSize(10, 10), false);
-    setLayerPropertiesForTesting(layer2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(-10, -10), IntSize(510, 510), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(child1.get(), child1Transform, FloatPoint(30, 20), IntSize(10, 10));
+    setLayerPropertiesForTesting(layer1.get(), identityMatrix, FloatPoint(-10, -20), IntSize(510, 520), true, opaqueLayers);
+    setLayerPropertiesForTesting(child2.get(), child2Transform, FloatPoint(20, 40), IntSize(10, 10));
+    setLayerPropertiesForTesting(layer2.get(), identityMatrix, FloatPoint(-10, -10), IntSize(510, 510), true, opaqueLayers);
 
     // Make them both render surfaces
     FilterOperations filters;
@@ -1135,7 +1185,9 @@ TEST(CCOcclusionTrackerTest, surfaceOcclusionInScreenSpaceDifferentTransforms)
      */
 }
 
-TEST(CCOcclusionTrackerTest, occlusionInteractionWithFilters)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_surfaceOcclusionInScreenSpaceDifferentTransforms, surfaceOcclusionInScreenSpaceDifferentTransforms);
+
+void occlusionInteractionWithFilters(bool opaqueLayers)
 {
     // This tests that the right transforms are being used.
     const TransformationMatrix identityMatrix;
@@ -1153,10 +1205,10 @@ TEST(CCOcclusionTrackerTest, occlusionInteractionWithFilters)
     layerTransform.rotate(90);
     layerTransform.translate(-250, -250);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
-    setLayerPropertiesForTesting(blurLayer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
-    setLayerPropertiesForTesting(opaqueLayer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
-    setLayerPropertiesForTesting(opacityLayer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(100, 100));
+    setLayerPropertiesForTesting(blurLayer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
+    setLayerPropertiesForTesting(opaqueLayer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
+    setLayerPropertiesForTesting(opacityLayer.get(), layerTransform, FloatPoint(30, 30), IntSize(500, 500), true, opaqueLayers);
 
     {
         FilterOperations filters;
@@ -1239,7 +1291,9 @@ TEST(CCOcclusionTrackerTest, occlusionInteractionWithFilters)
     EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
 }
 
-TEST(CCOcclusionTrackerTest, layerScissorRectOverTile)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_occlusionInteractionWithFilters, occlusionInteractionWithFilters);
+
+void layerScissorRectOverTile(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1254,9 +1308,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverTile)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1302,7 +1356,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverTile)
     EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
 }
 
-TEST(CCOcclusionTrackerTest, screenScissorRectOverTile)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverTile, layerScissorRectOverTile);
+
+void screenScissorRectOverTile(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1317,9 +1373,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverTile)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1367,7 +1423,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverTile)
     EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
 }
 
-TEST(CCOcclusionTrackerTest, layerScissorRectOverCulledTile)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverTile, screenScissorRectOverTile);
+
+void layerScissorRectOverCulledTile(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1382,9 +1440,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverCulledTile)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1425,7 +1483,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverCulledTile)
     EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
 }
 
-TEST(CCOcclusionTrackerTest, screenScissorRectOverCulledTile)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverCulledTile, layerScissorRectOverCulledTile);
+
+void screenScissorRectOverCulledTile(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1440,9 +1500,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverCulledTile)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1482,7 +1542,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverCulledTile)
     EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
 }
 
-TEST(CCOcclusionTrackerTest, layerScissorRectOverPartialTiles)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverCulledTile, screenScissorRectOverCulledTile);
+
+void layerScissorRectOverPartialTiles(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1497,9 +1559,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverPartialTiles)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1544,7 +1606,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverPartialTiles)
     EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)));
 }
 
-TEST(CCOcclusionTrackerTest, screenScissorRectOverPartialTiles)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverPartialTiles, layerScissorRectOverPartialTiles);
+
+void screenScissorRectOverPartialTiles(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1559,9 +1623,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverPartialTiles)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1605,7 +1669,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverPartialTiles)
     EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)));
 }
 
-TEST(CCOcclusionTrackerTest, layerScissorRectOverNoTiles)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverPartialTiles, screenScissorRectOverPartialTiles);
+
+void layerScissorRectOverNoTiles(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1620,9 +1686,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverNoTiles)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1667,7 +1733,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectOverNoTiles)
     EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)).isEmpty());
 }
 
-TEST(CCOcclusionTrackerTest, screenScissorRectOverNoTiles)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectOverNoTiles, layerScissorRectOverNoTiles);
+
+void screenScissorRectOverNoTiles(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1682,9 +1750,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverNoTiles)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1728,7 +1796,9 @@ TEST(CCOcclusionTrackerTest, screenScissorRectOverNoTiles)
     EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)).isEmpty());
 }
 
-TEST(CCOcclusionTrackerTest, layerScissorRectForLayerOffOrigin)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_screenScissorRectOverNoTiles, screenScissorRectOverNoTiles);
+
+void layerScissorRectForLayerOffOrigin(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1743,9 +1813,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectForLayerOffOrigin)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(100, 100), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(100, 100), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1770,7 +1840,9 @@ TEST(CCOcclusionTrackerTest, layerScissorRectForLayerOffOrigin)
     EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
 }
 
-TEST(CCOcclusionTrackerTest, damageRectOverTile)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_layerScissorRectForLayerOffOrigin, layerScissorRectForLayerOffOrigin);
+
+void damageRectOverTile(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1785,9 +1857,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverTile)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1819,7 +1891,7 @@ TEST(CCOcclusionTrackerTest, damageRectOverTile)
     EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 0, 100, 100)));
     EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
     EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 0, 100, 100)));
-    EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 100, 100, 100)));
+    EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(100, 100, 100, 100)));
     EXPECT_FALSE(occlusion.occluded(parentLayer.get(), IntRect(200, 100, 100, 100)));
     EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(200, 0, 100, 100)));
     EXPECT_TRUE(occlusion.occluded(parentLayer.get(), IntRect(0, 200, 100, 100)));
@@ -1831,7 +1903,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverTile)
     EXPECT_EQ_RECT(IntRect(200, 100, 100, 100), occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)));
 }
 
-TEST(CCOcclusionTrackerTest, damageRectOverCulledTile)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverTile, damageRectOverTile);
+
+void damageRectOverCulledTile(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1846,9 +1920,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverCulledTile)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1889,7 +1963,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverCulledTile)
     EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(0, 0, 300, 300)).isEmpty());
 }
 
-TEST(CCOcclusionTrackerTest, damageRectOverPartialTiles)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverCulledTile, damageRectOverCulledTile);
+
+void damageRectOverPartialTiles(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1904,9 +1980,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverPartialTiles)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -1951,7 +2027,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverPartialTiles)
     EXPECT_EQ_RECT(IntRect(100, 200, 100, 50), occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)));
 }
 
-TEST(CCOcclusionTrackerTest, damageRectOverNoTiles)
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverPartialTiles, damageRectOverPartialTiles);
+
+void damageRectOverNoTiles(bool opaqueLayers)
 {
     const TransformationMatrix identityMatrix;
     RefPtr<LayerChromium> parent = LayerChromium::create();
@@ -1966,9 +2044,9 @@ TEST(CCOcclusionTrackerTest, damageRectOverNoTiles)
     parentLayer->setFilters(filters);
     layer->setFilters(filters);
 
-    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(300, 300), false);
-    setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(parentLayer.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300), false, opaqueLayers);
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), true, opaqueLayers);
 
     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
     Vector<RefPtr<LayerChromium> > dummyLayerList;
@@ -2013,4 +2091,122 @@ TEST(CCOcclusionTrackerTest, damageRectOverNoTiles)
     EXPECT_TRUE(occlusion.unoccludedContentRect(parent.get(), IntRect(100, 200, 100, 100)).isEmpty());
 }
 
+TEST_OPAQUE_AND_PAINTED_OPAQUE(CCOcclusionTrackerTest_damageRectOverNoTiles, damageRectOverNoTiles);
+
+TEST(CCOcclusionTrackerTest, opaqueContentsRegionEmpty)
+{
+    const TransformationMatrix identityMatrix;
+    RefPtr<LayerChromium> parent = LayerChromium::create();
+    RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    parent->createRenderSurface();
+    parent->addChild(layer);
+
+    FilterOperations filters;
+    filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
+    layer->setFilters(filters);
+
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(0, 0), IntSize(200, 200), false, false);
+
+    Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+    Vector<RefPtr<LayerChromium> > dummyLayerList;
+    int dummyMaxTextureSize = 512;
+
+    parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
+    parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+    renderSurfaceLayerList.append(parent);
+
+    CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+    TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
+
+    occlusion.enterTargetRenderSurface(layer->renderSurface());
+
+    EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 0, 100, 100)));
+    EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 0, 100, 100)));
+    EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(0, 100, 100, 100)));
+    EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(100, 100, 100, 100)));
+
+    // Occluded since its outside the surface bounds.
+    EXPECT_TRUE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
+
+    // Test without any scissors.
+    occlusion.setLayerScissorRect(IntRect(0, 0, 1000, 1000));
+    EXPECT_FALSE(occlusion.occluded(layer.get(), IntRect(200, 100, 100, 100)));
+    occlusion.useDefaultLayerScissorRect();
+
+    occlusion.markOccludedBehindLayer(layer.get());
+    occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+
+    EXPECT_TRUE(occlusion.occlusionInScreenSpace().bounds().isEmpty());
+    EXPECT_EQ(0u, occlusion.occlusionInScreenSpace().rects().size());
+}
+
+TEST(CCOcclusionTrackerTest, opaqueContentsRegionNonEmpty)
+{
+    const TransformationMatrix identityMatrix;
+    RefPtr<LayerChromium> parent = LayerChromium::create();
+    RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    parent->createRenderSurface();
+    parent->addChild(layer);
+
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+    setLayerPropertiesForTesting(layer.get(), identityMatrix, FloatPoint(100, 100), IntSize(200, 200), false, false);
+
+    Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+    Vector<RefPtr<LayerChromium> > dummyLayerList;
+    int dummyMaxTextureSize = 512;
+
+    parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
+    parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+    renderSurfaceLayerList.append(parent);
+
+    CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+    {
+        TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
+        layer->setOpaquePaintRect(IntRect(0, 0, 100, 100));
+
+        occlusion.enterTargetRenderSurface(parent->renderSurface());
+        occlusion.markOccludedBehindLayer(layer.get());
+
+        EXPECT_EQ_RECT(IntRect(100, 100, 100, 100), occlusion.occlusionInScreenSpace().bounds());
+        EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(0, 100, 100, 100)));
+        EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(100, 100, 100, 100)));
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(200, 200, 100, 100)));
+    }
+
+    {
+        TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
+        layer->setOpaquePaintRect(IntRect(20, 20, 180, 180));
+
+        occlusion.enterTargetRenderSurface(parent->renderSurface());
+        occlusion.markOccludedBehindLayer(layer.get());
+
+        EXPECT_EQ_RECT(IntRect(120, 120, 180, 180), occlusion.occlusionInScreenSpace().bounds());
+        EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(0, 100, 100, 100)));
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(100, 100, 100, 100)));
+        EXPECT_TRUE(occlusion.occluded(parent.get(), IntRect(200, 200, 100, 100)));
+    }
+
+    {
+        TestCCOcclusionTracker occlusion(IntRect(0, 0, 1000, 1000));
+        layer->setOpaquePaintRect(IntRect(150, 150, 100, 100));
+
+        occlusion.enterTargetRenderSurface(parent->renderSurface());
+        occlusion.markOccludedBehindLayer(layer.get());
+
+        EXPECT_EQ_RECT(IntRect(250, 250, 50, 50), occlusion.occlusionInScreenSpace().bounds());
+        EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(0, 100, 100, 100)));
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(100, 100, 100, 100)));
+        EXPECT_FALSE(occlusion.occluded(parent.get(), IntRect(200, 200, 100, 100)));
+    }
+}
+
 } // namespace
index 0ddaeca42c07a348ad707c7bcaf004f107de6fac..2523230e005cb91e154d919cc7e9c965f0f94103 100644 (file)
@@ -957,4 +957,64 @@ TEST(TiledLayerChromiumTest, tilesPaintedWithOcclusionAndScaling)
     EXPECT_EQ(9-1, layer->fakeLayerTextureUpdater()->prepareRectCount());
 }
 
+TEST(TiledLayerChromiumTest, opaqueContentsRegion)
+{
+    OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024);
+    RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get()));
+
+    // The tile size is 100x100, so this invalidates and then paints two tiles in various ways.
+
+    IntRect opaquePaintRect;
+    Region opaqueContents;
+    Region noOcclusion;
+
+    IntRect contentBounds = IntRect(0, 0, 100, 200);
+    IntRect visibleBounds = IntRect(0, 0, 100, 150);
+
+    layer->setBounds(contentBounds.size());
+    layer->setVisibleLayerRect(visibleBounds);
+    layer->setDrawOpacity(1);
+
+    // If the layer doesn't paint opaque content, then the opaqueContentsRegion should be empty.
+    layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
+    layer->invalidateRect(contentBounds);
+    layer->prepareToUpdate(contentBounds, noOcclusion);
+    opaqueContents = layer->opaqueContentsRegion();
+    EXPECT_TRUE(opaqueContents.isEmpty());
+
+    // opaqueContentsRegion should match the visible part of what is painted opaque.
+    opaquePaintRect = IntRect(10, 10, 90, 190);
+    layer->fakeLayerTextureUpdater()->setOpaquePaintRect(opaquePaintRect);
+    layer->invalidateRect(contentBounds);
+    layer->prepareToUpdate(contentBounds, noOcclusion);
+    opaqueContents = layer->opaqueContentsRegion();
+    EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
+    EXPECT_EQ(1u, opaqueContents.rects().size());
+
+    // If we paint again without invalidating, the same stuff should be opaque.
+    layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
+    layer->prepareToUpdate(contentBounds, noOcclusion);
+    opaqueContents = layer->opaqueContentsRegion();
+    EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
+    EXPECT_EQ(1u, opaqueContents.rects().size());
+
+    // If we repaint a non-opaque part of the tile, then it shouldn't lose its opaque-ness. And other tiles should
+    // not be affected.
+    layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
+    layer->invalidateRect(IntRect(0, 0, 1, 1));
+    layer->prepareToUpdate(contentBounds, noOcclusion);
+    opaqueContents = layer->opaqueContentsRegion();
+    EXPECT_EQ_RECT(intersection(opaquePaintRect, visibleBounds), opaqueContents.bounds());
+    EXPECT_EQ(1u, opaqueContents.rects().size());
+
+    // If we repaint an opaque part of the tile, then it should lose its opaque-ness. But other tiles should still
+    // not be affected.
+    layer->fakeLayerTextureUpdater()->setOpaquePaintRect(IntRect());
+    layer->invalidateRect(IntRect(10, 10, 1, 1));
+    layer->prepareToUpdate(contentBounds, noOcclusion);
+    opaqueContents = layer->opaqueContentsRegion();
+    EXPECT_EQ_RECT(intersection(IntRect(10, 100, 90, 100), visibleBounds), opaqueContents.bounds());
+    EXPECT_EQ(1u, opaqueContents.rects().size());
+}
+
 } // namespace