LayerRendererChromiumTest.cpp [plain text]
#include "config.h"
#include "LayerRendererChromium.h"
#include "FakeWebGraphicsContext3D.h"
#include "GraphicsContext3D.h"
#include "GraphicsContext3DPrivate.h"
#include "cc/CCSingleThreadProxy.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using namespace WebCore;
using namespace WebKit;
class FrameCountingMemoryAllocationSettingContext : public FakeWebGraphicsContext3D {
public:
FrameCountingMemoryAllocationSettingContext() : m_frame(0) { }
virtual void prepareTexture() { m_frame++; }
virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) { m_memoryAllocationChangedCallback = callback; }
virtual WebString getString(WebKit::WGC3Denum name)
{
if (name == GraphicsContext3D::EXTENSIONS)
return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager GL_CHROMIUM_discard_framebuffer");
return WebString();
}
int frameCount() { return m_frame; }
void setMemoryAllocation(WebGraphicsMemoryAllocation allocation) { m_memoryAllocationChangedCallback->onMemoryAllocationChanged(allocation); }
private:
int m_frame;
WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* m_memoryAllocationChangedCallback;
};
class FakeLayerRendererChromiumClient : public LayerRendererChromiumClient {
public:
FakeLayerRendererChromiumClient()
: m_setFullRootLayerDamageCount(0)
, m_rootLayer(CCLayerImpl::create(1))
{
m_rootLayer->createRenderSurface();
}
virtual const IntSize& viewportSize() const OVERRIDE { static IntSize fakeSize; return fakeSize; }
virtual const CCSettings& settings() const OVERRIDE { static CCSettings fakeSettings; return fakeSettings; }
virtual void didLoseContext() OVERRIDE { }
virtual void onSwapBuffersComplete() OVERRIDE { }
virtual void setFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCount++; }
virtual void setContentsMemoryAllocationLimitBytes(size_t) OVERRIDE { }
int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCount; }
CCLayerImpl* rootLayer() { return m_rootLayer.get(); }
private:
int m_setFullRootLayerDamageCount;
DebugScopedSetImplThread m_implThread;
OwnPtr<CCLayerImpl> m_rootLayer;
};
class FakeLayerRendererChromium : public LayerRendererChromium {
public:
FakeLayerRendererChromium(LayerRendererChromiumClient* client, PassRefPtr<GraphicsContext3D> context) : LayerRendererChromium(client, context) { }
using LayerRendererChromium::initialize;
using LayerRendererChromium::isFramebufferDiscarded;
};
class LayerRendererChromiumTest : public testing::Test {
protected:
LayerRendererChromiumTest()
: m_suggestHaveBackbufferYes(1, true)
, m_suggestHaveBackbufferNo(1, false)
, m_context(GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new FrameCountingMemoryAllocationSettingContext()), GraphicsContext3D::RenderDirectlyToHostWindow))
, m_mockContext(*static_cast<FrameCountingMemoryAllocationSettingContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(m_context.get())))
, m_layerRendererChromium(&m_mockClient, m_context.release())
{
}
virtual void SetUp()
{
m_layerRendererChromium.initialize();
}
void swapBuffers()
{
m_layerRendererChromium.swapBuffers(IntRect());
}
WebGraphicsMemoryAllocation m_suggestHaveBackbufferYes;
WebGraphicsMemoryAllocation m_suggestHaveBackbufferNo;
RefPtr<GraphicsContext3D> m_context;
FrameCountingMemoryAllocationSettingContext& m_mockContext;
FakeLayerRendererChromiumClient m_mockClient;
FakeLayerRendererChromium m_layerRendererChromium;
};
TEST_F(LayerRendererChromiumTest, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing)
{
m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferYes);
EXPECT_EQ(0, m_mockClient.setFullRootLayerDamageCount());
EXPECT_FALSE(m_layerRendererChromium.isFramebufferDiscarded());
swapBuffers();
EXPECT_EQ(1, m_mockContext.frameCount());
}
TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayer)
{
m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
}
TEST_F(LayerRendererChromiumTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing)
{
m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
}
TEST_F(LayerRendererChromiumTest, SwapBuffersWhileBackbufferDiscardedShouldIgnoreSwapAndDamageRootLayer)
{
m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
swapBuffers();
EXPECT_EQ(0, m_mockContext.frameCount());
EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount());
swapBuffers();
EXPECT_EQ(0, m_mockContext.frameCount());
EXPECT_EQ(3, m_mockClient.setFullRootLayerDamageCount());
}
TEST_F(LayerRendererChromiumTest, DiscardedBackbufferIsRecreatredForScopeDuration)
{
m_mockContext.setMemoryAllocation(m_suggestHaveBackbufferNo);
EXPECT_TRUE(m_layerRendererChromium.isFramebufferDiscarded());
EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount());
m_layerRendererChromium.beginDrawingFrame(m_mockClient.rootLayer()->renderSurface());
EXPECT_FALSE(m_layerRendererChromium.isFramebufferDiscarded());
swapBuffers();
EXPECT_EQ(1, m_mockContext.frameCount());
}
class ForbidSynchronousCallContext : public FakeWebGraphicsContext3D {
public:
ForbidSynchronousCallContext() { }
virtual bool getActiveAttrib(WebGLId program, WGC3Duint index, ActiveInfo&) { ADD_FAILURE(); return false; }
virtual bool getActiveUniform(WebGLId program, WGC3Duint index, ActiveInfo&) { ADD_FAILURE(); return false; }
virtual void getAttachedShaders(WebGLId program, WGC3Dsizei maxCount, WGC3Dsizei* count, WebGLId* shaders) { ADD_FAILURE(); }
virtual WGC3Dint getAttribLocation(WebGLId program, const WGC3Dchar* name) { ADD_FAILURE(); return 0; }
virtual void getBooleanv(WGC3Denum pname, WGC3Dboolean* value) { ADD_FAILURE(); }
virtual void getBufferParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); }
virtual Attributes getContextAttributes() { ADD_FAILURE(); return m_attrs; }
virtual WGC3Denum getError() { ADD_FAILURE(); return 0; }
virtual void getFloatv(WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); }
virtual void getFramebufferAttachmentParameteriv(WGC3Denum target, WGC3Denum attachment, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); }
virtual void getIntegerv(WGC3Denum pname, WGC3Dint* value)
{
if (pname == WebCore::GraphicsContext3D::MAX_TEXTURE_SIZE)
*value = 1024; else
ADD_FAILURE();
}
virtual void getProgramiv(WebGLId program, WGC3Denum pname, WGC3Dint* value)
{
#ifndef NDEBUG
*value = 1;
#else
ADD_FAILURE();
#endif
}
virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value)
{
#ifndef NDEBUG
*value = 1;
#else
ADD_FAILURE();
#endif
}
virtual WebString getString(WGC3Denum name)
{
if (name != WebCore::GraphicsContext3D::EXTENSIONS)
ADD_FAILURE();
return WebString();
}
virtual WebString getProgramInfoLog(WebGLId program) { ADD_FAILURE(); return WebString(); }
virtual void getRenderbufferParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); }
virtual WebString getShaderInfoLog(WebGLId shader) { ADD_FAILURE(); return WebString(); }
virtual void getShaderPrecisionFormat(WGC3Denum shadertype, WGC3Denum precisiontype, WGC3Dint* range, WGC3Dint* precision) { ADD_FAILURE(); }
virtual WebString getShaderSource(WebGLId shader) { ADD_FAILURE(); return WebString(); }
virtual void getTexParameterfv(WGC3Denum target, WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); }
virtual void getTexParameteriv(WGC3Denum target, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); }
virtual void getUniformfv(WebGLId program, WGC3Dint location, WGC3Dfloat* value) { ADD_FAILURE(); }
virtual void getUniformiv(WebGLId program, WGC3Dint location, WGC3Dint* value) { ADD_FAILURE(); }
virtual WGC3Dint getUniformLocation(WebGLId program, const WGC3Dchar* name) { ADD_FAILURE(); return 0; }
virtual void getVertexAttribfv(WGC3Duint index, WGC3Denum pname, WGC3Dfloat* value) { ADD_FAILURE(); }
virtual void getVertexAttribiv(WGC3Duint index, WGC3Denum pname, WGC3Dint* value) { ADD_FAILURE(); }
virtual WGC3Dsizeiptr getVertexAttribOffset(WGC3Duint index, WGC3Denum pname) { ADD_FAILURE(); return 0; }
};
TEST(LayerRendererChromiumTest2, initializationDoesNotMakeSynchronousCalls)
{
FakeLayerRendererChromiumClient mockClient;
FakeLayerRendererChromium layerRendererChromium(&mockClient, GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new ForbidSynchronousCallContext), GraphicsContext3D::RenderDirectlyToHostWindow));
EXPECT_TRUE(layerRendererChromium.initialize());
}