1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/software_renderer.h"
7 #include "cc/quad_sink.h"
8 #include "cc/render_pass.h"
9 #include "cc/render_pass_draw_quad.h"
10 #include "cc/solid_color_draw_quad.h"
11 #include "cc/test/animation_test_common.h"
12 #include "cc/test/fake_web_compositor_output_surface.h"
13 #include "cc/test/fake_web_compositor_software_output_device.h"
14 #include "cc/test/geometry_test_utils.h"
15 #include "cc/test/render_pass_test_common.h"
16 #include "cc/tile_draw_quad.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using namespace WebKit
;
21 using namespace WebKitTests
;
26 class SoftwareRendererTest
: public testing::Test
, public RendererClient
{
28 void initializeRenderer() {
29 m_outputSurface
= FakeWebCompositorOutputSurface::createSoftware(scoped_ptr
<WebKit::WebCompositorSoftwareOutputDevice
>(new FakeWebCompositorSoftwareOutputDevice
));
30 m_resourceProvider
= ResourceProvider::create(m_outputSurface
.get());
31 m_renderer
= SoftwareRenderer::create(this, resourceProvider(), softwareDevice());
34 WebCompositorSoftwareOutputDevice
* softwareDevice() const { return m_outputSurface
->softwareDevice(); }
35 FakeWebCompositorOutputSurface
* outputSurface() const { return m_outputSurface
.get(); }
36 ResourceProvider
* resourceProvider() const { return m_resourceProvider
.get(); }
37 SoftwareRenderer
* renderer() const { return m_renderer
.get(); }
38 void setViewportSize(gfx::Size viewportSize
) { m_viewportSize
= viewportSize
; }
40 // RendererClient implementation.
41 virtual const gfx::Size
& deviceViewportSize() const OVERRIDE
{ return m_viewportSize
; }
42 virtual const LayerTreeSettings
& settings() const OVERRIDE
{ return m_settings
; }
43 virtual void didLoseContext() OVERRIDE
{ }
44 virtual void onSwapBuffersComplete() OVERRIDE
{ }
45 virtual void setFullRootLayerDamage() OVERRIDE
{ }
46 virtual void setManagedMemoryPolicy(const ManagedMemoryPolicy
& policy
) OVERRIDE
{ };
47 virtual void enforceManagedMemoryPolicy(const ManagedMemoryPolicy
& policy
) OVERRIDE
{ };
48 virtual bool hasImplThread() const OVERRIDE
{ return false; }
51 scoped_ptr
<FakeWebCompositorOutputSurface
> m_outputSurface
;
52 scoped_ptr
<ResourceProvider
> m_resourceProvider
;
53 scoped_ptr
<SoftwareRenderer
> m_renderer
;
54 gfx::Size m_viewportSize
;
55 LayerTreeSettings m_settings
;
58 TEST_F(SoftwareRendererTest
, solidColorQuad
)
60 gfx::Size
outerSize(100, 100);
61 int outerPixels
= outerSize
.width() * outerSize
.height();
62 gfx::Size
innerSize(98, 98);
63 gfx::Rect
outerRect(gfx::Point(), outerSize
);
64 gfx::Rect
innerRect(gfx::Point(1, 1), innerSize
);
65 setViewportSize(outerSize
);
69 scoped_ptr
<SharedQuadState
> sharedQuadState
= SharedQuadState::create(WebTransformationMatrix(), outerRect
, outerRect
, 1.0, true);
70 RenderPass::Id rootRenderPassId
= RenderPass::Id(1, 1);
71 scoped_ptr
<TestRenderPass
> rootRenderPass
= TestRenderPass::create(rootRenderPassId
, outerRect
, WebTransformationMatrix());
72 scoped_ptr
<DrawQuad
> outerQuad
= SolidColorDrawQuad::create(sharedQuadState
.get(), outerRect
, SK_ColorYELLOW
).PassAs
<DrawQuad
>();
73 scoped_ptr
<DrawQuad
> innerQuad
= SolidColorDrawQuad::create(sharedQuadState
.get(), innerRect
, SK_ColorCYAN
).PassAs
<DrawQuad
>();
74 rootRenderPass
->appendQuad(innerQuad
.Pass());
75 rootRenderPass
->appendQuad(outerQuad
.Pass());
78 RenderPassIdHashMap hashmap
;
79 list
.push_back(rootRenderPass
.get());
80 hashmap
.add(rootRenderPassId
, rootRenderPass
.PassAs
<RenderPass
>());
81 renderer()->drawFrame(list
, hashmap
);
83 scoped_array
<SkColor
> pixels(new SkColor
[deviceViewportSize().width() * deviceViewportSize().height()]);
84 renderer()->getFramebufferPixels(pixels
.get(), outerRect
);
86 // FIXME: This fails on Android. Endianness maybe?
87 // Yellow: expects 0xFFFFFF00, was 0xFF00FFFF on android.
88 // Cyan: expects 0xFF00FFFF, was 0xFFFFFF00 on android.
89 // http://crbug.com/154528
91 EXPECT_EQ(SK_ColorYELLOW
, pixels
[0]);
92 EXPECT_EQ(SK_ColorYELLOW
, pixels
[outerPixels
- 1]);
93 EXPECT_EQ(SK_ColorCYAN
, pixels
[outerSize
.width() + 1]);
94 EXPECT_EQ(SK_ColorCYAN
, pixels
[outerPixels
- outerSize
.width() - 2]);
98 TEST_F(SoftwareRendererTest
, tileQuad
)
100 gfx::Size
outerSize(100, 100);
101 int outerPixels
= outerSize
.width() * outerSize
.height();
102 gfx::Size
innerSize(98, 98);
103 int innerPixels
= innerSize
.width() * innerSize
.height();
104 gfx::Rect
outerRect(gfx::Point(), outerSize
);
105 gfx::Rect
innerRect(gfx::Point(1, 1), innerSize
);
106 setViewportSize(outerSize
);
107 initializeRenderer();
109 ResourceProvider::ResourceId resourceYellow
= resourceProvider()->createResource(1, outerSize
, GL_RGBA
, ResourceProvider::TextureUsageAny
);
110 ResourceProvider::ResourceId resourceCyan
= resourceProvider()->createResource(1, innerSize
, GL_RGBA
, ResourceProvider::TextureUsageAny
);
112 SkColor yellow
= SK_ColorYELLOW
;
113 SkColor cyan
= SK_ColorCYAN
;
114 scoped_array
<SkColor
> yellowPixels(new SkColor
[outerPixels
]);
115 scoped_array
<SkColor
> cyanPixels(new SkColor
[innerPixels
]);
116 for (int i
= 0; i
< outerPixels
; i
++)
117 yellowPixels
[i
] = yellow
;
118 for (int i
= 0; i
< innerPixels
; i
++)
119 cyanPixels
[i
] = cyan
;
121 resourceProvider()->setPixels(resourceYellow
, reinterpret_cast<uint8_t*>(yellowPixels
.get()), gfx::Rect(gfx::Point(), outerSize
), gfx::Rect(gfx::Point(), outerSize
), gfx::Vector2d());
122 resourceProvider()->setPixels(resourceCyan
, reinterpret_cast<uint8_t*>(cyanPixels
.get()), gfx::Rect(gfx::Point(), innerSize
), gfx::Rect(gfx::Point(), innerSize
), gfx::Vector2d());
124 gfx::Rect rect
= gfx::Rect(gfx::Point(), deviceViewportSize());
126 scoped_ptr
<SharedQuadState
> sharedQuadState
= SharedQuadState::create(WebTransformationMatrix(), outerRect
, outerRect
, 1.0, true);
127 RenderPass::Id rootRenderPassId
= RenderPass::Id(1, 1);
128 scoped_ptr
<TestRenderPass
> rootRenderPass
= TestRenderPass::create(rootRenderPassId
, gfx::Rect(gfx::Point(), deviceViewportSize()), WebTransformationMatrix());
129 scoped_ptr
<DrawQuad
> outerQuad
= TileDrawQuad::create(sharedQuadState
.get(), outerRect
, outerRect
, resourceYellow
, gfx::Vector2d(), outerSize
, false, false, false, false, false).PassAs
<DrawQuad
>();
130 scoped_ptr
<DrawQuad
> innerQuad
= TileDrawQuad::create(sharedQuadState
.get(), innerRect
, innerRect
, resourceCyan
, gfx::Vector2d(), innerSize
, false, false, false, false, false).PassAs
<DrawQuad
>();
131 rootRenderPass
->appendQuad(innerQuad
.Pass());
132 rootRenderPass
->appendQuad(outerQuad
.Pass());
135 RenderPassIdHashMap hashmap
;
136 list
.push_back(rootRenderPass
.get());
137 hashmap
.add(rootRenderPassId
, rootRenderPass
.PassAs
<RenderPass
>());
138 renderer()->drawFrame(list
, hashmap
);
140 scoped_array
<SkColor
> pixels(new SkColor
[deviceViewportSize().width() * deviceViewportSize().height()]);
141 renderer()->getFramebufferPixels(pixels
.get(), outerRect
);
143 EXPECT_EQ(SK_ColorYELLOW
, pixels
[0]);
144 EXPECT_EQ(SK_ColorYELLOW
, pixels
[outerPixels
- 1]);
145 EXPECT_EQ(SK_ColorCYAN
, pixels
[outerSize
.width() + 1]);
146 EXPECT_EQ(SK_ColorCYAN
, pixels
[outerPixels
- outerSize
.width() - 2]);