OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/output/software_renderer.h" | 5 #include "cc/output/software_renderer.h" |
6 | 6 |
7 #include "cc/layers/quad_sink.h" | 7 #include "cc/layers/quad_sink.h" |
8 #include "cc/output/compositor_frame_metadata.h" | 8 #include "cc/output/compositor_frame_metadata.h" |
9 #include "cc/output/software_output_device.h" | 9 #include "cc/output/software_output_device.h" |
10 #include "cc/quads/render_pass.h" | 10 #include "cc/quads/render_pass.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 scoped_ptr<FakeOutputSurface> output_surface_; | 75 scoped_ptr<FakeOutputSurface> output_surface_; |
76 scoped_ptr<ResourceProvider> resource_provider_; | 76 scoped_ptr<ResourceProvider> resource_provider_; |
77 scoped_ptr<SoftwareRenderer> renderer_; | 77 scoped_ptr<SoftwareRenderer> renderer_; |
78 gfx::Size viewport_size_; | 78 gfx::Size viewport_size_; |
79 LayerTreeSettings settings_; | 79 LayerTreeSettings settings_; |
80 bool should_clear_root_render_pass_; | 80 bool should_clear_root_render_pass_; |
81 }; | 81 }; |
82 | 82 |
83 TEST_F(SoftwareRendererTest, SolidColorQuad) { | 83 TEST_F(SoftwareRendererTest, SolidColorQuad) { |
84 gfx::Size outer_size(100, 100); | 84 gfx::Size outer_size(100, 100); |
85 #if !defined(OS_ANDROID) | |
86 int outer_pixels = outer_size.width() * outer_size.height(); | |
87 #endif | |
88 gfx::Size inner_size(98, 98); | 85 gfx::Size inner_size(98, 98); |
89 gfx::Rect outer_rect(outer_size); | 86 gfx::Rect outer_rect(outer_size); |
90 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size); | 87 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size); |
91 set_viewport_size(outer_size); | 88 set_viewport_size(outer_size); |
92 | 89 |
93 InitializeRenderer(); | 90 InitializeRenderer(); |
94 | 91 |
95 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create(); | 92 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create(); |
96 shared_quad_state->SetAll( | 93 shared_quad_state->SetAll( |
97 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0); | 94 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0); |
98 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1); | 95 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1); |
99 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create(); | 96 scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create(); |
100 root_render_pass->SetNew( | 97 root_render_pass->SetNew( |
101 root_render_pass_id, outer_rect, outer_rect, gfx::Transform()); | 98 root_render_pass_id, outer_rect, outer_rect, gfx::Transform()); |
102 scoped_ptr<SolidColorDrawQuad> outer_quad = SolidColorDrawQuad::Create(); | 99 scoped_ptr<SolidColorDrawQuad> outer_quad = SolidColorDrawQuad::Create(); |
103 outer_quad->SetNew( | 100 outer_quad->SetNew( |
104 shared_quad_state.get(), outer_rect, SK_ColorYELLOW, false); | 101 shared_quad_state.get(), outer_rect, SK_ColorYELLOW, false); |
105 scoped_ptr<SolidColorDrawQuad> inner_quad = SolidColorDrawQuad::Create(); | 102 scoped_ptr<SolidColorDrawQuad> inner_quad = SolidColorDrawQuad::Create(); |
106 inner_quad->SetNew(shared_quad_state.get(), inner_rect, SK_ColorCYAN, false); | 103 inner_quad->SetNew(shared_quad_state.get(), inner_rect, SK_ColorCYAN, false); |
107 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>()); | 104 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>()); |
108 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>()); | 105 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>()); |
109 | 106 |
110 RenderPassList list; | 107 RenderPassList list; |
111 list.push_back(root_render_pass.PassAs<RenderPass>()); | 108 list.push_back(root_render_pass.PassAs<RenderPass>()); |
112 renderer()->DrawFrame(&list); | 109 renderer()->DrawFrame(&list); |
113 | 110 |
114 scoped_ptr<SkColor[]> pixels(new SkColor[DeviceViewportSize().width() * | 111 SkBitmap output; |
115 DeviceViewportSize().height()]); | 112 output.setConfig(SkBitmap::kARGB_8888_Config, |
116 renderer()->GetFramebufferPixels(pixels.get(), outer_rect); | 113 DeviceViewportSize().width(), |
| 114 DeviceViewportSize().height()); |
| 115 output.allocPixels(); |
| 116 renderer()->GetFramebufferPixels(output.getPixels(), outer_rect); |
117 | 117 |
118 // FIXME: This fails on Android. Endianness maybe? | 118 EXPECT_EQ(SK_ColorYELLOW, output.getColor(0, 0)); |
119 // Yellow: expects 0xFFFFFF00, was 0xFF00FFFF on android. | 119 EXPECT_EQ(SK_ColorYELLOW, |
120 // Cyan: expects 0xFF00FFFF, was 0xFFFFFF00 on android. | 120 output.getColor(outer_size.width() - 1, outer_size.height() - 1)); |
121 // http://crbug.com/154528 | 121 EXPECT_EQ(SK_ColorCYAN, output.getColor(1, 1)); |
122 #if !defined(OS_ANDROID) | 122 EXPECT_EQ(SK_ColorCYAN, |
123 EXPECT_EQ(SK_ColorYELLOW, pixels[0]); | 123 output.getColor(inner_size.width() - 1, inner_size.height() - 1)); |
124 EXPECT_EQ(SK_ColorYELLOW, pixels[outer_pixels - 1]); | |
125 EXPECT_EQ(SK_ColorCYAN, pixels[outer_size.width() + 1]); | |
126 EXPECT_EQ(SK_ColorCYAN, pixels[outer_pixels - outer_size.width() - 2]); | |
127 #endif | |
128 } | 124 } |
129 | 125 |
130 TEST_F(SoftwareRendererTest, TileQuad) { | 126 TEST_F(SoftwareRendererTest, TileQuad) { |
131 gfx::Size outer_size(100, 100); | 127 gfx::Size outer_size(100, 100); |
132 int outer_pixels = outer_size.width() * outer_size.height(); | |
133 gfx::Size inner_size(98, 98); | 128 gfx::Size inner_size(98, 98); |
134 int inner_pixels = inner_size.width() * inner_size.height(); | |
135 gfx::Rect outer_rect(outer_size); | 129 gfx::Rect outer_rect(outer_size); |
136 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size); | 130 gfx::Rect inner_rect(gfx::Point(1, 1), inner_size); |
137 set_viewport_size(outer_size); | 131 set_viewport_size(outer_size); |
138 InitializeRenderer(); | 132 InitializeRenderer(); |
139 | 133 |
140 ResourceProvider::ResourceId resource_yellow = | 134 ResourceProvider::ResourceId resource_yellow = |
141 resource_provider()->CreateResource( | 135 resource_provider()->CreateResource( |
142 outer_size, GL_RGBA, ResourceProvider::TextureUsageAny); | 136 outer_size, GL_RGBA, ResourceProvider::TextureUsageAny); |
143 ResourceProvider::ResourceId resource_cyan = | 137 ResourceProvider::ResourceId resource_cyan = |
144 resource_provider()->CreateResource( | 138 resource_provider()->CreateResource( |
145 inner_size, GL_RGBA, ResourceProvider::TextureUsageAny); | 139 inner_size, GL_RGBA, ResourceProvider::TextureUsageAny); |
146 | 140 |
147 SkColor yellow = SK_ColorYELLOW; | 141 SkBitmap yellow_tile; |
148 SkColor cyan = SK_ColorCYAN; | 142 yellow_tile.setConfig( |
149 scoped_ptr<SkColor[]> yellow_pixels(new SkColor[outer_pixels]); | 143 SkBitmap::kARGB_8888_Config, outer_size.width(), outer_size.height()); |
150 scoped_ptr<SkColor[]> cyan_pixels(new SkColor[inner_pixels]); | 144 yellow_tile.allocPixels(); |
151 for (int i = 0; i < outer_pixels; i++) | 145 yellow_tile.eraseColor(SK_ColorYELLOW); |
152 yellow_pixels[i] = yellow; | 146 |
153 for (int i = 0; i < inner_pixels; i++) | 147 SkBitmap cyan_tile; |
154 cyan_pixels[i] = cyan; | 148 cyan_tile.setConfig( |
| 149 SkBitmap::kARGB_8888_Config, inner_size.width(), inner_size.height()); |
| 150 cyan_tile.allocPixels(); |
| 151 cyan_tile.eraseColor(SK_ColorCYAN); |
155 | 152 |
156 resource_provider()->SetPixels( | 153 resource_provider()->SetPixels( |
157 resource_yellow, | 154 resource_yellow, |
158 reinterpret_cast<uint8_t*>(yellow_pixels.get()), | 155 static_cast<uint8_t*>(yellow_tile.getPixels()), |
159 gfx::Rect(outer_size), | 156 gfx::Rect(outer_size), |
160 gfx::Rect(outer_size), | 157 gfx::Rect(outer_size), |
161 gfx::Vector2d()); | 158 gfx::Vector2d()); |
162 resource_provider()->SetPixels(resource_cyan, | 159 resource_provider()->SetPixels(resource_cyan, |
163 reinterpret_cast<uint8_t*>(cyan_pixels.get()), | 160 static_cast<uint8_t*>(cyan_tile.getPixels()), |
164 gfx::Rect(inner_size), | 161 gfx::Rect(inner_size), |
165 gfx::Rect(inner_size), | 162 gfx::Rect(inner_size), |
166 gfx::Vector2d()); | 163 gfx::Vector2d()); |
167 | 164 |
168 gfx::Rect root_rect = gfx::Rect(DeviceViewportSize()); | 165 gfx::Rect root_rect = gfx::Rect(DeviceViewportSize()); |
169 | 166 |
170 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create(); | 167 scoped_ptr<SharedQuadState> shared_quad_state = SharedQuadState::Create(); |
171 shared_quad_state->SetAll( | 168 shared_quad_state->SetAll( |
172 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0); | 169 gfx::Transform(), outer_size, outer_rect, outer_rect, false, 1.0); |
173 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1); | 170 RenderPass::Id root_render_pass_id = RenderPass::Id(1, 1); |
(...skipping 16 matching lines...) Expand all Loading... |
190 gfx::RectF(inner_size), | 187 gfx::RectF(inner_size), |
191 inner_size, | 188 inner_size, |
192 false); | 189 false); |
193 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>()); | 190 root_render_pass->AppendQuad(inner_quad.PassAs<DrawQuad>()); |
194 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>()); | 191 root_render_pass->AppendQuad(outer_quad.PassAs<DrawQuad>()); |
195 | 192 |
196 RenderPassList list; | 193 RenderPassList list; |
197 list.push_back(root_render_pass.PassAs<RenderPass>()); | 194 list.push_back(root_render_pass.PassAs<RenderPass>()); |
198 renderer()->DrawFrame(&list); | 195 renderer()->DrawFrame(&list); |
199 | 196 |
200 scoped_ptr<SkColor[]> pixels(new SkColor[DeviceViewportSize().width() * | 197 SkBitmap output; |
201 DeviceViewportSize().height()]); | 198 output.setConfig(SkBitmap::kARGB_8888_Config, |
202 renderer()->GetFramebufferPixels(pixels.get(), outer_rect); | 199 DeviceViewportSize().width(), |
| 200 DeviceViewportSize().height()); |
| 201 output.allocPixels(); |
| 202 renderer()->GetFramebufferPixels(output.getPixels(), outer_rect); |
203 | 203 |
204 EXPECT_EQ(SK_ColorYELLOW, pixels[0]); | 204 EXPECT_EQ(SK_ColorYELLOW, output.getColor(0, 0)); |
205 EXPECT_EQ(SK_ColorYELLOW, pixels[outer_pixels - 1]); | 205 EXPECT_EQ(SK_ColorYELLOW, |
206 EXPECT_EQ(SK_ColorCYAN, pixels[outer_size.width() + 1]); | 206 output.getColor(outer_size.width() - 1, outer_size.height() - 1)); |
207 EXPECT_EQ(SK_ColorCYAN, pixels[outer_pixels - outer_size.width() - 2]); | 207 EXPECT_EQ(SK_ColorCYAN, output.getColor(1, 1)); |
| 208 EXPECT_EQ(SK_ColorCYAN, |
| 209 output.getColor(inner_size.width() - 1, inner_size.height() - 1)); |
208 } | 210 } |
209 | 211 |
210 TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) { | 212 TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) { |
211 gfx::Rect viewport_rect(0, 0, 100, 100); | 213 gfx::Rect viewport_rect(0, 0, 100, 100); |
212 size_t viewport_pixels = viewport_rect.width() * viewport_rect.height(); | |
213 set_viewport_size(viewport_rect.size()); | 214 set_viewport_size(viewport_rect.size()); |
214 set_should_clear_root_render_pass(false); | 215 set_should_clear_root_render_pass(false); |
215 InitializeRenderer(); | 216 InitializeRenderer(); |
216 | 217 |
217 RenderPassList list; | 218 RenderPassList list; |
218 scoped_ptr<SkColor[]> pixels(new SkColor[viewport_pixels]); | 219 |
| 220 SkBitmap output; |
| 221 output.setConfig(SkBitmap::kARGB_8888_Config, |
| 222 viewport_rect.width(), |
| 223 viewport_rect.height()); |
| 224 output.allocPixels(); |
219 | 225 |
220 // Draw a fullscreen green quad in a first frame. | 226 // Draw a fullscreen green quad in a first frame. |
221 RenderPass::Id root_clear_pass_id(1, 0); | 227 RenderPass::Id root_clear_pass_id(1, 0); |
222 TestRenderPass* root_clear_pass = AddRenderPass( | 228 TestRenderPass* root_clear_pass = AddRenderPass( |
223 &list, root_clear_pass_id, viewport_rect, gfx::Transform()); | 229 &list, root_clear_pass_id, viewport_rect, gfx::Transform()); |
224 AddQuad(root_clear_pass, viewport_rect, SK_ColorGREEN); | 230 AddQuad(root_clear_pass, viewport_rect, SK_ColorGREEN); |
225 | 231 |
226 renderer()->DecideRenderPassAllocationsForFrame(list); | 232 renderer()->DecideRenderPassAllocationsForFrame(list); |
227 renderer()->DrawFrame(&list); | 233 renderer()->DrawFrame(&list); |
228 renderer()->GetFramebufferPixels(pixels.get(), viewport_rect); | 234 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect); |
229 | 235 |
230 EXPECT_EQ(SK_ColorGREEN, pixels[0]); | 236 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0)); |
231 EXPECT_EQ(SK_ColorGREEN, pixels[viewport_pixels - 1]); | 237 EXPECT_EQ(SK_ColorGREEN, |
| 238 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1)); |
232 | 239 |
233 list.clear(); | 240 list.clear(); |
234 | 241 |
235 // Draw a smaller magenta rect without filling the viewport in a separate | 242 // Draw a smaller magenta rect without filling the viewport in a separate |
236 // frame. | 243 // frame. |
237 gfx::Rect smaller_rect(20, 20, 60, 60); | 244 gfx::Rect smaller_rect(20, 20, 60, 60); |
238 | 245 |
239 RenderPass::Id root_smaller_pass_id(2, 0); | 246 RenderPass::Id root_smaller_pass_id(2, 0); |
240 TestRenderPass* root_smaller_pass = AddRenderPass( | 247 TestRenderPass* root_smaller_pass = AddRenderPass( |
241 &list, root_smaller_pass_id, viewport_rect, gfx::Transform()); | 248 &list, root_smaller_pass_id, viewport_rect, gfx::Transform()); |
242 AddQuad(root_smaller_pass, smaller_rect, SK_ColorMAGENTA); | 249 AddQuad(root_smaller_pass, smaller_rect, SK_ColorMAGENTA); |
243 | 250 |
244 renderer()->DecideRenderPassAllocationsForFrame(list); | 251 renderer()->DecideRenderPassAllocationsForFrame(list); |
245 renderer()->DrawFrame(&list); | 252 renderer()->DrawFrame(&list); |
246 renderer()->GetFramebufferPixels(pixels.get(), viewport_rect); | 253 renderer()->GetFramebufferPixels(output.getPixels(), viewport_rect); |
247 | 254 |
248 // If we didn't clear, the borders should still be green. | 255 // If we didn't clear, the borders should still be green. |
249 EXPECT_EQ(SK_ColorGREEN, pixels[0]); | 256 EXPECT_EQ(SK_ColorGREEN, output.getColor(0, 0)); |
250 EXPECT_EQ(SK_ColorGREEN, pixels[viewport_pixels - 1]); | 257 EXPECT_EQ(SK_ColorGREEN, |
| 258 output.getColor(viewport_rect.width() - 1, viewport_rect.height() - 1)); |
251 | 259 |
252 EXPECT_EQ( | |
253 SK_ColorMAGENTA, | |
254 pixels[smaller_rect.y() * viewport_rect.width() + smaller_rect.x()]); | |
255 EXPECT_EQ(SK_ColorMAGENTA, | 260 EXPECT_EQ(SK_ColorMAGENTA, |
256 pixels[(smaller_rect.bottom() - 1) * viewport_rect.width() + | 261 output.getColor(smaller_rect.x(), smaller_rect.y())); |
257 smaller_rect.right() - 1]); | 262 EXPECT_EQ(SK_ColorMAGENTA, |
| 263 output.getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1)); |
258 } | 264 } |
259 | 265 |
260 } // namespace | 266 } // namespace |
261 } // namespace cc | 267 } // namespace cc |
OLD | NEW |