OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "cc/software_renderer.h" | |
6 | |
7 #include "cc/compositor_frame_metadata.h" | |
8 #include "cc/quad_sink.h" | |
9 #include "cc/render_pass.h" | |
10 #include "cc/render_pass_draw_quad.h" | |
11 #include "cc/software_output_device.h" | |
12 #include "cc/solid_color_draw_quad.h" | |
13 #include "cc/test/animation_test_common.h" | |
14 #include "cc/test/fake_output_surface.h" | |
15 #include "cc/test/geometry_test_utils.h" | |
16 #include "cc/test/render_pass_test_common.h" | |
17 #include "cc/test/render_pass_test_utils.h" | |
18 #include "cc/tile_draw_quad.h" | |
19 #include "testing/gmock/include/gmock/gmock.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | |
21 | |
22 using namespace WebKit; | |
23 | |
24 namespace cc { | |
25 namespace { | |
26 | |
27 class SoftwareRendererTest : public testing::Test, public RendererClient { | |
28 public: | |
29 SoftwareRendererTest() | |
30 : m_shouldClearRootRenderPass(true) | |
31 { | |
32 } | |
33 | |
34 void initializeRenderer() { | |
35 m_outputSurface = FakeOutputSurface::CreateSoftware(make_scoped_ptr(new
SoftwareOutputDevice)); | |
36 resource_provider_ = ResourceProvider::Create(m_outputSurface.get()); | |
37 m_renderer = SoftwareRenderer::Create(this, m_outputSurface.get(), resou
rceProvider()); | |
38 } | |
39 | |
40 ResourceProvider* resourceProvider() const { return resource_provider_.get()
; } | |
41 SoftwareRenderer* renderer() const { return m_renderer.get(); } | |
42 void setViewportSize(const gfx::Size& viewportSize) { m_viewportSize = viewp
ortSize; } | |
43 void setShouldClearRootRenderPass(bool clearRootRenderPass) { m_shouldClearR
ootRenderPass = clearRootRenderPass; } | |
44 | |
45 // RendererClient implementation. | |
46 virtual gfx::Size DeviceViewportSize() const OVERRIDE { return m_viewportSiz
e; } | |
47 virtual const LayerTreeSettings& Settings() const OVERRIDE { return m_settin
gs; } | |
48 virtual void DidLoseOutputSurface() OVERRIDE { } | |
49 virtual void OnSwapBuffersComplete() OVERRIDE { } | |
50 virtual void SetFullRootLayerDamage() OVERRIDE { } | |
51 virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERR
IDE { }; | |
52 virtual void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) O
VERRIDE { }; | |
53 virtual bool HasImplThread() const OVERRIDE { return false; } | |
54 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return m_shouldCle
arRootRenderPass; } | |
55 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const | |
56 OVERRIDE { return CompositorFrameMetadata(); } | |
57 | |
58 protected: | |
59 scoped_ptr<FakeOutputSurface> m_outputSurface; | |
60 scoped_ptr<ResourceProvider> resource_provider_; | |
61 scoped_ptr<SoftwareRenderer> m_renderer; | |
62 gfx::Size m_viewportSize; | |
63 LayerTreeSettings m_settings; | |
64 bool m_shouldClearRootRenderPass; | |
65 }; | |
66 | |
67 TEST_F(SoftwareRendererTest, solidColorQuad) | |
68 { | |
69 gfx::Size outerSize(100, 100); | |
70 int outerPixels = outerSize.width() * outerSize.height(); | |
71 gfx::Size innerSize(98, 98); | |
72 gfx::Rect outerRect(outerSize); | |
73 gfx::Rect innerRect(gfx::Point(1, 1), innerSize); | |
74 setViewportSize(outerSize); | |
75 | |
76 initializeRenderer(); | |
77 | |
78 scoped_ptr<SharedQuadState> sharedQuadState = SharedQuadState::Create(); | |
79 sharedQuadState->SetAll(gfx::Transform(), outerSize, outerRect, outerRect, f
alse, 1.0); | |
80 RenderPass::Id root_render_passId = RenderPass::Id(1, 1); | |
81 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create(); | |
82 root_render_pass->SetNew(root_render_passId, outerRect, outerRect, gfx::Tran
sform()); | |
83 scoped_ptr<SolidColorDrawQuad> outerQuad = SolidColorDrawQuad::Create(); | |
84 outerQuad->SetNew(sharedQuadState.get(), outerRect, SK_ColorYELLOW); | |
85 scoped_ptr<SolidColorDrawQuad> innerQuad = SolidColorDrawQuad::Create(); | |
86 innerQuad->SetNew(sharedQuadState.get(), innerRect, SK_ColorCYAN); | |
87 root_render_pass->AppendQuad(innerQuad.PassAs<DrawQuad>()); | |
88 root_render_pass->AppendQuad(outerQuad.PassAs<DrawQuad>()); | |
89 | |
90 RenderPassList list; | |
91 list.push_back(root_render_pass.PassAs<RenderPass>()); | |
92 renderer()->DrawFrame(list); | |
93 | |
94 scoped_array<SkColor> pixels(new SkColor[DeviceViewportSize().width() * Devi
ceViewportSize().height()]); | |
95 renderer()->GetFramebufferPixels(pixels.get(), outerRect); | |
96 | |
97 // FIXME: This fails on Android. Endianness maybe? | |
98 // Yellow: expects 0xFFFFFF00, was 0xFF00FFFF on android. | |
99 // Cyan: expects 0xFF00FFFF, was 0xFFFFFF00 on android. | |
100 // http://crbug.com/154528 | |
101 #ifndef OS_ANDROID | |
102 EXPECT_EQ(SK_ColorYELLOW, pixels[0]); | |
103 EXPECT_EQ(SK_ColorYELLOW, pixels[outerPixels - 1]); | |
104 EXPECT_EQ(SK_ColorCYAN, pixels[outerSize.width() + 1]); | |
105 EXPECT_EQ(SK_ColorCYAN, pixels[outerPixels - outerSize.width() - 2]); | |
106 #endif | |
107 } | |
108 | |
109 TEST_F(SoftwareRendererTest, tileQuad) | |
110 { | |
111 gfx::Size outerSize(100, 100); | |
112 int outerPixels = outerSize.width() * outerSize.height(); | |
113 gfx::Size innerSize(98, 98); | |
114 int innerPixels = innerSize.width() * innerSize.height(); | |
115 gfx::Rect outerRect(outerSize); | |
116 gfx::Rect innerRect(gfx::Point(1, 1), innerSize); | |
117 setViewportSize(outerSize); | |
118 initializeRenderer(); | |
119 | |
120 ResourceProvider::ResourceId resourceYellow = resourceProvider()->CreateReso
urce(outerSize, GL_RGBA, ResourceProvider::TextureUsageAny); | |
121 ResourceProvider::ResourceId resourceCyan = resourceProvider()->CreateResour
ce(innerSize, GL_RGBA, ResourceProvider::TextureUsageAny); | |
122 | |
123 SkColor yellow = SK_ColorYELLOW; | |
124 SkColor cyan = SK_ColorCYAN; | |
125 scoped_array<SkColor> yellowPixels(new SkColor[outerPixels]); | |
126 scoped_array<SkColor> cyanPixels(new SkColor[innerPixels]); | |
127 for (int i = 0; i < outerPixels; i++) | |
128 yellowPixels[i] = yellow; | |
129 for (int i = 0; i < innerPixels; i++) | |
130 cyanPixels[i] = cyan; | |
131 | |
132 resourceProvider()->SetPixels(resourceYellow, reinterpret_cast<uint8_t*>(yel
lowPixels.get()), gfx::Rect(outerSize), gfx::Rect(outerSize), gfx::Vector2d()); | |
133 resourceProvider()->SetPixels(resourceCyan, reinterpret_cast<uint8_t*>(cyanP
ixels.get()), gfx::Rect(innerSize), gfx::Rect(innerSize), gfx::Vector2d()); | |
134 | |
135 gfx::Rect rootRect = gfx::Rect(DeviceViewportSize()); | |
136 | |
137 scoped_ptr<SharedQuadState> sharedQuadState = SharedQuadState::Create(); | |
138 sharedQuadState->SetAll(gfx::Transform(), outerSize, outerRect, outerRect, f
alse, 1.0); | |
139 RenderPass::Id root_render_passId = RenderPass::Id(1, 1); | |
140 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create(); | |
141 root_render_pass->SetNew(root_render_passId, rootRect, rootRect, gfx::Transf
orm()); | |
142 scoped_ptr<TileDrawQuad> outerQuad = TileDrawQuad::Create(); | |
143 outerQuad->SetNew(sharedQuadState.get(), outerRect, outerRect, resourceYello
w, gfx::RectF(outerSize), outerSize, false); | |
144 scoped_ptr<TileDrawQuad> innerQuad = TileDrawQuad::Create(); | |
145 innerQuad->SetNew(sharedQuadState.get(), innerRect, innerRect, resourceCyan,
gfx::RectF(innerSize), innerSize, false); | |
146 root_render_pass->AppendQuad(innerQuad.PassAs<DrawQuad>()); | |
147 root_render_pass->AppendQuad(outerQuad.PassAs<DrawQuad>()); | |
148 | |
149 RenderPassList list; | |
150 list.push_back(root_render_pass.PassAs<RenderPass>()); | |
151 renderer()->DrawFrame(list); | |
152 | |
153 scoped_array<SkColor> pixels(new SkColor[DeviceViewportSize().width() * Devi
ceViewportSize().height()]); | |
154 renderer()->GetFramebufferPixels(pixels.get(), outerRect); | |
155 | |
156 EXPECT_EQ(SK_ColorYELLOW, pixels[0]); | |
157 EXPECT_EQ(SK_ColorYELLOW, pixels[outerPixels - 1]); | |
158 EXPECT_EQ(SK_ColorCYAN, pixels[outerSize.width() + 1]); | |
159 EXPECT_EQ(SK_ColorCYAN, pixels[outerPixels - outerSize.width() - 2]); | |
160 } | |
161 | |
162 TEST_F(SoftwareRendererTest, shouldClearRootRenderPass) | |
163 { | |
164 gfx::Rect viewportRect(gfx::Size(100, 100)); | |
165 size_t viewportPixels = viewportRect.width() * viewportRect.height(); | |
166 setViewportSize(viewportRect.size()); | |
167 setShouldClearRootRenderPass(false); | |
168 initializeRenderer(); | |
169 | |
170 RenderPassList list; | |
171 scoped_array<SkColor> pixels(new SkColor[viewportPixels]); | |
172 | |
173 // Draw a fullscreen green quad in a first frame. | |
174 RenderPass::Id rootClearPassId(1, 0); | |
175 TestRenderPass* rootClearPass = addRenderPass(list, rootClearPassId, viewpor
tRect, gfx::Transform()); | |
176 addQuad(rootClearPass, viewportRect, SK_ColorGREEN); | |
177 | |
178 renderer()->DecideRenderPassAllocationsForFrame(list); | |
179 renderer()->DrawFrame(list); | |
180 renderer()->GetFramebufferPixels(pixels.get(), viewportRect); | |
181 | |
182 EXPECT_EQ(SK_ColorGREEN, pixels[0]); | |
183 EXPECT_EQ(SK_ColorGREEN, pixels[viewportPixels - 1]); | |
184 | |
185 list.clear(); | |
186 | |
187 // Draw a smaller magenta rect without filling the viewport in a separate fr
ame. | |
188 gfx::Rect smallerRect(20, 20, 60, 60); | |
189 | |
190 RenderPass::Id rootSmallerPassId(2, 0); | |
191 TestRenderPass* rootSmallerPass = addRenderPass(list, rootSmallerPassId, vie
wportRect, gfx::Transform()); | |
192 addQuad(rootSmallerPass, smallerRect, SK_ColorMAGENTA); | |
193 | |
194 renderer()->DecideRenderPassAllocationsForFrame(list); | |
195 renderer()->DrawFrame(list); | |
196 renderer()->GetFramebufferPixels(pixels.get(), viewportRect); | |
197 | |
198 // If we didn't clear, the borders should still be green. | |
199 EXPECT_EQ(SK_ColorGREEN, pixels[0]); | |
200 EXPECT_EQ(SK_ColorGREEN, pixels[viewportPixels - 1]); | |
201 | |
202 EXPECT_EQ(SK_ColorMAGENTA, pixels[smallerRect.y() * viewportRect.width() + s
mallerRect.x()]); | |
203 EXPECT_EQ(SK_ColorMAGENTA, pixels[(smallerRect.bottom() - 1) * viewportRect.
width() + smallerRect.right() - 1]); | |
204 } | |
205 | |
206 } // namespace | |
207 } // namespace cc | |
OLD | NEW |