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/gl_renderer.h" | 5 #include "cc/gl_renderer.h" |
6 | 6 |
7 #include "base/file_util.h" | |
8 #include "base/path_service.h" | |
9 #include "cc/compositor_frame_metadata.h" | |
10 #include "cc/draw_quad.h" | 7 #include "cc/draw_quad.h" |
11 #include "cc/prioritized_resource_manager.h" | 8 #include "cc/test/pixel_test.h" |
12 #include "cc/resource_provider.h" | |
13 #include "cc/test/paths.h" | |
14 #include "cc/test/pixel_test_utils.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 #include "ui/gfx/codec/png_codec.h" | |
17 #include "ui/gl/gl_implementation.h" | |
18 #include "webkit/gpu/context_provider_in_process.h" | |
19 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" | |
20 | 9 |
21 namespace cc { | 10 namespace cc { |
22 namespace { | 11 namespace { |
23 | 12 |
24 const int kDeviceViewportWidth = 200; | 13 class GLRendererPixelTest : public PixelTest {}; |
25 const int kDeviceViewportHeight = 200; | |
26 | |
27 class FakeRendererClient : public RendererClient { | |
28 public: | |
29 FakeRendererClient() | |
30 { | |
31 } | |
32 | |
33 // RendererClient methods. | |
34 virtual gfx::Size DeviceViewportSize() const OVERRIDE { | |
35 return gfx::Size(kDeviceViewportWidth, kDeviceViewportHeight); | |
36 } | |
37 virtual const LayerTreeSettings& Settings() const OVERRIDE { | |
38 static LayerTreeSettings fake_settings; | |
39 return fake_settings; | |
40 } | |
41 virtual void DidLoseOutputSurface() OVERRIDE { } | |
42 virtual void OnSwapBuffersComplete() OVERRIDE { } | |
43 virtual void SetFullRootLayerDamage() OVERRIDE { } | |
44 virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy&) OVERRIDE {} | |
45 virtual void EnforceManagedMemoryPolicy( | |
46 const ManagedMemoryPolicy&) OVERRIDE {} | |
47 virtual bool HasImplThread() const OVERRIDE { return false; } | |
48 virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; } | |
49 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const | |
50 OVERRIDE { return CompositorFrameMetadata(); } | |
51 }; | |
52 | |
53 class GLRendererPixelTest : public testing::Test { | |
54 protected: | |
55 GLRendererPixelTest() {} | |
56 | |
57 virtual void SetUp() { | |
58 gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL); | |
59 scoped_ptr<webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl> | |
60 context3d( | |
61 new webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl); | |
62 context3d->Initialize(WebKit::WebGraphicsContext3D::Attributes(), NULL); | |
63 output_surface_.reset(new OutputSurface( | |
64 context3d.PassAs<WebKit::WebGraphicsContext3D>())); | |
65 resource_provider_ = ResourceProvider::Create(output_surface_.get()); | |
66 renderer_ = GLRenderer::Create(&fake_client_, | |
67 output_surface_.get(), | |
68 resource_provider_.get()); | |
69 | |
70 scoped_refptr<cc::ContextProvider> offscreen_contexts = | |
71 new webkit::gpu::ContextProviderInProcess( | |
72 webkit::gpu::ContextProviderInProcess::IN_PROCESS_COMMAND_BUFFER); | |
73 ASSERT_TRUE(offscreen_contexts->InitializeOnMainThread()); | |
74 resource_provider_->SetOffscreenContextProvider(offscreen_contexts); | |
75 } | |
76 | |
77 bool PixelsMatchReference(base::FilePath ref_file) { | |
78 gfx::Rect viewport_rect(kDeviceViewportWidth, kDeviceViewportHeight); | |
79 | |
80 SkBitmap bitmap; | |
81 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
82 viewport_rect.width(), viewport_rect.height()); | |
83 bitmap.allocPixels(); | |
84 unsigned char* pixels = static_cast<unsigned char*>(bitmap.getPixels()); | |
85 renderer_->GetFramebufferPixels(pixels, viewport_rect); | |
86 | |
87 base::FilePath test_data_dir; | |
88 if (!PathService::Get(cc::DIR_TEST_DATA, &test_data_dir)) | |
89 return false; | |
90 | |
91 // To rebaseline: | |
92 //return WritePNGFile(bitmap, test_data_dir.Append(ref_file)); | |
93 | |
94 return IsSameAsPNGFile(bitmap, test_data_dir.Append(ref_file)); | |
95 } | |
96 | |
97 scoped_ptr<OutputSurface> output_surface_; | |
98 FakeRendererClient fake_client_; | |
99 scoped_ptr<ResourceProvider> resource_provider_; | |
100 scoped_ptr<GLRenderer> renderer_; | |
101 }; | |
102 | 14 |
103 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id, | 15 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id, |
104 gfx::Rect rect) { | 16 gfx::Rect rect) { |
105 scoped_ptr<RenderPass> pass = RenderPass::Create(); | 17 scoped_ptr<RenderPass> pass = RenderPass::Create(); |
106 const gfx::Rect output_rect = rect; | 18 const gfx::Rect output_rect = rect; |
107 const gfx::RectF damage_rect = rect; | 19 const gfx::RectF damage_rect = rect; |
108 const gfx::Transform transform_to_root_target; | 20 const gfx::Transform transform_to_root_target; |
109 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); | 21 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); |
110 return pass.Pass(); | 22 return pass.Pass(); |
111 } | 23 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 WebKit::WebFilterOperations(), // foreground filters | 63 WebKit::WebFilterOperations(), // foreground filters |
152 skia::RefPtr<SkImageFilter>(), // foreground filter | 64 skia::RefPtr<SkImageFilter>(), // foreground filter |
153 WebKit::WebFilterOperations()); // background filters | 65 WebKit::WebFilterOperations()); // background filters |
154 | 66 |
155 return quad.PassAs<DrawQuad>(); | 67 return quad.PassAs<DrawQuad>(); |
156 } | 68 } |
157 | 69 |
158 | 70 |
159 #if !defined(OS_ANDROID) | 71 #if !defined(OS_ANDROID) |
160 TEST_F(GLRendererPixelTest, simpleGreenRect) { | 72 TEST_F(GLRendererPixelTest, simpleGreenRect) { |
161 gfx::Rect rect(kDeviceViewportWidth, kDeviceViewportHeight); | 73 gfx::Rect rect(device_viewport_size_); |
162 | 74 |
163 RenderPass::Id id(1, 1); | 75 RenderPass::Id id(1, 1); |
164 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 76 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
165 | 77 |
166 gfx::Transform content_to_target_transform; | 78 gfx::Transform content_to_target_transform; |
167 scoped_ptr<SharedQuadState> shared_state = | 79 scoped_ptr<SharedQuadState> shared_state = |
168 CreateTestSharedQuadState(content_to_target_transform, rect); | 80 CreateTestSharedQuadState(content_to_target_transform, rect); |
169 | 81 |
170 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); | 82 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); |
171 color_quad->SetNew(shared_state.get(), rect, SK_ColorGREEN); | 83 color_quad->SetNew(shared_state.get(), rect, SK_ColorGREEN); |
172 | 84 |
173 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); | 85 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); |
174 | 86 |
175 RenderPassList pass_list; | 87 RenderPassList pass_list; |
176 pass_list.push_back(pass.Pass()); | 88 pass_list.push_back(pass.Pass()); |
177 | 89 |
178 renderer_->DrawFrame(pass_list); | 90 renderer_->DrawFrame(pass_list); |
179 | 91 |
180 EXPECT_TRUE(PixelsMatchReference( | 92 EXPECT_TRUE(PixelsMatchReference( |
181 base::FilePath(FILE_PATH_LITERAL("green.png")))); | 93 base::FilePath(FILE_PATH_LITERAL("green.png")))); |
182 } | 94 } |
183 | 95 |
184 TEST_F(GLRendererPixelTest, RenderPassChangesSize) { | 96 TEST_F(GLRendererPixelTest, RenderPassChangesSize) { |
185 gfx::Rect viewport_rect(kDeviceViewportWidth, kDeviceViewportHeight); | 97 gfx::Rect viewport_rect(device_viewport_size_); |
186 | 98 |
187 RenderPass::Id root_pass_id(1, 1); | 99 RenderPass::Id root_pass_id(1, 1); |
188 scoped_ptr<RenderPass> root_pass = | 100 scoped_ptr<RenderPass> root_pass = |
189 CreateTestRootRenderPass(root_pass_id, viewport_rect); | 101 CreateTestRootRenderPass(root_pass_id, viewport_rect); |
190 | 102 |
191 RenderPass::Id child_pass_id(2, 2); | 103 RenderPass::Id child_pass_id(2, 2); |
192 gfx::Rect pass_rect(kDeviceViewportWidth, kDeviceViewportHeight); | 104 gfx::Rect pass_rect(device_viewport_size_); |
193 gfx::Transform transform_to_root; | 105 gfx::Transform transform_to_root; |
194 scoped_ptr<RenderPass> child_pass = | 106 scoped_ptr<RenderPass> child_pass = |
195 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 107 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); |
196 | 108 |
197 gfx::Transform content_to_target_transform; | 109 gfx::Transform content_to_target_transform; |
198 scoped_ptr<SharedQuadState> shared_state = | 110 scoped_ptr<SharedQuadState> shared_state = |
199 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); | 111 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); |
200 | 112 |
201 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); | 113 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); |
202 blue->SetNew(shared_state.get(), | 114 blue->SetNew(shared_state.get(), |
203 gfx::Rect(0, | 115 gfx::Rect(0, |
204 0, | 116 0, |
205 kDeviceViewportWidth / 2, | 117 device_viewport_size_.width() / 2, |
206 kDeviceViewportHeight), | 118 device_viewport_size_.height()), |
207 SK_ColorBLUE); | 119 SK_ColorBLUE); |
208 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); | 120 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); |
209 yellow->SetNew(shared_state.get(), | 121 yellow->SetNew(shared_state.get(), |
210 gfx::Rect(kDeviceViewportWidth / 2, | 122 gfx::Rect(device_viewport_size_.width() / 2, |
211 0, | 123 0, |
212 kDeviceViewportWidth / 2, | 124 device_viewport_size_.width() / 2, |
213 kDeviceViewportHeight), | 125 device_viewport_size_.height()), |
214 SK_ColorYELLOW); | 126 SK_ColorYELLOW); |
215 | 127 |
216 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); | 128 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); |
217 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); | 129 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); |
218 | 130 |
219 scoped_ptr<SharedQuadState> pass_shared_state = | 131 scoped_ptr<SharedQuadState> pass_shared_state = |
220 CreateTestSharedQuadState(gfx::Transform(), pass_rect); | 132 CreateTestSharedQuadState(gfx::Transform(), pass_rect); |
221 root_pass->quad_list.push_back( | 133 root_pass->quad_list.push_back( |
222 CreateTestRenderPassDrawQuad(pass_shared_state.get(), | 134 CreateTestRenderPassDrawQuad(pass_shared_state.get(), |
223 pass_rect, | 135 pass_rect, |
224 child_pass_id)); | 136 child_pass_id)); |
225 | 137 |
226 RenderPassList pass_list; | 138 RenderPassList pass_list; |
227 pass_list.push_back(child_pass.Pass()); | 139 pass_list.push_back(child_pass.Pass()); |
228 pass_list.push_back(root_pass.Pass()); | 140 pass_list.push_back(root_pass.Pass()); |
229 | 141 |
230 renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); | 142 renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); |
231 renderer_->DecideRenderPassAllocationsForFrame(pass_list); | 143 renderer_->DecideRenderPassAllocationsForFrame(pass_list); |
232 renderer_->DrawFrame(pass_list); | 144 renderer_->DrawFrame(pass_list); |
233 | 145 |
234 EXPECT_TRUE(PixelsMatchReference( | 146 EXPECT_TRUE(PixelsMatchReference( |
235 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")))); | 147 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")))); |
236 } | 148 } |
237 | 149 |
238 class GLRendererPixelTestWithBackgroundFilter : public GLRendererPixelTest { | 150 class GLRendererPixelTestWithBackgroundFilter : public GLRendererPixelTest { |
239 protected: | 151 protected: |
240 void DrawFrame() { | 152 void DrawFrame() { |
241 gfx::Rect device_viewport_rect(kDeviceViewportWidth, kDeviceViewportHeight); | 153 gfx::Rect device_viewport_rect(device_viewport_size_); |
242 | 154 |
243 RenderPass::Id root_id(1, 1); | 155 RenderPass::Id root_id(1, 1); |
244 scoped_ptr<RenderPass> root_pass = | 156 scoped_ptr<RenderPass> root_pass = |
245 CreateTestRootRenderPass(root_id, device_viewport_rect); | 157 CreateTestRootRenderPass(root_id, device_viewport_rect); |
246 root_pass->has_transparent_background = false; | 158 root_pass->has_transparent_background = false; |
247 | 159 |
248 gfx::Transform identity_content_to_target_transform; | 160 gfx::Transform identity_content_to_target_transform; |
249 | 161 |
250 RenderPass::Id filter_pass_id(2, 1); | 162 RenderPass::Id filter_pass_id(2, 1); |
251 gfx::Transform transform_to_root; | 163 gfx::Transform transform_to_root; |
(...skipping 29 matching lines...) Expand all Loading... |
281 0, // mask_resource_id | 193 0, // mask_resource_id |
282 filter_pass_content_rect_, // contents_changed_since_last_frame | 194 filter_pass_content_rect_, // contents_changed_since_last_frame |
283 gfx::RectF(), // mask_uv_rect | 195 gfx::RectF(), // mask_uv_rect |
284 WebKit::WebFilterOperations(), // filters | 196 WebKit::WebFilterOperations(), // filters |
285 skia::RefPtr<SkImageFilter>(), // filter | 197 skia::RefPtr<SkImageFilter>(), // filter |
286 background_filters_); | 198 background_filters_); |
287 root_pass->quad_list.push_back(filter_pass_quad.PassAs<DrawQuad>()); | 199 root_pass->quad_list.push_back(filter_pass_quad.PassAs<DrawQuad>()); |
288 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); | 200 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); |
289 } | 201 } |
290 | 202 |
291 const int kColumnWidth = kDeviceViewportWidth / 3; | 203 const int kColumnWidth = device_viewport_rect.width() / 3; |
292 | 204 |
293 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20); | 205 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20); |
294 for (int i = 0; left_rect.y() < kDeviceViewportHeight; ++i) { | 206 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) { |
295 scoped_ptr<SharedQuadState> shared_state = | 207 scoped_ptr<SharedQuadState> shared_state = |
296 CreateTestSharedQuadState(identity_content_to_target_transform, | 208 CreateTestSharedQuadState(identity_content_to_target_transform, |
297 left_rect); | 209 left_rect); |
298 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); | 210 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); |
299 color_quad->SetNew(shared_state.get(), left_rect, SK_ColorGREEN); | 211 color_quad->SetNew(shared_state.get(), left_rect, SK_ColorGREEN); |
300 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); | 212 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); |
301 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); | 213 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); |
302 left_rect += gfx::Vector2d(0, left_rect.height() + 1); | 214 left_rect += gfx::Vector2d(0, left_rect.height() + 1); |
303 } | 215 } |
304 | 216 |
305 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20); | 217 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20); |
306 for (int i = 0; middle_rect.y() < kDeviceViewportHeight; ++i) { | 218 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) { |
307 scoped_ptr<SharedQuadState> shared_state = | 219 scoped_ptr<SharedQuadState> shared_state = |
308 CreateTestSharedQuadState(identity_content_to_target_transform, | 220 CreateTestSharedQuadState(identity_content_to_target_transform, |
309 middle_rect); | 221 middle_rect); |
310 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); | 222 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); |
311 color_quad->SetNew(shared_state.get(), middle_rect, SK_ColorRED); | 223 color_quad->SetNew(shared_state.get(), middle_rect, SK_ColorRED); |
312 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); | 224 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); |
313 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); | 225 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); |
314 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1); | 226 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1); |
315 } | 227 } |
316 | 228 |
317 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20); | 229 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20); |
318 for (int i = 0; right_rect.y() < kDeviceViewportHeight; ++i) { | 230 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) { |
319 scoped_ptr<SharedQuadState> shared_state = | 231 scoped_ptr<SharedQuadState> shared_state = |
320 CreateTestSharedQuadState(identity_content_to_target_transform, | 232 CreateTestSharedQuadState(identity_content_to_target_transform, |
321 right_rect); | 233 right_rect); |
322 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); | 234 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); |
323 color_quad->SetNew(shared_state.get(), right_rect, SK_ColorBLUE); | 235 color_quad->SetNew(shared_state.get(), right_rect, SK_ColorBLUE); |
324 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); | 236 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); |
325 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); | 237 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); |
326 right_rect += gfx::Vector2d(0, right_rect.height() + 1); | 238 right_rect += gfx::Vector2d(0, right_rect.height() + 1); |
327 } | 239 } |
328 | 240 |
(...skipping 18 matching lines...) Expand all Loading... |
347 | 259 |
348 WebKit::WebFilterOperations background_filters_; | 260 WebKit::WebFilterOperations background_filters_; |
349 gfx::Transform filter_pass_to_target_transform_; | 261 gfx::Transform filter_pass_to_target_transform_; |
350 gfx::Rect filter_pass_content_rect_; | 262 gfx::Rect filter_pass_content_rect_; |
351 }; | 263 }; |
352 | 264 |
353 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) { | 265 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) { |
354 background_filters_.append( | 266 background_filters_.append( |
355 WebKit::WebFilterOperation::createInvertFilter(1.f)); | 267 WebKit::WebFilterOperation::createInvertFilter(1.f)); |
356 | 268 |
357 filter_pass_content_rect_ = | 269 filter_pass_content_rect_ = gfx::Rect(device_viewport_size_); |
358 gfx::Rect(kDeviceViewportWidth, kDeviceViewportHeight); | |
359 filter_pass_content_rect_.Inset(12, 14, 16, 18); | 270 filter_pass_content_rect_.Inset(12, 14, 16, 18); |
360 | 271 |
361 DrawFrame(); | 272 DrawFrame(); |
362 EXPECT_TRUE(PixelsMatchReference( | 273 EXPECT_TRUE(PixelsMatchReference( |
363 base::FilePath(FILE_PATH_LITERAL("background_filter.png")))); | 274 base::FilePath(FILE_PATH_LITERAL("background_filter.png")))); |
364 } | 275 } |
365 #endif | 276 #endif |
366 | 277 |
367 } // namespace | 278 } // namespace |
368 } // namespace cc | 279 } // namespace cc |
OLD | NEW |