Log Message
[chromium] Don't occlude on main-thread behind layers/surfaces with impl-thread animations https://bugs.webkit.org/show_bug.cgi?id=81354
Patch by Dana Jansens <[email protected]> on 2012-03-18 Reviewed by Adrienne Walker. Source/WebCore: Layers and surfaces can have an animating opacity or translation on the impl thread. In this case, the main thread does not know their actual values, and treats these values as "unknowns". This means we can't use them for marking areas of the screen as occluded, and we can't consider a part of a layer occluded in a space that we can not reliably transform to. Unit test: CCOcclusionTrackerTestAnimationOpacity0OnMainThread CCOcclusionTrackerTestAnimationOpacity1OnMainThread CCOcclusionTrackerTestAnimationTranslateOnMainThread * platform/graphics/chromium/cc/CCOcclusionTracker.cpp: (WebCore::layerOpacityKnown): (WebCore::layerTransformsToTargetKnown): (WebCore::layerTransformsToScreenKnown): (WebCore): (WebCore::surfaceOpacityUnknown): (WebCore::surfaceTransformsToTargetUnknown): (WebCore::surfaceTransformsToScreenUnknown): (WebCore::::finishedTargetRenderSurface): (WebCore::contentToScreenSpaceTransform): (WebCore::contentToTargetSurfaceTransform): (WebCore::::markOccludedBehindLayer): (WebCore::::occluded): (WebCore::::unoccludedContentRect): Source/WebKit/chromium: * tests/CCOcclusionTrackerTest.cpp: (WebCore): (WebCore::addOpacityAnimationToLayer): (WebCore::addTransformAnimationToLayer): (CCOcclusionTrackerTestAnimationOpacity1OnMainThread): (WebCore::CCOcclusionTrackerTestAnimationOpacity1OnMainThread::runMyTest): (CCOcclusionTrackerTestAnimationOpacity0OnMainThread): (WebCore::CCOcclusionTrackerTestAnimationOpacity0OnMainThread::runMyTest): (CCOcclusionTrackerTestAnimationTranslateOnMainThread): (WebCore::CCOcclusionTrackerTestAnimationTranslateOnMainThread::runMyTest):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (111144 => 111145)
--- trunk/Source/WebCore/ChangeLog 2012-03-19 00:58:34 UTC (rev 111144)
+++ trunk/Source/WebCore/ChangeLog 2012-03-19 01:07:16 UTC (rev 111145)
@@ -1,5 +1,38 @@
2012-03-18 Dana Jansens <[email protected]>
+ [chromium] Don't occlude on main-thread behind layers/surfaces with impl-thread animations
+ https://bugs.webkit.org/show_bug.cgi?id=81354
+
+ Reviewed by Adrienne Walker.
+
+ Layers and surfaces can have an animating opacity or translation on the
+ impl thread. In this case, the main thread does not know their actual
+ values, and treats these values as "unknowns". This means we can't use
+ them for marking areas of the screen as occluded, and we can't consider
+ a part of a layer occluded in a space that we can not reliably transform
+ to.
+
+ Unit test: CCOcclusionTrackerTestAnimationOpacity0OnMainThread
+ CCOcclusionTrackerTestAnimationOpacity1OnMainThread
+ CCOcclusionTrackerTestAnimationTranslateOnMainThread
+
+ * platform/graphics/chromium/cc/CCOcclusionTracker.cpp:
+ (WebCore::layerOpacityKnown):
+ (WebCore::layerTransformsToTargetKnown):
+ (WebCore::layerTransformsToScreenKnown):
+ (WebCore):
+ (WebCore::surfaceOpacityUnknown):
+ (WebCore::surfaceTransformsToTargetUnknown):
+ (WebCore::surfaceTransformsToScreenUnknown):
+ (WebCore::::finishedTargetRenderSurface):
+ (WebCore::contentToScreenSpaceTransform):
+ (WebCore::contentToTargetSurfaceTransform):
+ (WebCore::::markOccludedBehindLayer):
+ (WebCore::::occluded):
+ (WebCore::::unoccludedContentRect):
+
+2012-03-18 Dana Jansens <[email protected]>
+
[chromium] Animating opacity is not opaque and should create a render surface on main thread
https://bugs.webkit.org/show_bug.cgi?id=81401
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp (111144 => 111145)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp 2012-03-19 00:58:34 UTC (rev 111144)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp 2012-03-19 01:07:16 UTC (rev 111145)
@@ -73,6 +73,20 @@
}
}
+static inline bool layerOpacityKnown(const LayerChromium* layer) { return !layer->drawOpacityIsAnimating(); }
+static inline bool layerOpacityKnown(const CCLayerImpl*) { return true; }
+static inline bool layerTransformsToTargetKnown(const LayerChromium* layer) { return !layer->drawTransformIsAnimating(); }
+static inline bool layerTransformsToTargetKnown(const CCLayerImpl*) { return true; }
+static inline bool layerTransformsToScreenKnown(const LayerChromium* layer) { return !layer->screenSpaceTransformIsAnimating(); }
+static inline bool layerTransformsToScreenKnown(const CCLayerImpl*) { return true; }
+
+static inline bool surfaceOpacityKnown(const RenderSurfaceChromium* surface) { return !surface->drawOpacityIsAnimating(); }
+static inline bool surfaceOpacityKnown(const CCRenderSurface*) { return true; }
+static inline bool surfaceTransformsToTargetKnown(const RenderSurfaceChromium* surface) { return !surface->targetSurfaceTransformsAreAnimating(); }
+static inline bool surfaceTransformsToTargetKnown(const CCRenderSurface*) { return true; }
+static inline bool surfaceTransformsToScreenKnown(const RenderSurfaceChromium* surface) { return !surface->screenSpaceTransformsAreAnimating(); }
+static inline bool surfaceTransformsToScreenKnown(const CCRenderSurface*) { return true; }
+
template<typename LayerType, typename RenderSurfaceType>
void CCOcclusionTrackerBase<LayerType, RenderSurfaceType>::finishedTargetRenderSurface(const LayerType* owningLayer, const RenderSurfaceType* finishedTarget)
{
@@ -82,9 +96,15 @@
// Make sure we know about the target surface.
enterTargetRenderSurface(finishedTarget);
- if (owningLayer->maskLayer() || finishedTarget->drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) {
+ // If the occlusion within the surface can not be applied to things outside of the surface's subtree, then clear the occlusion here so it won't be used.
+ if (owningLayer->maskLayer() || !surfaceOpacityKnown(finishedTarget) || finishedTarget->drawOpacity() < 1 || finishedTarget->filters().hasFilterThatAffectsOpacity()) {
m_stack.last().occlusionInScreen = Region();
m_stack.last().occlusionInTarget = Region();
+ } else {
+ if (!surfaceTransformsToTargetKnown(finishedTarget))
+ m_stack.last().occlusionInTarget = Region();
+ if (!surfaceTransformsToScreenKnown(finishedTarget))
+ m_stack.last().occlusionInScreen = Region();
}
}
@@ -141,6 +161,7 @@
template<typename LayerType>
static inline TransformationMatrix contentToScreenSpaceTransform(const LayerType* layer)
{
+ ASSERT(layerTransformsToScreenKnown(layer));
IntSize boundsInLayerSpace = layer->bounds();
IntSize boundsInContentSpace = layer->contentBounds();
@@ -159,6 +180,7 @@
template<typename LayerType>
static inline TransformationMatrix contentToTargetSurfaceTransform(const LayerType* layer)
{
+ ASSERT(layerTransformsToTargetKnown(layer));
IntSize boundsInLayerSpace = layer->bounds();
IntSize boundsInContentSpace = layer->contentBounds();
@@ -209,15 +231,14 @@
if (m_stack.isEmpty())
return;
- if (layer->drawOpacity() != 1)
+ if (!layerOpacityKnown(layer) || layer->drawOpacity() < 1)
return;
- TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
- TransformationMatrix contentToTargetSurface = contentToTargetSurfaceTransform<LayerType>(layer);
-
// 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));
+ if (layerTransformsToScreenKnown(layer))
+ m_stack.last().occlusionInScreen.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToScreenSpaceTransform<LayerType>(layer), m_usePaintTracking));
+ if (layerTransformsToTargetKnown(layer))
+ m_stack.last().occlusionInTarget.unite(computeOcclusionBehindLayer<LayerType>(layer, contentToTargetSurfaceTransform<LayerType>(layer), m_usePaintTracking));
}
static inline bool testContentRectOccluded(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion)
@@ -239,9 +260,9 @@
ASSERT(layer->targetRenderSurface() == m_stack.last().surface);
- if (testContentRectOccluded(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen))
+ if (layerTransformsToScreenKnown(layer) && testContentRectOccluded(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen))
return true;
- if (testContentRectOccluded(contentRect, contentToTargetSurfaceTransform<LayerType>(layer), layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget))
+ if (layerTransformsToTargetKnown(layer) && testContentRectOccluded(contentRect, contentToTargetSurfaceTransform<LayerType>(layer), layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget))
return true;
return false;
}
@@ -307,14 +328,17 @@
// We want to return a rect that contains all the visible parts of |contentRect| in both screen space and in the target surface.
// So we find the visible parts of |contentRect| in each space, and take the intersection.
- TransformationMatrix contentToScreenSpace = contentToScreenSpaceTransform<LayerType>(layer);
- TransformationMatrix contentToTargetSurface = contentToTargetSurfaceTransform<LayerType>(layer);
+ IntRect unoccludedInScreen = contentRect;
+ if (layerTransformsToScreenKnown(layer))
+ unoccludedInScreen = computeUnoccludedContentRect(contentRect, contentToScreenSpaceTransform<LayerType>(layer), m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen);
- IntRect unoccludedInScreen = computeUnoccludedContentRect(contentRect, contentToScreenSpace, m_scissorRectInScreenSpace, m_stack.last().occlusionInScreen);
if (unoccludedInScreen.isEmpty())
- return IntRect();
- IntRect unoccludedInTarget = computeUnoccludedContentRect(contentRect, contentToTargetSurface, layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget);
+ return unoccludedInScreen;
+ IntRect unoccludedInTarget = contentRect;
+ if (layerTransformsToTargetKnown(layer))
+ unoccludedInTarget = computeUnoccludedContentRect(contentRect, contentToTargetSurfaceTransform<LayerType>(layer), layerScissorRectInTargetSurface(layer), m_stack.last().occlusionInTarget);
+
return intersection(unoccludedInScreen, unoccludedInTarget);
}
Modified: trunk/Source/WebKit/chromium/ChangeLog (111144 => 111145)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-03-19 00:58:34 UTC (rev 111144)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-03-19 01:07:16 UTC (rev 111145)
@@ -1,5 +1,23 @@
2012-03-18 Dana Jansens <[email protected]>
+ [chromium] Don't occlude on main-thread behind layers/surfaces with impl-thread animations
+ https://bugs.webkit.org/show_bug.cgi?id=81354
+
+ Reviewed by Adrienne Walker.
+
+ * tests/CCOcclusionTrackerTest.cpp:
+ (WebCore):
+ (WebCore::addOpacityAnimationToLayer):
+ (WebCore::addTransformAnimationToLayer):
+ (CCOcclusionTrackerTestAnimationOpacity1OnMainThread):
+ (WebCore::CCOcclusionTrackerTestAnimationOpacity1OnMainThread::runMyTest):
+ (CCOcclusionTrackerTestAnimationOpacity0OnMainThread):
+ (WebCore::CCOcclusionTrackerTestAnimationOpacity0OnMainThread::runMyTest):
+ (CCOcclusionTrackerTestAnimationTranslateOnMainThread):
+ (WebCore::CCOcclusionTrackerTestAnimationTranslateOnMainThread::runMyTest):
+
+2012-03-18 Dana Jansens <[email protected]>
+
[chromium] Animating opacity is not opaque and should create a render surface on main thread
https://bugs.webkit.org/show_bug.cgi?id=81401
Modified: trunk/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp (111144 => 111145)
--- trunk/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp 2012-03-19 00:58:34 UTC (rev 111144)
+++ trunk/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp 2012-03-19 01:07:16 UTC (rev 111145)
@@ -30,6 +30,8 @@
#include "LayerChromium.h"
#include "Region.h"
#include "TransformationMatrix.h"
+#include "TranslateTransformOperation.h"
+#include "cc/CCLayerAnimationController.h"
#include "cc/CCLayerImpl.h"
#include "cc/CCLayerTreeHostCommon.h"
#include "cc/CCSingleThreadProxy.h"
@@ -1674,4 +1676,206 @@
MAIN_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera);
+template<typename LayerType>
+static int addOpacityAnimationToLayer(LayerType* layer, float startValue, float endValue, double duration)
+{
+ static int id = 0;
+ WebCore::KeyframeValueList values(AnimatedPropertyOpacity);
+ values.insert(new FloatAnimationValue(0, startValue));
+ values.insert(new FloatAnimationValue(duration, endValue));
+
+ RefPtr<Animation> animation = Animation::create();
+ animation->setDuration(duration);
+
+ IntSize boxSize;
+ layer->layerAnimationController()->addAnimation(values, boxSize, animation.get(), id, 0, 0);
+ return id++;
+}
+
+template<typename LayerType>
+static int addTransformAnimationToLayer(LayerType* layer, double duration)
+{
+ static int id = 0;
+ WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
+
+ TransformOperations operations1;
+ operations1.operations().append(TranslateTransformOperation::create(Length(2, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+ values.insert(new TransformAnimationValue(0, &operations1));
+
+ RefPtr<Animation> animation = Animation::create();
+ animation->setDuration(duration);
+
+ IntSize boxSize;
+ layer->layerAnimationController()->addAnimation(values, boxSize, animation.get(), id, 0, 0);
+ return id++;
+}
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestAnimationOpacity1OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
+ typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
+
+ addOpacityAnimationToLayer(layer, 0, 1, 10);
+ addOpacityAnimationToLayer(surface, 0, 1, 10);
+ this->calcDrawEtc(parent);
+
+ EXPECT_TRUE(layer->drawOpacityIsAnimating());
+ EXPECT_FALSE(surface->drawOpacityIsAnimating());
+ EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
+
+ TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ occlusion.enterTargetRenderSurface(surface->renderSurface());
+ occlusion.markOccludedBehindLayer(surfaceChild2);
+ EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ occlusion.markOccludedBehindLayer(surfaceChild);
+ EXPECT_EQ_RECT(IntRect(200, 0, 100, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ occlusion.markOccludedBehindLayer(surface);
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
+ occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ // Occlusion is lost when leaving the animating surface.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+
+ occlusion.markOccludedBehindLayer(layer);
+ // Occlusion is not added for the animating layer.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
+
+MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity1OnMainThread);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestAnimationOpacity0OnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
+ typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
+
+ addOpacityAnimationToLayer(layer, 1, 0, 10);
+ addOpacityAnimationToLayer(surface, 1, 0, 10);
+ this->calcDrawEtc(parent);
+
+ EXPECT_TRUE(layer->drawOpacityIsAnimating());
+ EXPECT_FALSE(surface->drawOpacityIsAnimating());
+ EXPECT_TRUE(surface->renderSurface()->drawOpacityIsAnimating());
+
+ TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ occlusion.enterTargetRenderSurface(surface->renderSurface());
+ occlusion.markOccludedBehindLayer(surfaceChild2);
+ EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ occlusion.markOccludedBehindLayer(surfaceChild);
+ EXPECT_EQ_RECT(IntRect(200, 0, 100, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ occlusion.markOccludedBehindLayer(surface);
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
+ occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ // Occlusion is lost when leaving the animating surface.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+
+ occlusion.markOccludedBehindLayer(layer);
+ // Occlusion is not added for the animating layer.
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
+
+MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationOpacity0OnMainThread);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestAnimationTranslateOnMainThread : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+ void runMyTest()
+ {
+ typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+ typename Types::ContentLayerType* layer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300), true);
+ typename Types::ContentLayerType* surfaceChild = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(200, 300), true);
+ typename Types::ContentLayerType* surfaceChild2 = this->createDrawingLayer(surface, this->identityMatrix, FloatPoint(0, 0), IntSize(100, 300), true);
+ typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(50, 300), true);
+
+ addTransformAnimationToLayer(layer, 10);
+ addTransformAnimationToLayer(surface, 10);
+ addTransformAnimationToLayer(surfaceChild, 10);
+ this->calcDrawEtc(parent);
+
+ EXPECT_TRUE(layer->drawTransformIsAnimating());
+ EXPECT_TRUE(layer->screenSpaceTransformIsAnimating());
+ EXPECT_TRUE(surface->renderSurface()->targetSurfaceTransformsAreAnimating());
+ EXPECT_TRUE(surface->renderSurface()->screenSpaceTransformsAreAnimating());
+ // The surface owning layer doesn't animate against its own surface.
+ EXPECT_FALSE(surface->drawTransformIsAnimating());
+ EXPECT_TRUE(surface->screenSpaceTransformIsAnimating());
+ EXPECT_TRUE(surfaceChild->drawTransformIsAnimating());
+ EXPECT_TRUE(surfaceChild->screenSpaceTransformIsAnimating());
+
+ TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+
+ occlusion.enterTargetRenderSurface(surface2->renderSurface());
+ occlusion.markOccludedBehindLayer(surface2);
+ occlusion.finishedTargetRenderSurface(surface2, surface2->renderSurface());
+ occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+
+ occlusion.enterTargetRenderSurface(surface->renderSurface());
+
+ // The layer is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
+ // It also means that things occluding in screen space (e.g. surface2) cannot occlude this layer.
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 300), occlusion.unoccludedContentRect(surfaceChild2, IntRect(0, 0, 100, 300)));
+ EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
+
+ occlusion.markOccludedBehindLayer(surfaceChild2);
+ EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 100, 300)));
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+
+ // The surface child is occluded by the surfaceChild2, but is moving relative its target and the screen, so it
+ // can't be occluded.
+ EXPECT_EQ_RECT(IntRect(0, 0, 200, 300), occlusion.unoccludedContentRect(surfaceChild, IntRect(0, 0, 200, 300)));
+ EXPECT_FALSE(occlusion.occluded(surfaceChild, IntRect(0, 0, 50, 300)));
+
+ occlusion.markOccludedBehindLayer(surfaceChild);
+ // The layer is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 100, 300), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(100, 0, 200, 300), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+
+ occlusion.markOccludedBehindLayer(surface);
+ // The layer is moving in screen space but not relative to its target, so occlusion should happen in its target space only.
+ EXPECT_EQ_RECT(IntRect(0, 0, 50, 300), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 300, 300), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
+ EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), occlusion.unoccludedContentRect(surface, IntRect(0, 0, 300, 300)));
+
+ occlusion.finishedTargetRenderSurface(surface, surface->renderSurface());
+ occlusion.leaveToTargetRenderSurface(parent->renderSurface());
+ // The surface is moving in the screen and in its target, so all occlusion is lost when leaving it.
+ EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+
+ occlusion.markOccludedBehindLayer(layer);
+ // The layer is animating in the screen and in its target, so no occlusion is added.
+ EXPECT_EQ_RECT(IntRect(50, 0, 250, 300), occlusion.unoccludedContentRect(parent, IntRect(0, 0, 300, 300)));
+ }
+};
+
+MAIN_THREAD_TEST(CCOcclusionTrackerTestAnimationTranslateOnMainThread);
+
} // namespace
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
