summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp')
-rw-r--r--Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp226
1 files changed, 204 insertions, 22 deletions
diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
index 738c88190..d19b036bb 100644
--- a/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
+++ b/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp
@@ -32,6 +32,7 @@
#include "FakeWebGraphicsContext3D.h"
#include "GraphicsContext3DPrivate.h"
#include "LayerRendererChromium.h"
+#include "ManagedTexture.h"
#include "cc/CCIOSurfaceLayerImpl.h"
#include "cc/CCLayerImpl.h"
#include "cc/CCLayerTilingData.h"
@@ -80,7 +81,6 @@ public:
virtual void setNeedsRedrawOnImplThread() OVERRIDE { m_didRequestRedraw = true; }
virtual void setNeedsCommitOnImplThread() OVERRIDE { m_didRequestCommit = true; }
virtual void postAnimationEventsToMainThreadOnImplThread(PassOwnPtr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE { }
- virtual void postSetContentsMemoryAllocationLimitBytesToMainThreadOnImplThread(size_t) OVERRIDE { }
PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHost(bool partialSwap, PassRefPtr<CCGraphicsContext> graphicsContext, PassOwnPtr<CCLayerImpl> rootPtr)
{
@@ -1791,7 +1791,7 @@ TEST_F(CCLayerTreeHostImplTest, partialSwapNoUpdate)
Mock::VerifyAndClearExpectations(&mockContext);
}
-class PartialSwapContext: public FakeWebGraphicsContext3D {
+class PartialSwapContext : public FakeWebGraphicsContext3D {
public:
WebString getString(WGC3Denum name)
{
@@ -2040,12 +2040,17 @@ private:
// FakeWebGraphicsContext3D have an id of 1).
class StrictWebGraphicsContext3D : public FakeWebGraphicsContext3D {
public:
+ StrictWebGraphicsContext3D()
+ : FakeWebGraphicsContext3D()
+ {
+ m_nextTextureId = 7; // Start allocating texture ids larger than any other resource IDs so we can tell if someone's mixing up their resource types.
+ }
+
virtual WebGLId createBuffer() { return 2; }
virtual WebGLId createFramebuffer() { return 3; }
virtual WebGLId createProgram() { return 4; }
virtual WebGLId createRenderbuffer() { return 5; }
virtual WebGLId createShader(WGC3Denum) { return 6; }
- virtual WebGLId createTexture() { return 7; }
virtual void deleteBuffer(WebGLId id)
{
@@ -2077,10 +2082,17 @@ public:
ADD_FAILURE() << "Trying to delete shader id " << id;
}
+ virtual WebGLId createTexture()
+ {
+ unsigned textureId = FakeWebGraphicsContext3D::createTexture();
+ m_allocatedTextureIds.add(textureId);
+ return textureId;
+ }
virtual void deleteTexture(WebGLId id)
{
- if (id != 7)
+ if (!m_allocatedTextureIds.contains(id))
ADD_FAILURE() << "Trying to delete texture id " << id;
+ m_allocatedTextureIds.remove(id);
}
virtual void bindBuffer(WGC3Denum, WebGLId id)
@@ -2115,7 +2127,7 @@ public:
virtual void bindTexture(WGC3Denum, WebGLId id)
{
- if (id != 7 && id)
+ if (id && !m_allocatedTextureIds.contains(id))
ADD_FAILURE() << "Trying to bind texture id " << id;
}
@@ -2123,6 +2135,9 @@ public:
{
return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new StrictWebGraphicsContext3D()), GraphicsContext3D::RenderDirectlyToHostWindow);
}
+
+private:
+ HashSet<unsigned> m_allocatedTextureIds;
};
// Fake video frame that represents a 4x4 YUV video frame.
@@ -2262,14 +2277,13 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext)
class TrackingWebGraphicsContext3D : public FakeWebGraphicsContext3D {
public:
TrackingWebGraphicsContext3D()
- : m_nextTextureId(1)
+ : FakeWebGraphicsContext3D()
, m_numTextures(0)
{ }
virtual WebGLId createTexture() OVERRIDE
{
- WebGLId id = m_nextTextureId;
- ++m_nextTextureId;
+ WebGLId id = FakeWebGraphicsContext3D::createTexture();
m_textures.set(id, true);
++m_numTextures;
@@ -2301,7 +2315,6 @@ public:
unsigned numTextures() const { return m_numTextures; }
private:
- WebGLId m_nextTextureId;
HashMap<WebGLId, bool> m_textures;
unsigned m_numTextures;
};
@@ -2409,20 +2422,15 @@ TEST_F(CCLayerTreeHostImplTest, hasTransparentBackground)
Mock::VerifyAndClearExpectations(&mockContext);
}
-TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
+static void setupLayersForTextureCaching(CCLayerTreeHostImpl* layerTreeHostImpl, CCLayerImpl*& rootPtr, CCLayerImpl*& intermediateLayerPtr, CCLayerImpl*& surfaceLayerPtr, CCLayerImpl*& childPtr)
{
- CCSettings::setPartialSwapEnabled(true);
-
- CCLayerTreeSettings settings;
- OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
-
RefPtr<CCGraphicsContext> context = CCGraphicsContext::create3D(GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new PartialSwapContext()), GraphicsContext3D::RenderDirectlyToHostWindow));
- myHostImpl->initializeLayerRenderer(context.release(), UnthrottledUploader);
- myHostImpl->setViewportSize(IntSize(100, 100));
+ layerTreeHostImpl->initializeLayerRenderer(context.release(), UnthrottledUploader);
+ layerTreeHostImpl->setViewportSize(IntSize(100, 100));
OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
- CCLayerImpl* rootPtr = root.get();
+ rootPtr = root.get();
root->setAnchorPoint(FloatPoint(0, 0));
root->setPosition(FloatPoint(0, 0));
@@ -2430,11 +2438,11 @@ TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
root->setContentBounds(IntSize(100, 100));
root->setVisibleLayerRect(IntRect(0, 0, 100, 100));
root->setDrawsContent(true);
- myHostImpl->setRootLayer(root.release());
+ layerTreeHostImpl->setRootLayer(root.release());
// Intermediate layer does not own a surface, and does not draw content.
OwnPtr<CCLayerImpl> intermediateLayer = CCLayerImpl::create(2);
- CCLayerImpl* intermediateLayerPtr = intermediateLayer.get();
+ intermediateLayerPtr = intermediateLayer.get();
intermediateLayerPtr->setAnchorPoint(FloatPoint(0, 0));
intermediateLayerPtr->setPosition(FloatPoint(10, 10));
@@ -2445,7 +2453,7 @@ TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
rootPtr->addChild(intermediateLayer.release());
OwnPtr<CCLayerImpl> surfaceLayer = CCLayerImpl::create(3);
- CCLayerImpl* surfaceLayerPtr = surfaceLayer.get();
+ surfaceLayerPtr = surfaceLayer.get();
// Surface layer is the layer that changes its opacity
// It will contain other layers that draw content.
@@ -2460,7 +2468,7 @@ TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
// Child of the surface layer will produce some quads
OwnPtr<FakeLayerWithQuads> child = FakeLayerWithQuads::create(4);
- FakeLayerWithQuads* childPtr = child.get();
+ childPtr = child.get();
childPtr->setAnchorPoint(FloatPoint(0, 0));
childPtr->setPosition(FloatPoint(5, 5));
@@ -2470,6 +2478,21 @@ TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
childPtr->setDrawsContent(true);
surfaceLayerPtr->addChild(child.release());
+}
+
+TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
+{
+ CCSettings::setPartialSwapEnabled(true);
+
+ CCLayerTreeSettings settings;
+ OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
+
+ CCLayerImpl* rootPtr;
+ CCLayerImpl* intermediateLayerPtr;
+ CCLayerImpl* surfaceLayerPtr;
+ CCLayerImpl* childPtr;
+
+ setupLayersForTextureCaching(myHostImpl.get(), rootPtr, intermediateLayerPtr, surfaceLayerPtr, childPtr);
{
CCLayerTreeHostImpl::FrameData frame;
@@ -2614,6 +2637,165 @@ TEST_F(CCLayerTreeHostImplTest, surfaceTextureCaching)
}
}
+TEST_F(CCLayerTreeHostImplTest, surfaceTextureCachingNoPartialSwap)
+{
+ CCSettings::setPartialSwapEnabled(false);
+
+ CCLayerTreeSettings settings;
+ OwnPtr<CCLayerTreeHostImpl> myHostImpl = CCLayerTreeHostImpl::create(settings, this);
+
+ CCLayerImpl* rootPtr;
+ CCLayerImpl* intermediateLayerPtr;
+ CCLayerImpl* surfaceLayerPtr;
+ CCLayerImpl* childPtr;
+
+ setupLayersForTextureCaching(myHostImpl.get(), rootPtr, intermediateLayerPtr, surfaceLayerPtr, childPtr);
+
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Must receive two render passes, each with one quad
+ ASSERT_EQ(2U, frame.renderPasses.size());
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+ EXPECT_EQ(1U, frame.renderPasses[1]->quadList().size());
+
+ EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
+ CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
+ EXPECT_TRUE(quad->renderPass()->targetSurface()->contentsChanged());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+
+ // Draw without any change
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Even though there was no change, we set the damage to entire viewport.
+ // One of the passes should be culled as a result, since contents didn't change
+ // and we have cached texture.
+ ASSERT_EQ(1U, frame.renderPasses.size());
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+
+ // Change opacity and draw
+ surfaceLayerPtr->setOpacity(0.6f);
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Must receive one render pass, as the other one should be culled
+ ASSERT_EQ(1U, frame.renderPasses.size());
+
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+ EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[0]->quadList()[0]->material());
+ CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[0]->quadList()[0].get());
+ EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+
+ // Change less benign property and draw - should have contents changed flag
+ surfaceLayerPtr->setStackingOrderChanged(true);
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Must receive two render passes, each with one quad
+ ASSERT_EQ(2U, frame.renderPasses.size());
+
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+ EXPECT_EQ(CCDrawQuad::SolidColor, frame.renderPasses[0]->quadList()[0]->material());
+
+ EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
+ CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
+ EXPECT_TRUE(quad->renderPass()->targetSurface()->contentsChanged());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+
+ // Change opacity again, but evict the cached surface texture
+ surfaceLayerPtr->setOpacity(0.5f);
+ ManagedTexture* contentsTexture = surfaceLayerPtr->renderSurface()->contentsTexture();
+ ASSERT_TRUE(contentsTexture->isValid(contentsTexture->size(), contentsTexture->format()));
+ CCRenderer* renderer = myHostImpl->layerRenderer();
+ TextureManager* textureManager = renderer->implTextureManager();
+ size_t maxMemoryLimit = textureManager->maxMemoryLimitBytes();
+
+ // This should evice all cached surfaces
+ textureManager->setMaxMemoryLimitBytes(0);
+
+ // Restore original limit
+ textureManager->setMaxMemoryLimitBytes(maxMemoryLimit);
+
+ // Was our surface evicted?
+ ASSERT_FALSE(contentsTexture->isValid(contentsTexture->size(), contentsTexture->format()));
+
+ // Change opacity and draw
+ surfaceLayerPtr->setOpacity(0.6f);
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Must receive two render passes
+ ASSERT_EQ(2U, frame.renderPasses.size());
+
+ // Even though not enough properties changed, the entire thing must be
+ // redrawn as we don't have cached textures
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+ EXPECT_EQ(1U, frame.renderPasses[1]->quadList().size());
+
+ EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[1]->quadList()[0]->material());
+ CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[1]->quadList()[0].get());
+ EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+
+ // Draw without any change, to make sure the state is clear
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Even though there was no change, we set the damage to entire viewport.
+ // One of the passes should be culled as a result, since contents didn't change
+ // and we have cached texture.
+ ASSERT_EQ(1U, frame.renderPasses.size());
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+
+ // Change opacity on the intermediate layer
+ WebTransformationMatrix transform = intermediateLayerPtr->transform();
+ transform.setM11(1.0001);
+ intermediateLayerPtr->setTransform(transform);
+ {
+ CCLayerTreeHostImpl::FrameData frame;
+ EXPECT_TRUE(myHostImpl->prepareToDraw(frame));
+
+ // Must receive one render pass, as the other one should be culled.
+ ASSERT_EQ(1U, frame.renderPasses.size());
+ EXPECT_EQ(1U, frame.renderPasses[0]->quadList().size());
+
+ EXPECT_EQ(CCDrawQuad::RenderPass, frame.renderPasses[0]->quadList()[0]->material());
+ CCRenderPassDrawQuad* quad = static_cast<CCRenderPassDrawQuad*>(frame.renderPasses[0]->quadList()[0].get());
+ EXPECT_FALSE(quad->renderPass()->targetSurface()->contentsChanged());
+
+ myHostImpl->drawLayers(frame);
+ myHostImpl->didDrawAllLayers(frame);
+ }
+}
+
struct RenderPassCacheEntry {
mutable OwnPtr<CCRenderPass> renderPassPtr;
CCRenderPass* renderPass;