1 // Copyright 2014 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/output/compositor_frame.h" 6 #include "cc/quads/render_pass.h" 7 #include "cc/quads/solid_color_draw_quad.h" 8 #include "cc/quads/surface_draw_quad.h" 9 #include "cc/surfaces/surface.h" 10 #include "cc/surfaces/surface_aggregator.h" 11 #include "cc/surfaces/surface_factory.h" 12 #include "cc/surfaces/surface_factory_client.h" 13 #include "cc/surfaces/surface_id_allocator.h" 14 #include "cc/surfaces/surface_manager.h" 15 #include "cc/test/pixel_comparator.h" 16 #include "cc/test/pixel_test.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 #if !defined(OS_ANDROID) 20 21 namespace cc { 22 namespace { 23 24 class EmptySurfaceFactoryClient : public SurfaceFactoryClient { 25 public: 26 virtual void ReturnResources( 27 const ReturnedResourceArray& resources) OVERRIDE {} 28 }; 29 30 class SurfacesPixelTest : public RendererPixelTest<GLRenderer> { 31 public: 32 SurfacesPixelTest() : allocator_(1u), factory_(&manager_, &client_) {} 33 34 protected: 35 SurfaceManager manager_; 36 SurfaceIdAllocator allocator_; 37 EmptySurfaceFactoryClient client_; 38 SurfaceFactory factory_; 39 }; 40 41 SharedQuadState* CreateAndAppendTestSharedQuadState( 42 RenderPass* render_pass, 43 const gfx::Transform& transform, 44 const gfx::Size& size) { 45 const gfx::Size content_bounds = size; 46 const gfx::Rect visible_content_rect = gfx::Rect(size); 47 const gfx::Rect clip_rect = gfx::Rect(size); 48 bool is_clipped = false; 49 float opacity = 1.f; 50 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; 51 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); 52 shared_state->SetAll(transform, 53 content_bounds, 54 visible_content_rect, 55 clip_rect, 56 is_clipped, 57 opacity, 58 blend_mode, 59 0); 60 return shared_state; 61 } 62 63 // Draws a very simple frame with no surface references. 64 TEST_F(SurfacesPixelTest, DrawSimpleFrame) { 65 gfx::Rect rect(device_viewport_size_); 66 RenderPassId id(1, 1); 67 scoped_ptr<RenderPass> pass = RenderPass::Create(); 68 pass->SetNew(id, rect, rect, gfx::Transform()); 69 70 CreateAndAppendTestSharedQuadState( 71 pass.get(), gfx::Transform(), device_viewport_size_); 72 73 SolidColorDrawQuad* color_quad = 74 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 75 bool force_anti_aliasing_off = false; 76 color_quad->SetNew(pass->shared_quad_state_list.back(), 77 rect, 78 rect, 79 SK_ColorGREEN, 80 force_anti_aliasing_off); 81 82 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 83 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 84 85 scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); 86 root_frame->delegated_frame_data = delegated_frame_data.Pass(); 87 88 SurfaceId root_surface_id = allocator_.GenerateId(); 89 factory_.Create(root_surface_id, device_viewport_size_); 90 factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); 91 92 SurfaceAggregator aggregator(&manager_, resource_provider_.get()); 93 scoped_ptr<CompositorFrame> aggregated_frame = 94 aggregator.Aggregate(root_surface_id); 95 factory_.Destroy(root_surface_id); 96 97 bool discard_alpha = false; 98 ExactPixelComparator pixel_comparator(discard_alpha); 99 RenderPassList* pass_list = 100 &aggregated_frame->delegated_frame_data->render_pass_list; 101 EXPECT_TRUE(RunPixelTest(pass_list, 102 base::FilePath(FILE_PATH_LITERAL("green.png")), 103 pixel_comparator)); 104 } 105 106 // Draws a frame with simple surface embedding. 107 TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) { 108 gfx::Size child_size(200, 100); 109 SurfaceId child_surface_id = allocator_.GenerateId(); 110 SurfaceId root_surface_id = allocator_.GenerateId(); 111 factory_.Create(child_surface_id, child_size); 112 factory_.Create(root_surface_id, device_viewport_size_); 113 { 114 gfx::Rect rect(device_viewport_size_); 115 RenderPassId id(1, 1); 116 scoped_ptr<RenderPass> pass = RenderPass::Create(); 117 pass->SetNew(id, rect, rect, gfx::Transform()); 118 119 CreateAndAppendTestSharedQuadState( 120 pass.get(), gfx::Transform(), device_viewport_size_); 121 122 SurfaceDrawQuad* surface_quad = 123 pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); 124 surface_quad->SetNew(pass->shared_quad_state_list.back(), 125 gfx::Rect(child_size), 126 gfx::Rect(child_size), 127 child_surface_id); 128 129 SolidColorDrawQuad* color_quad = 130 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 131 bool force_anti_aliasing_off = false; 132 color_quad->SetNew(pass->shared_quad_state_list.back(), 133 rect, 134 rect, 135 SK_ColorYELLOW, 136 force_anti_aliasing_off); 137 138 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 139 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 140 141 scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); 142 root_frame->delegated_frame_data = delegated_frame_data.Pass(); 143 144 factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); 145 } 146 147 { 148 gfx::Rect rect(child_size); 149 RenderPassId id(1, 1); 150 scoped_ptr<RenderPass> pass = RenderPass::Create(); 151 pass->SetNew(id, rect, rect, gfx::Transform()); 152 153 CreateAndAppendTestSharedQuadState( 154 pass.get(), gfx::Transform(), child_size); 155 156 SolidColorDrawQuad* color_quad = 157 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 158 bool force_anti_aliasing_off = false; 159 color_quad->SetNew(pass->shared_quad_state_list.back(), 160 rect, 161 rect, 162 SK_ColorBLUE, 163 force_anti_aliasing_off); 164 165 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 166 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 167 168 scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); 169 child_frame->delegated_frame_data = delegated_frame_data.Pass(); 170 171 factory_.SubmitFrame(child_surface_id, child_frame.Pass(), base::Closure()); 172 } 173 174 SurfaceAggregator aggregator(&manager_, resource_provider_.get()); 175 scoped_ptr<CompositorFrame> aggregated_frame = 176 aggregator.Aggregate(root_surface_id); 177 178 bool discard_alpha = false; 179 ExactPixelComparator pixel_comparator(discard_alpha); 180 RenderPassList* pass_list = 181 &aggregated_frame->delegated_frame_data->render_pass_list; 182 EXPECT_TRUE(RunPixelTest(pass_list, 183 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), 184 pixel_comparator)); 185 factory_.Destroy(root_surface_id); 186 factory_.Destroy(child_surface_id); 187 } 188 189 // Tests a surface quad that has a non-identity transform into its pass. 190 TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) { 191 gfx::Size child_size(100, 200); 192 gfx::Size quad_size(100, 100); 193 // Structure: 194 // root (200x200) -> left_child (100x200 @ 0x0, 195 // right_child (100x200 @ 0x100) 196 // left_child -> top_green_quad (100x100 @ 0x0), 197 // bottom_blue_quad (100x100 @ 0x100) 198 // right_child -> top_blue_quad (100x100 @ 0x0), 199 // bottom_green_quad (100x100 @ 0x100) 200 SurfaceId left_child_id = allocator_.GenerateId(); 201 SurfaceId right_child_id = allocator_.GenerateId(); 202 SurfaceId root_surface_id = allocator_.GenerateId(); 203 factory_.Create(left_child_id, child_size); 204 factory_.Create(right_child_id, child_size); 205 factory_.Create(root_surface_id, device_viewport_size_); 206 207 { 208 gfx::Rect rect(device_viewport_size_); 209 RenderPassId id(1, 1); 210 scoped_ptr<RenderPass> pass = RenderPass::Create(); 211 pass->SetNew(id, rect, rect, gfx::Transform()); 212 213 gfx::Transform surface_transform; 214 CreateAndAppendTestSharedQuadState( 215 pass.get(), surface_transform, device_viewport_size_); 216 217 SurfaceDrawQuad* left_surface_quad = 218 pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); 219 left_surface_quad->SetNew(pass->shared_quad_state_list.back(), 220 gfx::Rect(child_size), 221 gfx::Rect(child_size), 222 left_child_id); 223 224 surface_transform.Translate(100, 0); 225 CreateAndAppendTestSharedQuadState( 226 pass.get(), surface_transform, device_viewport_size_); 227 228 SurfaceDrawQuad* right_surface_quad = 229 pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); 230 right_surface_quad->SetNew(pass->shared_quad_state_list.back(), 231 gfx::Rect(child_size), 232 gfx::Rect(child_size), 233 right_child_id); 234 235 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 236 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 237 238 scoped_ptr<CompositorFrame> root_frame(new CompositorFrame); 239 root_frame->delegated_frame_data = delegated_frame_data.Pass(); 240 241 factory_.SubmitFrame(root_surface_id, root_frame.Pass(), base::Closure()); 242 } 243 244 { 245 gfx::Rect rect(child_size); 246 RenderPassId id(1, 1); 247 scoped_ptr<RenderPass> pass = RenderPass::Create(); 248 pass->SetNew(id, rect, rect, gfx::Transform()); 249 250 CreateAndAppendTestSharedQuadState( 251 pass.get(), gfx::Transform(), child_size); 252 253 SolidColorDrawQuad* top_color_quad = 254 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 255 bool force_anti_aliasing_off = false; 256 top_color_quad->SetNew(pass->shared_quad_state_list.back(), 257 gfx::Rect(quad_size), 258 gfx::Rect(quad_size), 259 SK_ColorGREEN, 260 force_anti_aliasing_off); 261 262 SolidColorDrawQuad* bottom_color_quad = 263 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 264 bottom_color_quad->SetNew(pass->shared_quad_state_list.back(), 265 gfx::Rect(0, 100, 100, 100), 266 gfx::Rect(0, 100, 100, 100), 267 SK_ColorBLUE, 268 force_anti_aliasing_off); 269 270 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 271 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 272 273 scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); 274 child_frame->delegated_frame_data = delegated_frame_data.Pass(); 275 276 factory_.SubmitFrame(left_child_id, child_frame.Pass(), base::Closure()); 277 } 278 279 { 280 gfx::Rect rect(child_size); 281 RenderPassId id(1, 1); 282 scoped_ptr<RenderPass> pass = RenderPass::Create(); 283 pass->SetNew(id, rect, rect, gfx::Transform()); 284 285 CreateAndAppendTestSharedQuadState( 286 pass.get(), gfx::Transform(), child_size); 287 288 SolidColorDrawQuad* top_color_quad = 289 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 290 bool force_anti_aliasing_off = false; 291 top_color_quad->SetNew(pass->shared_quad_state_list.back(), 292 gfx::Rect(quad_size), 293 gfx::Rect(quad_size), 294 SK_ColorBLUE, 295 force_anti_aliasing_off); 296 297 SolidColorDrawQuad* bottom_color_quad = 298 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 299 bottom_color_quad->SetNew(pass->shared_quad_state_list.back(), 300 gfx::Rect(0, 100, 100, 100), 301 gfx::Rect(0, 100, 100, 100), 302 SK_ColorGREEN, 303 force_anti_aliasing_off); 304 305 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 306 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 307 308 scoped_ptr<CompositorFrame> child_frame(new CompositorFrame); 309 child_frame->delegated_frame_data = delegated_frame_data.Pass(); 310 311 factory_.SubmitFrame(right_child_id, child_frame.Pass(), base::Closure()); 312 } 313 314 SurfaceAggregator aggregator(&manager_, resource_provider_.get()); 315 scoped_ptr<CompositorFrame> aggregated_frame = 316 aggregator.Aggregate(root_surface_id); 317 318 bool discard_alpha = false; 319 ExactPixelComparator pixel_comparator(discard_alpha); 320 RenderPassList* pass_list = 321 &aggregated_frame->delegated_frame_data->render_pass_list; 322 EXPECT_TRUE(RunPixelTest( 323 pass_list, 324 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), 325 pixel_comparator)); 326 327 factory_.Destroy(root_surface_id); 328 factory_.Destroy(left_child_id); 329 factory_.Destroy(right_child_id); 330 } 331 332 } // namespace 333 } // namespace cc 334 335 #endif // !defined(OS_ANDROID) 336