Move prefs::kLastPolicyStatisticsUpdate to the policy component.
[chromium-blink-merge.git] / cc / output / software_renderer_unittest.cc
blob03f1635084be626feaaa89fa6c5fa9e0d7d983dc
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/output/software_renderer.h"
7 #include "cc/layers/quad_sink.h"
8 #include "cc/output/compositor_frame_metadata.h"
9 #include "cc/output/software_output_device.h"
10 #include "cc/quads/render_pass.h"
11 #include "cc/quads/render_pass_draw_quad.h"
12 #include "cc/quads/solid_color_draw_quad.h"
13 #include "cc/quads/tile_draw_quad.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_output_surface.h"
16 #include "cc/test/fake_output_surface_client.h"
17 #include "cc/test/geometry_test_utils.h"
18 #include "cc/test/render_pass_test_common.h"
19 #include "cc/test/render_pass_test_utils.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/skia/include/core/SkCanvas.h"
23 #include "third_party/skia/include/core/SkDevice.h"
25 namespace cc {
26 namespace {
28 class SoftwareRendererTest : public testing::Test, public RendererClient {
29 public:
30 void InitializeRenderer(
31 scoped_ptr<SoftwareOutputDevice> software_output_device) {
32 output_surface_ = FakeOutputSurface::CreateSoftware(
33 software_output_device.Pass());
34 CHECK(output_surface_->BindToClient(&output_surface_client_));
36 resource_provider_ =
37 ResourceProvider::Create(output_surface_.get(), 0, false);
38 renderer_ = SoftwareRenderer::Create(
39 this, &settings_, output_surface_.get(), resource_provider());
42 ResourceProvider* resource_provider() const {
43 return resource_provider_.get();
46 SoftwareRenderer* renderer() const { return renderer_.get(); }
48 void set_viewport(gfx::Rect viewport) {
49 viewport_ = viewport;
52 // RendererClient implementation.
53 virtual gfx::Rect DeviceViewport() const OVERRIDE {
54 return viewport_;
56 virtual gfx::Rect DeviceClip() const OVERRIDE { return DeviceViewport(); }
57 virtual void SetFullRootLayerDamage() OVERRIDE {}
58 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE {
59 return CompositorFrameMetadata();
62 protected:
63 LayerTreeSettings settings_;
64 FakeOutputSurfaceClient output_surface_client_;
65 scoped_ptr<FakeOutputSurface> output_surface_;
66 scoped_ptr<ResourceProvider> resource_provider_;
67 scoped_ptr<SoftwareRenderer> renderer_;
68 gfx::Rect viewport_;
71 TEST_F(SoftwareRendererTest, SolidColorQuad) {
72 gfx::Size outer_size(100, 100);
73 gfx::Size inner_size(98, 98);
74 gfx::Rect outer_rect(outer_size);
75 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
76 gfx::Rect visible_rect(gfx::Point(1, 2), gfx::Size(98, 97));
77 set_viewport(gfx::Rect(outer_size));
79 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
81 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
82 shared_quad_state->SetAll(
83 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0);
84 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
85 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
86 root_render_pass->SetNew(
87 root_render_pass_id, outer_rect, outer_rect, gfx::Transform());
88 scoped_ptr<SolidColorDrawQuad> outer_quad = SolidColorDrawQuad::Create();
89 outer_quad->SetNew(
90 shared_quad_state.get(), outer_rect, SK_ColorYELLOW, false);
91 scoped_ptr<SolidColorDrawQuad> inner_quad = SolidColorDrawQuad::Create();
92 inner_quad->SetNew(shared_quad_state.get(), inner_rect, SK_ColorCYAN, false);
93 inner_quad->visible_rect = visible_rect;
94 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>());
95 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>());
97 RenderPassList list;
98 list.push_back(root_render_pass.PassAs<RenderPass>());
100 float device_scale_factor = 1.f;
101 renderer()->DrawFrame(&list, NULL, device_scale_factor, true);
103 SkBitmap output;
104 output.setConfig(SkBitmap::kARGB_8888_Config,
105 DeviceViewport().width(),
106 DeviceViewport().height());
107 output.allocPixels();
108 renderer()->GetFramebufferPixels(output.getPixels(), outer_rect);
110 EXPECT_EQ(SK_ColorYELLOW, output.getColor(0, 0));
111 EXPECT_EQ(SK_ColorYELLOW,
112 output.getColor(outer_size.width() - 1, outer_size.height() - 1));
113 EXPECT_EQ(SK_ColorYELLOW, output.getColor(1, 1));
114 EXPECT_EQ(SK_ColorCYAN, output.getColor(1, 2));
115 EXPECT_EQ(SK_ColorCYAN,
116 output.getColor(inner_size.width() - 1, inner_size.height() - 1));
119 TEST_F(SoftwareRendererTest, TileQuad) {
120 gfx::Size outer_size(100, 100);
121 gfx::Size inner_size(98, 98);
122 gfx::Rect outer_rect(outer_size);
123 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
124 set_viewport(gfx::Rect(outer_size));
125 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
127 ResourceProvider::ResourceId resource_yellow =
128 resource_provider()->CreateResource(outer_size,
129 GL_CLAMP_TO_EDGE,
130 ResourceProvider::TextureUsageAny,
131 RGBA_8888);
132 ResourceProvider::ResourceId resource_cyan =
133 resource_provider()->CreateResource(inner_size,
134 GL_CLAMP_TO_EDGE,
135 ResourceProvider::TextureUsageAny,
136 RGBA_8888);
138 SkBitmap yellow_tile;
139 yellow_tile.setConfig(
140 SkBitmap::kARGB_8888_Config, outer_size.width(), outer_size.height());
141 yellow_tile.allocPixels();
142 yellow_tile.eraseColor(SK_ColorYELLOW);
144 SkBitmap cyan_tile;
145 cyan_tile.setConfig(
146 SkBitmap::kARGB_8888_Config, inner_size.width(), inner_size.height());
147 cyan_tile.allocPixels();
148 cyan_tile.eraseColor(SK_ColorCYAN);
150 resource_provider()->SetPixels(
151 resource_yellow,
152 static_cast<uint8_t*>(yellow_tile.getPixels()),
153 gfx::Rect(outer_size),
154 gfx::Rect(outer_size),
155 gfx::Vector2d());
156 resource_provider()->SetPixels(resource_cyan,
157 static_cast<uint8_t*>(cyan_tile.getPixels()),
158 gfx::Rect(inner_size),
159 gfx::Rect(inner_size),
160 gfx::Vector2d());
162 gfx::Rect root_rect = DeviceViewport();
164 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
165 shared_quad_state->SetAll(
166 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0);
167 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
168 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
169 root_render_pass->SetNew(
170 root_render_pass_id, root_rect, root_rect, gfx::Transform());
171 scoped_ptr<TileDrawQuad> outer_quad = TileDrawQuad::Create();
172 outer_quad->SetNew(shared_quad_state.get(),
173 outer_rect,
174 outer_rect,
175 resource_yellow,
176 gfx::RectF(outer_size),
177 outer_size,
178 false);
179 scoped_ptr<TileDrawQuad> inner_quad = TileDrawQuad::Create();
180 inner_quad->SetNew(shared_quad_state.get(),
181 inner_rect,
182 inner_rect,
183 resource_cyan,
184 gfx::RectF(inner_size),
185 inner_size,
186 false);
187 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>());
188 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>());
190 RenderPassList list;
191 list.push_back(root_render_pass.PassAs<RenderPass>());
193 float device_scale_factor = 1.f;
194 renderer()->DrawFrame(&list, NULL, device_scale_factor, true);
196 SkBitmap output;
197 output.setConfig(SkBitmap::kARGB_8888_Config,
198 DeviceViewport().width(),
199 DeviceViewport().height());
200 output.allocPixels();
201 renderer()->GetFramebufferPixels(output.getPixels(), outer_rect);
203 EXPECT_EQ(SK_ColorYELLOW, output.getColor(0, 0));
204 EXPECT_EQ(SK_ColorYELLOW,
205 output.getColor(outer_size.width() - 1, outer_size.height() - 1));
206 EXPECT_EQ(SK_ColorCYAN, output.getColor(1, 1));
207 EXPECT_EQ(SK_ColorCYAN,
208 output.getColor(inner_size.width() - 1, inner_size.height() - 1));
211 TEST_F(SoftwareRendererTest, TileQuadVisibleRect) {
212 gfx::Size tile_size(100, 100);
213 gfx::Rect tile_rect(tile_size);
214 gfx::Rect visible_rect = tile_rect;
215 visible_rect.Inset(1, 2, 3, 4);
216 set_viewport(gfx::Rect(tile_size));
217 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
219 ResourceProvider::ResourceId resource_cyan =
220 resource_provider()->CreateResource(tile_size,
221 GL_CLAMP_TO_EDGE,
222 ResourceProvider::TextureUsageAny,
223 RGBA_8888);
225 SkBitmap cyan_tile; // The lowest five rows are yellow.
226 cyan_tile.setConfig(
227 SkBitmap::kARGB_8888_Config, tile_size.width(), tile_size.height());
228 cyan_tile.allocPixels();
229 cyan_tile.eraseColor(SK_ColorCYAN);
230 cyan_tile.eraseArea(
231 SkIRect::MakeLTRB(
232 0, visible_rect.bottom() - 1, tile_rect.width(), tile_rect.bottom()),
233 SK_ColorYELLOW);
235 resource_provider()->SetPixels(resource_cyan,
236 static_cast<uint8_t*>(cyan_tile.getPixels()),
237 gfx::Rect(tile_size),
238 gfx::Rect(tile_size),
239 gfx::Vector2d());
241 gfx::Rect root_rect = DeviceViewport();
243 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
244 shared_quad_state->SetAll(
245 gfx::Transform(), tile_size, tile_rect, tile_rect, false, 1.0);
246 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
247 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
248 root_render_pass->SetNew(
249 root_render_pass_id, root_rect, root_rect, gfx::Transform());
250 scoped_ptr<TileDrawQuad> quad = TileDrawQuad::Create();
251 quad->SetNew(shared_quad_state.get(),
252 tile_rect,
253 tile_rect,
254 resource_cyan,
255 gfx::RectF(tile_size),
256 tile_size,
257 false);
258 quad->visible_rect = visible_rect;
259 root_render_pass->AppendQuad(quad.PassAs<DrawQuad>());
261 RenderPassList list;
262 list.push_back(root_render_pass.PassAs<RenderPass>());
264 float device_scale_factor = 1.f;
265 renderer()->DrawFrame(&list, NULL, device_scale_factor, true);
267 SkBitmap output;
268 output.setConfig(SkBitmap::kARGB_8888_Config,
269 DeviceViewport().width(),
270 DeviceViewport().height());
271 output.allocPixels();
272 renderer()->GetFramebufferPixels(output.getPixels(), tile_rect);
274 // Check portion of tile not in visible rect isn't drawn.
275 const unsigned int kTransparent = SK_ColorTRANSPARENT;
276 EXPECT_EQ(kTransparent, output.getColor(0, 0));
277 EXPECT_EQ(kTransparent,
278 output.getColor(tile_rect.width() - 1, tile_rect.height() - 1));
279 EXPECT_EQ(kTransparent,
280 output.getColor(visible_rect.x() - 1, visible_rect.y() - 1));
281 EXPECT_EQ(kTransparent,
282 output.getColor(visible_rect.right(), visible_rect.bottom()));
283 // Ensure visible part is drawn correctly.
284 EXPECT_EQ(SK_ColorCYAN, output.getColor(visible_rect.x(), visible_rect.y()));
285 EXPECT_EQ(
286 SK_ColorCYAN,
287 output.getColor(visible_rect.right() - 2, visible_rect.bottom() - 2));
288 // Ensure last visible line is correct.
289 EXPECT_EQ(
290 SK_ColorYELLOW,
291 output.getColor(visible_rect.right() - 1, visible_rect.bottom() - 1));
294 TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
295 float device_scale_factor = 1.f;
296 gfx::Rect viewport_rect(0, 0, 100, 100);
297 set_viewport(viewport_rect);
299 settings_.should_clear_root_render_pass = false;
300 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
302 RenderPassList list;
304 SkBitmap output;
305 output.setConfig(SkBitmap::kARGB_8888_Config,
306 viewport_rect.width(),
307 viewport_rect.height());
308 output.allocPixels();
310 // Draw a fullscreen green quad in a first frame.
311 RenderPass::Id root_clear_pass_id(1, 0);
312 TestRenderPass* root_clear_pass = AddRenderPass(
313 &list, root_clear_pass_id, viewport_rect, gfx::Transform());
314 AddQuad(root_clear_pass, viewport_rect, SK_ColorGREEN);
316 renderer()->DecideRenderPassAllocationsForFrame(list);
317 renderer()->DrawFrame(&list, NULL, device_scale_factor, true);
318 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect);
320 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0));
321 EXPECT_EQ(SK_ColorGREEN,
322 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1));
324 list.clear();
326 // Draw a smaller magenta rect without filling the viewport in a separate
327 // frame.
328 gfx::Rect smaller_rect(20, 20, 60, 60);
330 RenderPass::Id root_smaller_pass_id(2, 0);
331 TestRenderPass* root_smaller_pass = AddRenderPass(
332 &list, root_smaller_pass_id, viewport_rect, gfx::Transform());
333 AddQuad(root_smaller_pass, smaller_rect, SK_ColorMAGENTA);
335 renderer()->DecideRenderPassAllocationsForFrame(list);
336 renderer()->DrawFrame(&list, NULL, device_scale_factor, true);
337 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect);
339 // If we didn't clear, the borders should still be green.
340 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0));
341 EXPECT_EQ(SK_ColorGREEN,
342 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1));
344 EXPECT_EQ(SK_ColorMAGENTA,
345 output.getColor(smaller_rect.x(), smaller_rect.y()));
346 EXPECT_EQ(SK_ColorMAGENTA,
347 output.getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));
350 TEST_F(SoftwareRendererTest, RenderPassVisibleRect) {
351 float device_scale_factor = 1.f;
352 gfx::Rect viewport_rect(0, 0, 100, 100);
353 set_viewport(viewport_rect);
354 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
356 RenderPassList list;
358 SkBitmap output;
359 output.setConfig(SkBitmap::kARGB_8888_Config,
360 viewport_rect.width(),
361 viewport_rect.height());
362 output.allocPixels();
364 // Pass drawn as inner quad is magenta.
365 gfx::Rect smaller_rect(20, 20, 60, 60);
366 RenderPass::Id smaller_pass_id(2, 1);
367 TestRenderPass* smaller_pass =
368 AddRenderPass(&list, smaller_pass_id, smaller_rect, gfx::Transform());
369 AddQuad(smaller_pass, smaller_rect, SK_ColorMAGENTA);
371 // Root pass is green.
372 RenderPass::Id root_clear_pass_id(1, 0);
373 TestRenderPass* root_clear_pass =
374 AddRenderPass(&list, root_clear_pass_id, viewport_rect, gfx::Transform());
375 AddRenderPassQuad(root_clear_pass, smaller_pass);
376 AddQuad(root_clear_pass, viewport_rect, SK_ColorGREEN);
378 // Interior pass quad has smaller visible rect.
379 gfx::Rect interior_visible_rect(30, 30, 40, 40);
380 root_clear_pass->quad_list[0]->visible_rect = interior_visible_rect;
382 renderer()->DecideRenderPassAllocationsForFrame(list);
383 renderer()->DrawFrame(&list, NULL, device_scale_factor, true);
384 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect);
386 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0));
387 EXPECT_EQ(
388 SK_ColorGREEN,
389 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1));
391 // Part outside visible rect should remain green.
392 EXPECT_EQ(SK_ColorGREEN, output.getColor(smaller_rect.x(), smaller_rect.y()));
393 EXPECT_EQ(
394 SK_ColorGREEN,
395 output.getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));
397 EXPECT_EQ(
398 SK_ColorMAGENTA,
399 output.getColor(interior_visible_rect.x(), interior_visible_rect.y()));
400 EXPECT_EQ(SK_ColorMAGENTA,
401 output.getColor(interior_visible_rect.right() - 1,
402 interior_visible_rect.bottom() - 1));
405 } // namespace
406 } // namespace cc