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