User interface of Apps Developer Tool:
[chromium-blink-merge.git] / cc / output / software_renderer_unittest.cc
blob238d654ac197342955b595776bf84163822bb863
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/geometry_test_utils.h"
17 #include "cc/test/render_pass_test_common.h"
18 #include "cc/test/render_pass_test_utils.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "third_party/skia/include/core/SkCanvas.h"
22 #include "third_party/skia/include/core/SkDevice.h"
24 namespace cc {
25 namespace {
27 class SoftwareRendererTest : public testing::Test, public RendererClient {
28 public:
29 SoftwareRendererTest() : should_clear_root_render_pass_(true) {}
31 void InitializeRenderer(
32 scoped_ptr<SoftwareOutputDevice> software_output_device) {
33 output_surface_ = FakeOutputSurface::CreateSoftware(
34 software_output_device.Pass());
35 resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
36 renderer_ = SoftwareRenderer::Create(
37 this, output_surface_.get(), resource_provider());
40 ResourceProvider* resource_provider() const {
41 return resource_provider_.get();
44 SoftwareRenderer* renderer() const { return renderer_.get(); }
46 void set_viewport(gfx::Rect viewport) {
47 viewport_ = viewport;
50 void set_should_clear_root_render_pass(bool clear_root_render_pass) {
51 should_clear_root_render_pass_ = clear_root_render_pass;
54 // RendererClient implementation.
55 virtual gfx::Rect DeviceViewport() const OVERRIDE {
56 return viewport_;
58 virtual float DeviceScaleFactor() const OVERRIDE {
59 return 1.f;
61 virtual const LayerTreeSettings& Settings() const OVERRIDE {
62 return settings_;
64 virtual void SetFullRootLayerDamage() OVERRIDE {}
65 virtual bool HasImplThread() const OVERRIDE { return false; }
66 virtual bool ShouldClearRootRenderPass() const OVERRIDE {
67 return should_clear_root_render_pass_;
69 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE {
70 return CompositorFrameMetadata();
72 virtual bool AllowPartialSwap() const OVERRIDE {
73 return true;
75 virtual bool ExternalStencilTestEnabled() const OVERRIDE { return false; }
77 protected:
78 scoped_ptr<FakeOutputSurface> output_surface_;
79 scoped_ptr<ResourceProvider> resource_provider_;
80 scoped_ptr<SoftwareRenderer> renderer_;
81 gfx::Rect viewport_;
82 LayerTreeSettings settings_;
83 bool should_clear_root_render_pass_;
86 TEST_F(SoftwareRendererTest, SolidColorQuad) {
87 gfx::Size outer_size(100, 100);
88 gfx::Size inner_size(98, 98);
89 gfx::Rect outer_rect(outer_size);
90 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
91 set_viewport(gfx::Rect(outer_size));
93 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
95 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
96 shared_quad_state->SetAll(
97 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0);
98 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
99 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
100 root_render_pass->SetNew(
101 root_render_pass_id, outer_rect, outer_rect, gfx::Transform());
102 scoped_ptr<SolidColorDrawQuad> outer_quad = SolidColorDrawQuad::Create();
103 outer_quad->SetNew(
104 shared_quad_state.get(), outer_rect, SK_ColorYELLOW, false);
105 scoped_ptr<SolidColorDrawQuad> inner_quad = SolidColorDrawQuad::Create();
106 inner_quad->SetNew(shared_quad_state.get(), inner_rect, SK_ColorCYAN, false);
107 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>());
108 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>());
110 RenderPassList list;
111 list.push_back(root_render_pass.PassAs<RenderPass>());
112 renderer()->DrawFrame(&list);
114 SkBitmap output;
115 output.setConfig(SkBitmap::kARGB_8888_Config,
116 DeviceViewport().width(),
117 DeviceViewport().height());
118 output.allocPixels();
119 renderer()->GetFramebufferPixels(output.getPixels(), outer_rect);
121 EXPECT_EQ(SK_ColorYELLOW, output.getColor(0, 0));
122 EXPECT_EQ(SK_ColorYELLOW,
123 output.getColor(outer_size.width() - 1, outer_size.height() - 1));
124 EXPECT_EQ(SK_ColorCYAN, output.getColor(1, 1));
125 EXPECT_EQ(SK_ColorCYAN,
126 output.getColor(inner_size.width() - 1, inner_size.height() - 1));
129 TEST_F(SoftwareRendererTest, TileQuad) {
130 gfx::Size outer_size(100, 100);
131 gfx::Size inner_size(98, 98);
132 gfx::Rect outer_rect(outer_size);
133 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
134 set_viewport(gfx::Rect(outer_size));
135 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
137 ResourceProvider::ResourceId resource_yellow =
138 resource_provider()->CreateResource(
139 outer_size, GL_RGBA, ResourceProvider::TextureUsageAny);
140 ResourceProvider::ResourceId resource_cyan =
141 resource_provider()->CreateResource(
142 inner_size, GL_RGBA, ResourceProvider::TextureUsageAny);
144 SkBitmap yellow_tile;
145 yellow_tile.setConfig(
146 SkBitmap::kARGB_8888_Config, outer_size.width(), outer_size.height());
147 yellow_tile.allocPixels();
148 yellow_tile.eraseColor(SK_ColorYELLOW);
150 SkBitmap cyan_tile;
151 cyan_tile.setConfig(
152 SkBitmap::kARGB_8888_Config, inner_size.width(), inner_size.height());
153 cyan_tile.allocPixels();
154 cyan_tile.eraseColor(SK_ColorCYAN);
156 resource_provider()->SetPixels(
157 resource_yellow,
158 static_cast<uint8_t*>(yellow_tile.getPixels()),
159 gfx::Rect(outer_size),
160 gfx::Rect(outer_size),
161 gfx::Vector2d());
162 resource_provider()->SetPixels(resource_cyan,
163 static_cast<uint8_t*>(cyan_tile.getPixels()),
164 gfx::Rect(inner_size),
165 gfx::Rect(inner_size),
166 gfx::Vector2d());
168 gfx::Rect root_rect = DeviceViewport();
170 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create();
171 shared_quad_state->SetAll(
172 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0);
173 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1);
174 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
175 root_render_pass->SetNew(
176 root_render_pass_id, root_rect, root_rect, gfx::Transform());
177 scoped_ptr<TileDrawQuad> outer_quad = TileDrawQuad::Create();
178 outer_quad->SetNew(shared_quad_state.get(),
179 outer_rect,
180 outer_rect,
181 resource_yellow,
182 gfx::RectF(outer_size),
183 outer_size,
184 false);
185 scoped_ptr<TileDrawQuad> inner_quad = TileDrawQuad::Create();
186 inner_quad->SetNew(shared_quad_state.get(),
187 inner_rect,
188 inner_rect,
189 resource_cyan,
190 gfx::RectF(inner_size),
191 inner_size,
192 false);
193 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>());
194 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>());
196 RenderPassList list;
197 list.push_back(root_render_pass.PassAs<RenderPass>());
198 renderer()->DrawFrame(&list);
200 SkBitmap output;
201 output.setConfig(SkBitmap::kARGB_8888_Config,
202 DeviceViewport().width(),
203 DeviceViewport().height());
204 output.allocPixels();
205 renderer()->GetFramebufferPixels(output.getPixels(), outer_rect);
207 EXPECT_EQ(SK_ColorYELLOW, output.getColor(0, 0));
208 EXPECT_EQ(SK_ColorYELLOW,
209 output.getColor(outer_size.width() - 1, outer_size.height() - 1));
210 EXPECT_EQ(SK_ColorCYAN, output.getColor(1, 1));
211 EXPECT_EQ(SK_ColorCYAN,
212 output.getColor(inner_size.width() - 1, inner_size.height() - 1));
215 TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
216 gfx::Rect viewport_rect(0, 0, 100, 100);
217 set_viewport(viewport_rect);
218 set_should_clear_root_render_pass(false);
219 InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
221 RenderPassList list;
223 SkBitmap output;
224 output.setConfig(SkBitmap::kARGB_8888_Config,
225 viewport_rect.width(),
226 viewport_rect.height());
227 output.allocPixels();
229 // Draw a fullscreen green quad in a first frame.
230 RenderPass::Id root_clear_pass_id(1, 0);
231 TestRenderPass* root_clear_pass = AddRenderPass(
232 &list, root_clear_pass_id, viewport_rect, gfx::Transform());
233 AddQuad(root_clear_pass, viewport_rect, SK_ColorGREEN);
235 renderer()->DecideRenderPassAllocationsForFrame(list);
236 renderer()->DrawFrame(&list);
237 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect);
239 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0));
240 EXPECT_EQ(SK_ColorGREEN,
241 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1));
243 list.clear();
245 // Draw a smaller magenta rect without filling the viewport in a separate
246 // frame.
247 gfx::Rect smaller_rect(20, 20, 60, 60);
249 RenderPass::Id root_smaller_pass_id(2, 0);
250 TestRenderPass* root_smaller_pass = AddRenderPass(
251 &list, root_smaller_pass_id, viewport_rect, gfx::Transform());
252 AddQuad(root_smaller_pass, smaller_rect, SK_ColorMAGENTA);
254 renderer()->DecideRenderPassAllocationsForFrame(list);
255 renderer()->DrawFrame(&list);
256 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect);
258 // If we didn't clear, the borders should still be green.
259 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0));
260 EXPECT_EQ(SK_ColorGREEN,
261 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1));
263 EXPECT_EQ(SK_ColorMAGENTA,
264 output.getColor(smaller_rect.x(), smaller_rect.y()));
265 EXPECT_EQ(SK_ColorMAGENTA,
266 output.getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));
269 } // namespace
270 } // namespace cc