[chromium] Compute occlusion during paint loop

https://bugs.webkit.org/show_bug.cgi?id=76858

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

Source/WebCore:

New unit tests in TiledLayerChromiumTest.cpp, CCLayerTreeHostCommonTest.cpp, CCLayerTreeHostTest.cpp

* platform/graphics/FloatRect.cpp:
(WebCore::enclosedIntRect):
(WebCore):
* platform/graphics/FloatRect.h:
(WebCore):
* platform/graphics/chromium/Canvas2DLayerChromium.cpp:
(WebCore::Canvas2DLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/Canvas2DLayerChromium.h:
(Canvas2DLayerChromium):
* platform/graphics/chromium/ContentLayerChromium.cpp:
(WebCore::ContentLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/ContentLayerChromium.h:
(ContentLayerChromium):
* platform/graphics/chromium/ImageLayerChromium.cpp:
(WebCore::ImageLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/ImageLayerChromium.h:
(ImageLayerChromium):
* platform/graphics/chromium/LayerChromium.cpp:
(WebCore::LayerChromium::contentToScreenSpaceTransform):
(WebCore):
(WebCore::LayerChromium::addSelfToOccludedScreenSpace):
(WebCore::LayerChromium::isPaintedAxisAlignedInScreen):
* platform/graphics/chromium/LayerChromium.h:
(WebCore):
(WebCore::LayerChromium::paintContentsIfDirty):
(LayerChromium):
* platform/graphics/chromium/RenderSurfaceChromium.h:
(RenderSurfaceChromium):
* platform/graphics/chromium/TiledLayerChromium.cpp:
(WebCore::TiledLayerChromium::addSelfToOccludedScreenSpace):
* platform/graphics/chromium/TiledLayerChromium.h:
(WebCore):
():
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::paintContentsIfDirty):
(WebCore::CCLayerTreeHost::paintMaskAndReplicaForRenderSurface):
(RenderSurfaceRegion):
(WebCore):
(WebCore::pushTargetRenderSurfaceRegion):
(WebCore::popAndPushTargetRenderSurfaceRegion):
(WebCore::CCLayerTreeHost::paintLayerContents):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore):
():
* platform/graphics/chromium/cc/CCQuadCuller.cpp:

Source/WebKit/chromium:

* tests/CCLayerTreeHostCommonTest.cpp:
(WebCore::TEST):
(WebCore):
* tests/CCLayerTreeHostTest.cpp:
(WTF::ContentLayerChromiumWithUpdateTracking::paintContentsIfDirty):
(WTF):
(TestLayerChromium):
(WTF::TestLayerChromium::create):
(WTF::TestLayerChromium::paintContentsIfDirty):
(WTF::TestLayerChromium::drawsContent):
(WTF::TestLayerChromium::occludedScreenSpace):
(WTF::TestLayerChromium::clearOccludedScreenSpace):
(WTF::TestLayerChromium::TestLayerChromium):
(WTF::setLayerPropertiesForTesting):
(CCLayerTreeHostTestLayerOcclusion):
(WTF::CCLayerTreeHostTestLayerOcclusion::CCLayerTreeHostTestLayerOcclusion):
(WTF::CCLayerTreeHostTestLayerOcclusion::beginTest):
(WTF::CCLayerTreeHostTestLayerOcclusion::afterTest):
* tests/Canvas2DLayerChromiumTest.cpp:
(WebCore::Canvas2DLayerChromiumTest::fullLifecycleTest):
* tests/TiledLayerChromiumTest.cpp:
(WTF::FakeLayerTextureUpdater::setOpaquePaintRect):
(FakeLayerTextureUpdater):
(WTF::FakeTiledLayerChromium::paintContentsIfDirty):
(WTF::FakeLayerTextureUpdater::prepareToUpdate):
(WTF::TEST):
(WTF):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106383 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 46cb5141
2012-01-31 Dana Jansens <danakj@chromium.org>
[chromium] Compute occlusion during paint loop
https://bugs.webkit.org/show_bug.cgi?id=76858
Reviewed by James Robinson.
New unit tests in TiledLayerChromiumTest.cpp, CCLayerTreeHostCommonTest.cpp, CCLayerTreeHostTest.cpp
* platform/graphics/FloatRect.cpp:
(WebCore::enclosedIntRect):
(WebCore):
* platform/graphics/FloatRect.h:
(WebCore):
* platform/graphics/chromium/Canvas2DLayerChromium.cpp:
(WebCore::Canvas2DLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/Canvas2DLayerChromium.h:
(Canvas2DLayerChromium):
* platform/graphics/chromium/ContentLayerChromium.cpp:
(WebCore::ContentLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/ContentLayerChromium.h:
(ContentLayerChromium):
* platform/graphics/chromium/ImageLayerChromium.cpp:
(WebCore::ImageLayerChromium::paintContentsIfDirty):
* platform/graphics/chromium/ImageLayerChromium.h:
(ImageLayerChromium):
* platform/graphics/chromium/LayerChromium.cpp:
(WebCore::LayerChromium::contentToScreenSpaceTransform):
(WebCore):
(WebCore::LayerChromium::addSelfToOccludedScreenSpace):
(WebCore::LayerChromium::isPaintedAxisAlignedInScreen):
* platform/graphics/chromium/LayerChromium.h:
(WebCore):
(WebCore::LayerChromium::paintContentsIfDirty):
(LayerChromium):
* platform/graphics/chromium/RenderSurfaceChromium.h:
(RenderSurfaceChromium):
* platform/graphics/chromium/TiledLayerChromium.cpp:
(WebCore::TiledLayerChromium::addSelfToOccludedScreenSpace):
* platform/graphics/chromium/TiledLayerChromium.h:
(WebCore):
():
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::paintContentsIfDirty):
(WebCore::CCLayerTreeHost::paintMaskAndReplicaForRenderSurface):
(RenderSurfaceRegion):
(WebCore):
(WebCore::pushTargetRenderSurfaceRegion):
(WebCore::popAndPushTargetRenderSurfaceRegion):
(WebCore::CCLayerTreeHost::paintLayerContents):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore):
():
* platform/graphics/chromium/cc/CCQuadCuller.cpp:
2012-01-31 John Bates <jbates@google.com>
[Chromium] Add chromium-style tracing support
......@@ -218,6 +218,19 @@ IntRect enclosingIntRect(const FloatRect& rect)
clampToInteger(width), clampToInteger(height));
}
IntRect enclosedIntRect(const FloatRect& rect)
{
int x = clampToInteger(ceilf(rect.x()));
int y = clampToInteger(ceilf(rect.y()));
float maxX = clampToInteger(floorf(rect.maxX()));
float maxY = clampToInteger(floorf(rect.maxY()));
// A rect of width 0 should not become a rect of width -1 due to ceil/floor.
int width = max(clampToInteger(maxX - x), 0);
int height = max(clampToInteger(maxY - y), 0);
return IntRect(x, y, width, height);
}
FloatRect mapRect(const FloatRect& r, const FloatRect& srcRect, const FloatRect& destRect)
{
if (srcRect.width() == 0 || srcRect.height() == 0)
......
......@@ -270,6 +270,9 @@ inline bool operator!=(const FloatRect& a, const FloatRect& b)
IntRect enclosingIntRect(const FloatRect&);
// Returns a valid IntRect contained within the given FloatRect.
IntRect enclosedIntRect(const FloatRect&);
// Map rect r from srcRect to an equivalent rect in destRect.
FloatRect mapRect(const FloatRect& r, const FloatRect& srcRect, const FloatRect& destRect);
......
......@@ -91,7 +91,7 @@ bool Canvas2DLayerChromium::drawsContent() const
&& m_context && (m_context->getExtensions()->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR);
}
void Canvas2DLayerChromium::paintContentsIfDirty()
void Canvas2DLayerChromium::paintContentsIfDirty(const Region& /* occludedScreenSpace */)
{
if (!drawsContent())
return;
......
......@@ -40,6 +40,7 @@
namespace WebCore {
class GraphicsContext3D;
class Region;
// A layer containing an accelerated 2d canvas
class Canvas2DLayerChromium : public CanvasLayerChromium {
......@@ -52,7 +53,7 @@ public:
virtual void contentChanged();
virtual bool drawsContent() const;
virtual void paintContentsIfDirty();
virtual void paintContentsIfDirty(const Region& occludedScreenSpace);
virtual void setLayerTreeHost(CCLayerTreeHost*);
virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
......
......@@ -93,7 +93,7 @@ bool ContentLayerChromium::drawsContent() const
return TiledLayerChromium::drawsContent() && m_delegate;
}
void ContentLayerChromium::paintContentsIfDirty()
void ContentLayerChromium::paintContentsIfDirty(const Region& /* occludedScreenSpace */)
{
updateTileSizeAndTilingOption();
......
......@@ -41,6 +41,7 @@ namespace WebCore {
class LayerTilerChromium;
class LayerTextureUpdater;
class Region;
class ContentLayerDelegate {
public:
......@@ -58,7 +59,7 @@ public:
void clearDelegate() { m_delegate = 0; }
virtual bool drawsContent() const;
virtual void paintContentsIfDirty();
virtual void paintContentsIfDirty(const Region& occludedScreenSpace);
virtual void idlePaintContentsIfDirty();
virtual void setOpaque(bool);
......
......@@ -158,7 +158,7 @@ void ImageLayerChromium::setContents(Image* contents)
setNeedsDisplay();
}
void ImageLayerChromium::paintContentsIfDirty()
void ImageLayerChromium::paintContentsIfDirty(const Region& /* occludedScreenSpace */)
{
if (m_needsDisplay) {
m_textureUpdater->updateFromImage(m_contents->nativeImageForCurrentFrame());
......
......@@ -45,6 +45,7 @@ namespace WebCore {
class Image;
class ImageLayerTextureUpdater;
class Region;
// A Layer that contains only an Image element.
class ImageLayerChromium : public TiledLayerChromium {
......@@ -53,7 +54,7 @@ public:
virtual ~ImageLayerChromium();
virtual bool drawsContent() const;
virtual void paintContentsIfDirty();
virtual void paintContentsIfDirty(const Region& occludedScreenSpace);
virtual bool needsContentsScale() const;
void setContents(Image* image);
......
......@@ -39,6 +39,7 @@
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
#endif
#include "Region.h"
#include "RenderLayerBacking.h"
#include "TextStream.h"
#include "skia/ext/platform_canvas.h"
......@@ -469,6 +470,35 @@ void LayerChromium::setContentsScale(float contentsScale)
setNeedsDisplay();
}
TransformationMatrix LayerChromium::contentToScreenSpaceTransform() const
{
IntSize boundsInLayerSpace = bounds();
IntSize boundsInContentSpace = contentBounds();
TransformationMatrix transform = screenSpaceTransform();
// Scale from content space to layer space
transform.scaleNonUniform(boundsInLayerSpace.width() / static_cast<double>(boundsInContentSpace.width()),
boundsInLayerSpace.height() / static_cast<double>(boundsInContentSpace.height()));
return transform;
}
void LayerChromium::addSelfToOccludedScreenSpace(Region& occludedScreenSpace)
{
if (!opaque() || drawOpacity() != 1 || !isPaintedAxisAlignedInScreen())
return;
FloatRect targetRect = contentToScreenSpaceTransform().mapRect(FloatRect(visibleLayerRect()));
occludedScreenSpace.unite(enclosedIntRect(targetRect));
}
bool LayerChromium::isPaintedAxisAlignedInScreen() const
{
FloatQuad quad = contentToScreenSpaceTransform().mapQuad(FloatQuad(visibleLayerRect()));
return quad.isRectilinear();
}
void LayerChromium::createRenderSurface()
{
ASSERT(!m_renderSurface);
......
......@@ -55,6 +55,7 @@ class CCLayerImpl;
class CCLayerTreeHost;
class CCTextureUpdater;
class GraphicsContext3D;
class Region;
// Base class for composited layers. Special layer types are derived from
// this class.
......@@ -153,7 +154,7 @@ public:
// These methods typically need to be overwritten by derived classes.
virtual bool drawsContent() const { return m_isDrawable; }
virtual void paintContentsIfDirty() { }
virtual void paintContentsIfDirty(const Region& /* occludedScreenSpace */) { }
virtual void idlePaintContentsIfDirty() { }
virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&) { }
virtual void setIsMask(bool) { }
......@@ -182,8 +183,10 @@ public:
void setClipRect(const IntRect& clipRect) { m_clipRect = clipRect; }
RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; }
void setTargetRenderSurface(RenderSurfaceChromium* surface) { m_targetRenderSurface = surface; }
// This moves from layer space, with origin in the center to target space with origin in the top left
const TransformationMatrix& drawTransform() const { return m_drawTransform; }
void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; }
// This moves from layer space, with origin the top left to screen space with origin in the top left
const TransformationMatrix& screenSpaceTransform() const { return m_screenSpaceTransform; }
void setScreenSpaceTransform(const TransformationMatrix& matrix) { m_screenSpaceTransform = matrix; }
const IntRect& drawableContentRect() const { return m_drawableContentRect; }
......@@ -191,6 +194,11 @@ public:
float contentsScale() const { return m_contentsScale; }
void setContentsScale(float);
TransformationMatrix contentToScreenSpaceTransform() const;
// Adds any opaque visible pixels to the occluded region.
virtual void addSelfToOccludedScreenSpace(Region& occludedScreenSpace);
// Returns true if any of the layer's descendants has content to draw.
bool descendantDrawsContent();
virtual void contentChanged() { }
......@@ -211,6 +219,8 @@ protected:
// hold context-dependent resources such as textures.
virtual void cleanupResources();
bool isPaintedAxisAlignedInScreen() const;
void setNeedsCommit();
// This flag is set when layer need repainting/updating.
......
......@@ -63,6 +63,8 @@ public:
float drawOpacity() const { return m_drawOpacity; }
void setDrawOpacity(float drawOpacity) { m_drawOpacity = drawOpacity; }
// This goes from content space with the origin in the center of the rect being transformed to the target space with the origin in the top left of the
// rect being transformed. Position the rect so that the origin is in the center of it before applying this transform.
const TransformationMatrix& drawTransform() const { return m_drawTransform; }
void setDrawTransform(const TransformationMatrix& drawTransform) { m_drawTransform = drawTransform; }
......
......@@ -488,6 +488,35 @@ void TiledLayerChromium::reserveTextures()
}
}
void TiledLayerChromium::addSelfToOccludedScreenSpace(Region& occludedScreenSpace)
{
if (m_skipsDraw || drawOpacity() != 1 || !isPaintedAxisAlignedInScreen())
return;
if (opaque()) {
LayerChromium::addSelfToOccludedScreenSpace(occludedScreenSpace);
return;
}
IntRect visibleRect = visibleLayerRect();
TransformationMatrix contentTransform = contentToScreenSpaceTransform();
// FIXME: Create/Use a FloatRegion for the occludedScreenSpace, instead of a Region based on ints, to avoid this step and get better accuracy between layers in target space.
Region tileRegion;
int left, top, right, bottom;
m_tiler->layerRectToTileIndices(visibleLayerRect(), left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
UpdatableTile* tile = tileAt(i, j);
if (tile) {
IntRect visibleTileOpaqueRect = intersection(visibleRect, tile->m_opaqueRect);
FloatRect screenRect = contentTransform.mapRect(FloatRect(visibleTileOpaqueRect));
occludedScreenSpace.unite(enclosedIntRect(screenRect));
}
}
}
}
void TiledLayerChromium::prepareToUpdate(const IntRect& layerRect)
{
m_skipsDraw = false;
......
......@@ -35,6 +35,7 @@
namespace WebCore {
class LayerTextureUpdater;
class Region;
class UpdatableTile;
class TiledLayerChromium : public LayerChromium {
......@@ -63,6 +64,8 @@ public:
virtual void reserveTextures();
virtual void addSelfToOccludedScreenSpace(Region& occludedScreenSpace);
protected:
TiledLayerChromium();
......
......@@ -29,6 +29,7 @@
#include "LayerChromium.h"
#include "LayerPainterChromium.h"
#include "LayerRendererChromium.h"
#include "Region.h"
#include "TraceEvent.h"
#include "TreeSynchronizer.h"
#include "cc/CCLayerIterator.h"
......@@ -413,12 +414,12 @@ void CCLayerTreeHost::reserveTextures()
}
// static
void CCLayerTreeHost::paintContentsIfDirty(LayerChromium* layer, PaintType paintType)
void CCLayerTreeHost::paintContentsIfDirty(LayerChromium* layer, PaintType paintType, const Region& occludedScreenSpace)
{
ASSERT(layer);
ASSERT(PaintVisible == paintType || PaintIdle == paintType);
if (PaintVisible == paintType)
layer->paintContentsIfDirty();
layer->paintContentsIfDirty(occludedScreenSpace);
else
layer->idlePaintContentsIfDirty();
}
......@@ -429,35 +430,93 @@ void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderS
// in code, we already know that at least something will be drawn into this render surface, so the
// mask and replica should be painted.
// FIXME: If the surface has a replica, it should be painted with occlusion that excludes the current target surface subtree.
Region noOcclusion;
if (renderSurfaceLayer->maskLayer()) {
renderSurfaceLayer->maskLayer()->setVisibleLayerRect(IntRect(IntPoint(), renderSurfaceLayer->contentBounds()));
paintContentsIfDirty(renderSurfaceLayer->maskLayer(), paintType);
paintContentsIfDirty(renderSurfaceLayer->maskLayer(), paintType, noOcclusion);
}
LayerChromium* replicaLayer = renderSurfaceLayer->replicaLayer();
if (replicaLayer) {
paintContentsIfDirty(replicaLayer, paintType);
paintContentsIfDirty(replicaLayer, paintType, noOcclusion);
if (replicaLayer->maskLayer()) {
replicaLayer->maskLayer()->setVisibleLayerRect(IntRect(IntPoint(), replicaLayer->maskLayer()->contentBounds()));
paintContentsIfDirty(replicaLayer->maskLayer(), paintType);
paintContentsIfDirty(replicaLayer->maskLayer(), paintType, noOcclusion);
}
}
}
struct RenderSurfaceRegion {
RenderSurfaceChromium* surface;
Region occludedInScreen;
};
// Add the surface to the top of the stack and copy the occlusion from the old top of the stack to the new.
static void enterTargetRenderSurface(Vector<RenderSurfaceRegion>& stack, RenderSurfaceChromium* newTarget)
{
if (stack.isEmpty()) {
stack.append(RenderSurfaceRegion());
stack.last().surface = newTarget;
} else if (stack.last().surface != newTarget) {
const RenderSurfaceRegion& previous = stack.last();
stack.append(RenderSurfaceRegion());
stack.last().surface = newTarget;
stack.last().occludedInScreen = previous.occludedInScreen;
}
}
// Pop the top of the stack off, push on the new surface, and merge the old top's occlusion into the new top surface.
static void leaveTargetRenderSurface(Vector<RenderSurfaceRegion>& stack, RenderSurfaceChromium* newTarget)
{
int lastIndex = stack.size() - 1;
bool surfaceWillBeAtTopAfterPop = stack.size() > 1 && stack[lastIndex - 1].surface == newTarget;
if (surfaceWillBeAtTopAfterPop) {
// Merge the top of the stack down.
stack[lastIndex - 1].occludedInScreen.unite(stack[lastIndex].occludedInScreen);
stack.removeLast();
} else {
// Replace the top of the stack with the new pushed surface. Copy the occluded region to the top.
stack.last().surface = newTarget;
}
}
void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList, PaintType paintType)
{
// Use FrontToBack to allow for testing occlusion and performing culling during the tree walk.
typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType;
// The stack holds occluded regions for subtrees in the RenderSurface-Layer tree, so that when we leave a subtree we may
// apply a mask to it, but not to the parts outside the subtree.
// - The first time we see a new subtree under a target, we add that target to the top of the stack. This can happen as a layer representing itself, or as a target surface.
// - When we visit a target surface, we apply its mask to its subtree, which is at the top of the stack.
// - When we visit a layer representing itself, we add its occlusion to the current subtree, which is at the top of the stack.
// - When we visit a layer representing a contributing surface, the current target will never be the top of the stack since we just came from the contributing surface.
// We merge the occlusion at the top of the stack with the new current subtree. This new target is pushed onto the stack if not already there.
Vector<RenderSurfaceRegion> targetSurfaceStack;
CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList);
for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) {
if (it.representsTargetRenderSurface()) {
ASSERT(it->renderSurface()->drawOpacity());
enterTargetRenderSurface(targetSurfaceStack, it->renderSurface());
paintMaskAndReplicaForRenderSurface(*it, paintType);
// FIXME: add the replica layer to the current occlusion
if (it->maskLayer() || it->renderSurface()->drawOpacity() < 1)
targetSurfaceStack.last().occludedInScreen = Region();
} else if (it.representsItself()) {
ASSERT(!it->bounds().isEmpty());
paintContentsIfDirty(*it, paintType);
enterTargetRenderSurface(targetSurfaceStack, it->targetRenderSurface());
paintContentsIfDirty(*it, paintType, targetSurfaceStack.last().occludedInScreen);
it->addSelfToOccludedScreenSpace(targetSurfaceStack.last().occludedInScreen);
} else {
leaveTargetRenderSurface(targetSurfaceStack, it.targetRenderSurfaceLayer()->renderSurface());
}
}
}
......
......@@ -48,6 +48,7 @@ class CCLayerTreeHostImpl;
class CCTextureUpdater;
class GraphicsContext3D;
class LayerPainterChromium;
class Region;
class TextureAllocator;
class TextureManager;
......@@ -205,7 +206,7 @@ private:
typedef Vector<OwnPtr<ManagedTexture> > TextureList;
enum PaintType { PaintVisible, PaintIdle };
static void paintContentsIfDirty(LayerChromium*, PaintType);
static void paintContentsIfDirty(LayerChromium*, PaintType, const Region& occludedScreenSpace);
void paintLayerContents(const LayerList&, PaintType);
void paintMaskAndReplicaForRenderSurface(LayerChromium*, PaintType);
......
......@@ -75,18 +75,6 @@ static IntRect rectSubtractRegion(const Region& region, const IntRect& rect)
return rect;
}
static IntRect enclosedIntRect(const FloatRect& rect)
{
float x = ceilf(rect.x());
float y = ceilf(rect.y());
// A rect of width 0 should not become a rect of width -1.
float width = max<float>(floorf(rect.maxX()) - x, 0);
float height = max<float>(floorf(rect.maxY()) - y, 0);
return IntRect(clampToInteger(x), clampToInteger(y),
clampToInteger(width), clampToInteger(height));
}
void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList)
{
if (!quadList.size())
......
2012-01-31 Dana Jansens <danakj@chromium.org>
[chromium] Compute occlusion during paint loop
https://bugs.webkit.org/show_bug.cgi?id=76858
Reviewed by James Robinson.
* tests/CCLayerTreeHostCommonTest.cpp:
(WebCore::TEST):
(WebCore):
* tests/CCLayerTreeHostTest.cpp:
(WTF::ContentLayerChromiumWithUpdateTracking::paintContentsIfDirty):
(WTF):
(TestLayerChromium):
(WTF::TestLayerChromium::create):
(WTF::TestLayerChromium::paintContentsIfDirty):
(WTF::TestLayerChromium::drawsContent):
(WTF::TestLayerChromium::occludedScreenSpace):
(WTF::TestLayerChromium::clearOccludedScreenSpace):
(WTF::TestLayerChromium::TestLayerChromium):
(WTF::setLayerPropertiesForTesting):
(CCLayerTreeHostTestLayerOcclusion):
(WTF::CCLayerTreeHostTestLayerOcclusion::CCLayerTreeHostTestLayerOcclusion):
(WTF::CCLayerTreeHostTestLayerOcclusion::beginTest):
(WTF::CCLayerTreeHostTestLayerOcclusion::afterTest):
* tests/Canvas2DLayerChromiumTest.cpp:
(WebCore::Canvas2DLayerChromiumTest::fullLifecycleTest):
* tests/TiledLayerChromiumTest.cpp:
(WTF::FakeLayerTextureUpdater::setOpaquePaintRect):
(FakeLayerTextureUpdater):
(WTF::FakeTiledLayerChromium::paintContentsIfDirty):
(WTF::FakeLayerTextureUpdater::prepareToUpdate):
(WTF::TEST):
(WTF):
2012-01-31 John Bates <jbates@google.com>
[Chromium] Add chromium-style tracing support
......@@ -28,6 +28,7 @@
#include "CCLayerTreeTestCommon.h"
#include "LayerChromium.h"
#include "Region.h"
#include "TransformationMatrix.h"
#include <gmock/gmock.h>
......@@ -35,6 +36,12 @@
using namespace WebCore;
#define EXPECT_EQ_RECT(a, b) \
EXPECT_EQ(a.x(), b.x()); \
EXPECT_EQ(a.y(), b.y()); \
EXPECT_EQ(a.width(), b.width()); \
EXPECT_EQ(a.height(), b.height());
namespace {
void setLayerPropertiesForTesting(LayerChromium* layer, const TransformationMatrix& transform, const TransformationMatrix& sublayerTransform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3D)
......@@ -595,4 +602,174 @@ TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
// - test the other functions in CCLayerTreeHostCommon
//
TEST(CCLayerTreeHostCommonTest, layerAddsSelfToOccludedRegion)
{
// This tests that the right transforms are being used.
Region occluded;
const TransformationMatrix identityMatrix;
RefPtr<LayerChromium> parent = LayerChromium::create();
RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
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), false);
layer->setOpaque(true);
Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
Vector<RefPtr<LayerChromium> > dummyLayerList;
int dummyMaxTextureSize = 512;
// FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
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);
occluded = Region();
layer->addSelfToOccludedScreenSpace(occluded);
EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), occluded.bounds());
EXPECT_EQ(1u, occluded.rects().size());
}
TEST(CCLayerTreeHostCommonTest, layerAddsSelfToOccludedRegionWithRotation)
{
// This tests that the right transforms are being used.
Region occluded;
const TransformationMatrix identityMatrix;
RefPtr<LayerChromium> parent = LayerChromium::create();
RefPtr<LayerChromiumWithForcedDrawsContent> layer = adoptRef(new LayerChromiumWithForcedDrawsContent());
parent->createRenderSurface();
parent->addChild(layer);
TransformationMatrix layerTransform;
layerTransform.translate(250, 250);
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), false);
layer->setOpaque(true);
Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
Vector<RefPtr<LayerChromium> > dummyLayerList;
int dummyMaxTextureSize = 512;
// FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
parent->renderSurface()->setContentRect(IntRect(IntPoint::zero(), parent->bounds()));
parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
renderSurfaceLayerList.append(parent);