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. 4 5 #include "base/message_loop/message_loop.h" 6 #include "cc/layers/append_quads_data.h" 7 #include "cc/output/gl_renderer.h" 8 #include "cc/quads/draw_quad.h" 9 #include "cc/quads/picture_draw_quad.h" 10 #include "cc/quads/texture_draw_quad.h" 11 #include "cc/test/fake_picture_pile_impl.h" 12 #include "cc/test/pixel_test.h" 13 #include "gpu/GLES2/gl2extchromium.h" 14 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 15 #include "third_party/skia/include/core/SkImageFilter.h" 16 #include "third_party/skia/include/core/SkMatrix.h" 17 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" 18 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" 19 #include "ui/gfx/rect_conversions.h" 20 21 namespace cc { 22 namespace { 23 24 #if !defined(OS_ANDROID) 25 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id, 26 gfx::Rect rect) { 27 scoped_ptr<RenderPass> pass = RenderPass::Create(); 28 const gfx::Rect output_rect = rect; 29 const gfx::RectF damage_rect = rect; 30 const gfx::Transform transform_to_root_target; 31 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); 32 return pass.Pass(); 33 } 34 35 scoped_ptr<RenderPass> CreateTestRenderPass( 36 RenderPass::Id id, 37 gfx::Rect rect, 38 const gfx::Transform& transform_to_root_target) { 39 scoped_ptr<RenderPass> pass = RenderPass::Create(); 40 const gfx::Rect output_rect = rect; 41 const gfx::RectF damage_rect = rect; 42 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); 43 return pass.Pass(); 44 } 45 46 scoped_ptr<SharedQuadState> CreateTestSharedQuadState( 47 gfx::Transform content_to_target_transform, gfx::Rect rect) { 48 const gfx::Size content_bounds = rect.size(); 49 const gfx::Rect visible_content_rect = rect; 50 const gfx::Rect clip_rect = rect; 51 const bool is_clipped = false; 52 const float opacity = 1.0f; 53 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; 54 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); 55 shared_state->SetAll(content_to_target_transform, 56 content_bounds, 57 visible_content_rect, 58 clip_rect, 59 is_clipped, 60 opacity, 61 blend_mode); 62 return shared_state.Pass(); 63 } 64 65 scoped_ptr<SharedQuadState> CreateTestSharedQuadStateClipped( 66 gfx::Transform content_to_target_transform, 67 gfx::Rect rect, 68 gfx::Rect clip_rect) { 69 const gfx::Size content_bounds = rect.size(); 70 const gfx::Rect visible_content_rect = clip_rect; 71 const bool is_clipped = true; 72 const float opacity = 1.0f; 73 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; 74 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); 75 shared_state->SetAll(content_to_target_transform, 76 content_bounds, 77 visible_content_rect, 78 clip_rect, 79 is_clipped, 80 opacity, 81 blend_mode); 82 return shared_state.Pass(); 83 } 84 85 scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad( 86 SharedQuadState* shared_state, gfx::Rect rect, RenderPass::Id pass_id) { 87 scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); 88 quad->SetNew(shared_state, 89 rect, 90 pass_id, 91 false, // is_replica 92 0, // mask_resource_id 93 rect, // contents_changed_since_last_frame 94 gfx::RectF(1.f, 1.f), // mask_uv_rect 95 FilterOperations(), // foreground filters 96 FilterOperations()); // background filters 97 98 return quad.PassAs<DrawQuad>(); 99 } 100 101 scoped_ptr<TextureDrawQuad> CreateTestTextureDrawQuad( 102 gfx::Rect rect, 103 SkColor texel_color, 104 SkColor background_color, 105 bool premultiplied_alpha, 106 SharedQuadState* shared_state, 107 ResourceProvider* resource_provider) { 108 SkPMColor pixel_color = premultiplied_alpha ? 109 SkPreMultiplyColor(texel_color) : 110 SkPackARGB32NoCheck(SkColorGetA(texel_color), 111 SkColorGetR(texel_color), 112 SkColorGetG(texel_color), 113 SkColorGetB(texel_color)); 114 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color); 115 116 ResourceProvider::ResourceId resource = 117 resource_provider->CreateResource(rect.size(), 118 GL_CLAMP_TO_EDGE, 119 ResourceProvider::TextureUsageAny, 120 RGBA_8888); 121 resource_provider->SetPixels( 122 resource, 123 reinterpret_cast<uint8_t*>(&pixels.front()), 124 rect, 125 rect, 126 gfx::Vector2d()); 127 128 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; 129 130 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); 131 quad->SetNew(shared_state, 132 rect, 133 gfx::Rect(), 134 resource, 135 premultiplied_alpha, 136 gfx::PointF(0.0f, 0.0f), // uv_top_left 137 gfx::PointF(1.0f, 1.0f), // uv_bottom_right 138 background_color, 139 vertex_opacity, 140 false); // flipped 141 return quad.Pass(); 142 } 143 144 typedef ::testing::Types<GLRenderer, 145 SoftwareRenderer, 146 GLRendererWithExpandedViewport, 147 SoftwareRendererWithExpandedViewport> RendererTypes; 148 TYPED_TEST_CASE(RendererPixelTest, RendererTypes); 149 150 // All pixels can be off by one, but any more than that is an error. 151 class FuzzyPixelOffByOneComparator : public FuzzyPixelComparator { 152 public: 153 explicit FuzzyPixelOffByOneComparator(bool discard_alpha) 154 : FuzzyPixelComparator(discard_alpha, 100.f, 0.f, 1.f, 1, 0) {} 155 }; 156 157 template <typename RendererType> 158 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator { 159 public: 160 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha) 161 : fuzzy_(discard_alpha), exact_(discard_alpha) {} 162 163 virtual bool Compare(const SkBitmap& actual_bmp, 164 const SkBitmap& expected_bmp) const; 165 166 private: 167 FuzzyPixelOffByOneComparator fuzzy_; 168 ExactPixelComparator exact_; 169 }; 170 171 template<> 172 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare( 173 const SkBitmap& actual_bmp, 174 const SkBitmap& expected_bmp) const { 175 return fuzzy_.Compare(actual_bmp, expected_bmp); 176 } 177 178 template <> 179 bool FuzzyForSoftwareOnlyPixelComparator< 180 SoftwareRendererWithExpandedViewport>::Compare( 181 const SkBitmap& actual_bmp, 182 const SkBitmap& expected_bmp) const { 183 return fuzzy_.Compare(actual_bmp, expected_bmp); 184 } 185 186 template<typename RendererType> 187 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare( 188 const SkBitmap& actual_bmp, 189 const SkBitmap& expected_bmp) const { 190 return exact_.Compare(actual_bmp, expected_bmp); 191 } 192 193 TYPED_TEST(RendererPixelTest, SimpleGreenRect) { 194 gfx::Rect rect(this->device_viewport_size_); 195 196 RenderPass::Id id(1, 1); 197 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 198 199 scoped_ptr<SharedQuadState> shared_state = 200 CreateTestSharedQuadState(gfx::Transform(), rect); 201 202 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 203 color_quad->SetNew(shared_state.get(), rect, SK_ColorGREEN, false); 204 205 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 206 207 RenderPassList pass_list; 208 pass_list.push_back(pass.Pass()); 209 210 EXPECT_TRUE(this->RunPixelTest( 211 &pass_list, 212 PixelTest::NoOffscreenContext, 213 base::FilePath(FILE_PATH_LITERAL("green.png")), 214 ExactPixelComparator(true))); 215 } 216 217 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) { 218 gfx::Rect rect(this->device_viewport_size_); 219 gfx::Rect small_rect(100, 100); 220 221 RenderPass::Id child_id(2, 1); 222 scoped_ptr<RenderPass> child_pass = 223 CreateTestRenderPass(child_id, small_rect, gfx::Transform()); 224 225 scoped_ptr<SharedQuadState> child_shared_state = 226 CreateTestSharedQuadState(gfx::Transform(), small_rect); 227 228 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 229 color_quad->SetNew(child_shared_state.get(), rect, SK_ColorGREEN, false); 230 child_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 231 232 RenderPass::Id root_id(1, 1); 233 scoped_ptr<RenderPass> root_pass = 234 CreateTestRenderPass(root_id, rect, gfx::Transform()); 235 236 scoped_ptr<SharedQuadState> root_shared_state = 237 CreateTestSharedQuadState(gfx::Transform(), rect); 238 239 scoped_ptr<DrawQuad> render_pass_quad = 240 CreateTestRenderPassDrawQuad(root_shared_state.get(), 241 small_rect, 242 child_id); 243 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>()); 244 245 RenderPass* child_pass_ptr = child_pass.get(); 246 247 RenderPassList pass_list; 248 pass_list.push_back(child_pass.Pass()); 249 pass_list.push_back(root_pass.Pass()); 250 251 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget( 252 &pass_list, 253 child_pass_ptr, 254 PixelTest::NoOffscreenContext, 255 base::FilePath(FILE_PATH_LITERAL("green_small.png")), 256 ExactPixelComparator(true))); 257 } 258 259 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) { 260 gfx::Rect rect(this->device_viewport_size_); 261 262 RenderPass::Id id(1, 1); 263 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 264 265 scoped_ptr<SharedQuadState> shared_state = 266 CreateTestSharedQuadState(gfx::Transform(), rect); 267 268 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad( 269 gfx::Rect(this->device_viewport_size_), 270 SkColorSetARGB(128, 0, 255, 0), // Texel color. 271 SK_ColorTRANSPARENT, // Background color. 272 true, // Premultiplied alpha. 273 shared_state.get(), 274 this->resource_provider_.get()); 275 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>()); 276 277 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 278 color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false); 279 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 280 281 RenderPassList pass_list; 282 pass_list.push_back(pass.Pass()); 283 284 EXPECT_TRUE(this->RunPixelTest( 285 &pass_list, 286 PixelTest::NoOffscreenContext, 287 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), 288 FuzzyPixelOffByOneComparator(true))); 289 } 290 291 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) { 292 gfx::Rect rect(this->device_viewport_size_); 293 294 RenderPass::Id id(1, 1); 295 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 296 297 scoped_ptr<SharedQuadState> texture_quad_state = 298 CreateTestSharedQuadState(gfx::Transform(), rect); 299 texture_quad_state->opacity = 0.8f; 300 301 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad( 302 gfx::Rect(this->device_viewport_size_), 303 SkColorSetARGB(204, 120, 255, 120), // Texel color. 304 SK_ColorGREEN, // Background color. 305 true, // Premultiplied alpha. 306 texture_quad_state.get(), 307 this->resource_provider_.get()); 308 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>()); 309 310 scoped_ptr<SharedQuadState> color_quad_state = 311 CreateTestSharedQuadState(gfx::Transform(), rect); 312 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 313 color_quad->SetNew(color_quad_state.get(), rect, SK_ColorWHITE, false); 314 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 315 316 RenderPassList pass_list; 317 pass_list.push_back(pass.Pass()); 318 319 EXPECT_TRUE(this->RunPixelTest( 320 &pass_list, 321 PixelTest::NoOffscreenContext, 322 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), 323 FuzzyPixelOffByOneComparator(true))); 324 } 325 326 // TODO(skaslev): The software renderer does not support non-premultplied alpha. 327 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) { 328 gfx::Rect rect(this->device_viewport_size_); 329 330 RenderPass::Id id(1, 1); 331 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 332 333 scoped_ptr<SharedQuadState> shared_state = 334 CreateTestSharedQuadState(gfx::Transform(), rect); 335 336 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad( 337 gfx::Rect(this->device_viewport_size_), 338 SkColorSetARGB(128, 0, 255, 0), // Texel color. 339 SK_ColorTRANSPARENT, // Background color. 340 false, // Premultiplied alpha. 341 shared_state.get(), 342 this->resource_provider_.get()); 343 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>()); 344 345 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 346 color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false); 347 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 348 349 RenderPassList pass_list; 350 pass_list.push_back(pass.Pass()); 351 352 EXPECT_TRUE(this->RunPixelTest( 353 &pass_list, 354 PixelTest::NoOffscreenContext, 355 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), 356 FuzzyPixelOffByOneComparator(true))); 357 } 358 359 // TODO(skaslev): The software renderer does not support non-premultplied alpha. 360 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) { 361 gfx::Rect rect(this->device_viewport_size_); 362 363 RenderPass::Id id(1, 1); 364 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 365 366 scoped_ptr<SharedQuadState> texture_quad_state = 367 CreateTestSharedQuadState(gfx::Transform(), rect); 368 texture_quad_state->opacity = 0.8f; 369 370 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad( 371 gfx::Rect(this->device_viewport_size_), 372 SkColorSetARGB(204, 120, 255, 120), // Texel color. 373 SK_ColorGREEN, // Background color. 374 false, // Premultiplied alpha. 375 texture_quad_state.get(), 376 this->resource_provider_.get()); 377 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>()); 378 379 scoped_ptr<SharedQuadState> color_quad_state = 380 CreateTestSharedQuadState(gfx::Transform(), rect); 381 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 382 color_quad->SetNew(color_quad_state.get(), rect, SK_ColorWHITE, false); 383 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 384 385 RenderPassList pass_list; 386 pass_list.push_back(pass.Pass()); 387 388 EXPECT_TRUE(this->RunPixelTest( 389 &pass_list, 390 PixelTest::NoOffscreenContext, 391 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), 392 FuzzyPixelOffByOneComparator(true))); 393 } 394 395 class VideoGLRendererPixelTest : public GLRendererPixelTest { 396 protected: 397 scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad( 398 SharedQuadState* shared_state, bool with_alpha, bool is_transparent) { 399 gfx::Rect rect(this->device_viewport_size_); 400 gfx::Rect opaque_rect(0, 0, 0, 0); 401 402 ResourceProvider::ResourceId y_resource = 403 resource_provider_->CreateResource( 404 this->device_viewport_size_, 405 GL_CLAMP_TO_EDGE, 406 ResourceProvider::TextureUsageAny, 407 LUMINANCE_8); 408 ResourceProvider::ResourceId u_resource = 409 resource_provider_->CreateResource( 410 this->device_viewport_size_, 411 GL_CLAMP_TO_EDGE, 412 ResourceProvider::TextureUsageAny, 413 LUMINANCE_8); 414 ResourceProvider::ResourceId v_resource = 415 resource_provider_->CreateResource( 416 this->device_viewport_size_, 417 GL_CLAMP_TO_EDGE, 418 ResourceProvider::TextureUsageAny, 419 LUMINANCE_8); 420 ResourceProvider::ResourceId a_resource = 0; 421 if (with_alpha) { 422 a_resource = resource_provider_->CreateResource( 423 this->device_viewport_size_, 424 GL_CLAMP_TO_EDGE, 425 ResourceProvider::TextureUsageAny, 426 LUMINANCE_8); 427 } 428 429 int w = this->device_viewport_size_.width(); 430 int h = this->device_viewport_size_.height(); 431 const int y_plane_size = w * h; 432 gfx::Rect uv_rect((w + 1) / 2, (h + 1) / 2); 433 const int uv_plane_size = uv_rect.size().GetArea(); 434 scoped_ptr<uint8_t[]> y_plane(new uint8_t[y_plane_size]); 435 scoped_ptr<uint8_t[]> u_plane(new uint8_t[uv_plane_size]); 436 scoped_ptr<uint8_t[]> v_plane(new uint8_t[uv_plane_size]); 437 scoped_ptr<uint8_t[]> a_plane; 438 if (with_alpha) 439 a_plane.reset(new uint8_t[y_plane_size]); 440 // YUV values representing Green. 441 memset(y_plane.get(), 149, y_plane_size); 442 memset(u_plane.get(), 43, uv_plane_size); 443 memset(v_plane.get(), 21, uv_plane_size); 444 if (with_alpha) 445 memset(a_plane.get(), is_transparent ? 0 : 128, y_plane_size); 446 447 resource_provider_->SetPixels(y_resource, y_plane.get(), rect, rect, 448 gfx::Vector2d()); 449 resource_provider_->SetPixels(u_resource, u_plane.get(), uv_rect, uv_rect, 450 gfx::Vector2d()); 451 resource_provider_->SetPixels(v_resource, v_plane.get(), uv_rect, uv_rect, 452 gfx::Vector2d()); 453 if (with_alpha) { 454 resource_provider_->SetPixels(a_resource, a_plane.get(), rect, rect, 455 gfx::Vector2d()); 456 } 457 458 scoped_ptr<YUVVideoDrawQuad> yuv_quad = YUVVideoDrawQuad::Create(); 459 yuv_quad->SetNew(shared_state, rect, opaque_rect, gfx::Size(), 460 y_resource, u_resource, v_resource, a_resource); 461 return yuv_quad.Pass(); 462 } 463 }; 464 465 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) { 466 gfx::Rect rect(this->device_viewport_size_); 467 468 RenderPass::Id id(1, 1); 469 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 470 471 scoped_ptr<SharedQuadState> shared_state = 472 CreateTestSharedQuadState(gfx::Transform(), rect); 473 474 scoped_ptr<YUVVideoDrawQuad> yuv_quad = 475 CreateTestYUVVideoDrawQuad(shared_state.get(), false, false); 476 477 pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>()); 478 479 RenderPassList pass_list; 480 pass_list.push_back(pass.Pass()); 481 482 EXPECT_TRUE(this->RunPixelTest( 483 &pass_list, 484 PixelTest::NoOffscreenContext, 485 base::FilePath(FILE_PATH_LITERAL("green.png")), 486 ExactPixelComparator(true))); 487 } 488 489 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) { 490 gfx::Rect rect(this->device_viewport_size_); 491 492 RenderPass::Id id(1, 1); 493 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 494 495 scoped_ptr<SharedQuadState> shared_state = 496 CreateTestSharedQuadState(gfx::Transform(), rect); 497 498 scoped_ptr<YUVVideoDrawQuad> yuv_quad = 499 CreateTestYUVVideoDrawQuad(shared_state.get(), true, false); 500 501 pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>()); 502 503 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 504 color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false); 505 506 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 507 508 RenderPassList pass_list; 509 pass_list.push_back(pass.Pass()); 510 511 EXPECT_TRUE(this->RunPixelTest( 512 &pass_list, 513 PixelTest::NoOffscreenContext, 514 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), 515 ExactPixelComparator(true))); 516 } 517 518 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) { 519 gfx::Rect rect(this->device_viewport_size_); 520 521 RenderPass::Id id(1, 1); 522 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 523 524 scoped_ptr<SharedQuadState> shared_state = 525 CreateTestSharedQuadState(gfx::Transform(), rect); 526 527 scoped_ptr<YUVVideoDrawQuad> yuv_quad = 528 CreateTestYUVVideoDrawQuad(shared_state.get(), true, true); 529 530 pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>()); 531 532 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 533 color_quad->SetNew(shared_state.get(), rect, SK_ColorBLACK, false); 534 535 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 536 537 RenderPassList pass_list; 538 pass_list.push_back(pass.Pass()); 539 540 EXPECT_TRUE(this->RunPixelTest( 541 &pass_list, 542 PixelTest::NoOffscreenContext, 543 base::FilePath(FILE_PATH_LITERAL("black.png")), 544 ExactPixelComparator(true))); 545 } 546 547 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { 548 gfx::Rect viewport_rect(this->device_viewport_size_); 549 550 RenderPass::Id root_pass_id(1, 1); 551 scoped_ptr<RenderPass> root_pass = 552 CreateTestRootRenderPass(root_pass_id, viewport_rect); 553 554 RenderPass::Id child_pass_id(2, 2); 555 gfx::Rect pass_rect(this->device_viewport_size_); 556 gfx::Transform transform_to_root; 557 scoped_ptr<RenderPass> child_pass = 558 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 559 560 gfx::Transform content_to_target_transform; 561 scoped_ptr<SharedQuadState> shared_state = 562 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 563 shared_state->opacity = 0.5f; 564 565 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 566 blue->SetNew(shared_state.get(), 567 gfx::Rect(0, 568 0, 569 this->device_viewport_size_.width(), 570 this->device_viewport_size_.height() / 2), 571 SK_ColorBLUE, 572 false); 573 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 574 yellow->SetNew(shared_state.get(), 575 gfx::Rect(0, 576 this->device_viewport_size_.height() / 2, 577 this->device_viewport_size_.width(), 578 this->device_viewport_size_.height() / 2), 579 SK_ColorYELLOW, 580 false); 581 582 scoped_ptr<SharedQuadState> blank_state = 583 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 584 585 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create(); 586 white->SetNew(blank_state.get(), 587 viewport_rect, 588 SK_ColorWHITE, 589 false); 590 591 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 592 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 593 child_pass->quad_list.push_back(white.PassAs<DrawQuad>()); 594 595 scoped_ptr<SharedQuadState> pass_shared_state = 596 CreateTestSharedQuadState(gfx::Transform(), pass_rect); 597 598 SkScalar matrix[20]; 599 float amount = 0.5f; 600 matrix[0] = 0.213f + 0.787f * amount; 601 matrix[1] = 0.715f - 0.715f * amount; 602 matrix[2] = 1.f - (matrix[0] + matrix[1]); 603 matrix[3] = matrix[4] = 0; 604 matrix[5] = 0.213f - 0.213f * amount; 605 matrix[6] = 0.715f + 0.285f * amount; 606 matrix[7] = 1.f - (matrix[5] + matrix[6]); 607 matrix[8] = matrix[9] = 0; 608 matrix[10] = 0.213f - 0.213f * amount; 609 matrix[11] = 0.715f - 0.715f * amount; 610 matrix[12] = 1.f - (matrix[10] + matrix[11]); 611 matrix[13] = matrix[14] = 0; 612 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; 613 matrix[18] = 1; 614 skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef( 615 new SkColorMatrixFilter(matrix))); 616 skia::RefPtr<SkImageFilter> filter = 617 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL)); 618 FilterOperations filters; 619 filters.Append(FilterOperation::CreateReferenceFilter(filter)); 620 621 scoped_ptr<RenderPassDrawQuad> render_pass_quad = 622 RenderPassDrawQuad::Create(); 623 render_pass_quad->SetNew(pass_shared_state.get(), 624 pass_rect, 625 child_pass_id, 626 false, 627 0, 628 pass_rect, 629 gfx::RectF(), 630 filters, 631 FilterOperations()); 632 633 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>()); 634 635 RenderPassList pass_list; 636 pass_list.push_back(child_pass.Pass()); 637 pass_list.push_back(root_pass.Pass()); 638 639 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl 640 // renderer so use a fuzzy comparator. 641 EXPECT_TRUE(this->RunPixelTest( 642 &pass_list, 643 PixelTest::NoOffscreenContext, 644 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), 645 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); 646 } 647 648 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) { 649 gfx::Rect viewport_rect(this->device_viewport_size_); 650 651 RenderPass::Id root_pass_id(1, 1); 652 scoped_ptr<RenderPass> root_pass = 653 CreateTestRootRenderPass(root_pass_id, viewport_rect); 654 655 RenderPass::Id child_pass_id(2, 2); 656 gfx::Rect pass_rect(this->device_viewport_size_); 657 gfx::Transform transform_to_root; 658 scoped_ptr<RenderPass> child_pass = 659 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 660 661 gfx::Transform content_to_target_transform; 662 scoped_ptr<SharedQuadState> shared_state = 663 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 664 shared_state->opacity = 0.5f; 665 666 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 667 blue->SetNew(shared_state.get(), 668 gfx::Rect(0, 669 0, 670 this->device_viewport_size_.width(), 671 this->device_viewport_size_.height() / 2), 672 SK_ColorBLUE, 673 false); 674 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 675 yellow->SetNew(shared_state.get(), 676 gfx::Rect(0, 677 this->device_viewport_size_.height() / 2, 678 this->device_viewport_size_.width(), 679 this->device_viewport_size_.height() / 2), 680 SK_ColorYELLOW, 681 false); 682 683 scoped_ptr<SharedQuadState> blank_state = 684 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 685 686 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create(); 687 white->SetNew(blank_state.get(), 688 viewport_rect, 689 SK_ColorWHITE, 690 false); 691 692 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 693 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 694 child_pass->quad_list.push_back(white.PassAs<DrawQuad>()); 695 696 scoped_ptr<SharedQuadState> pass_shared_state = 697 CreateTestSharedQuadState(gfx::Transform(), pass_rect); 698 699 FilterOperations filters; 700 filters.Append(FilterOperation::CreateSaturateFilter(0.5f)); 701 702 scoped_ptr<RenderPassDrawQuad> render_pass_quad = 703 RenderPassDrawQuad::Create(); 704 render_pass_quad->SetNew(pass_shared_state.get(), 705 pass_rect, 706 child_pass_id, 707 false, 708 0, 709 pass_rect, 710 gfx::RectF(), 711 filters, 712 FilterOperations()); 713 714 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>()); 715 716 RenderPassList pass_list; 717 pass_list.push_back(child_pass.Pass()); 718 pass_list.push_back(root_pass.Pass()); 719 720 EXPECT_TRUE(this->RunPixelTest( 721 &pass_list, 722 PixelTest::NoOffscreenContext, 723 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), 724 ExactPixelComparator(true))); 725 } 726 727 TYPED_TEST(RendererPixelTest, FastPassFilterChain) { 728 gfx::Rect viewport_rect(this->device_viewport_size_); 729 730 RenderPass::Id root_pass_id(1, 1); 731 scoped_ptr<RenderPass> root_pass = 732 CreateTestRootRenderPass(root_pass_id, viewport_rect); 733 734 RenderPass::Id child_pass_id(2, 2); 735 gfx::Rect pass_rect(this->device_viewport_size_); 736 gfx::Transform transform_to_root; 737 scoped_ptr<RenderPass> child_pass = 738 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 739 740 gfx::Transform content_to_target_transform; 741 scoped_ptr<SharedQuadState> shared_state = 742 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 743 shared_state->opacity = 0.5f; 744 745 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 746 blue->SetNew(shared_state.get(), 747 gfx::Rect(0, 748 0, 749 this->device_viewport_size_.width(), 750 this->device_viewport_size_.height() / 2), 751 SK_ColorBLUE, 752 false); 753 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 754 yellow->SetNew(shared_state.get(), 755 gfx::Rect(0, 756 this->device_viewport_size_.height() / 2, 757 this->device_viewport_size_.width(), 758 this->device_viewport_size_.height() / 2), 759 SK_ColorYELLOW, 760 false); 761 762 scoped_ptr<SharedQuadState> blank_state = 763 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 764 765 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create(); 766 white->SetNew(blank_state.get(), 767 viewport_rect, 768 SK_ColorWHITE, 769 false); 770 771 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 772 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 773 child_pass->quad_list.push_back(white.PassAs<DrawQuad>()); 774 775 scoped_ptr<SharedQuadState> pass_shared_state = 776 CreateTestSharedQuadState(gfx::Transform(), pass_rect); 777 778 FilterOperations filters; 779 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f)); 780 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f)); 781 782 scoped_ptr<RenderPassDrawQuad> render_pass_quad = 783 RenderPassDrawQuad::Create(); 784 render_pass_quad->SetNew(pass_shared_state.get(), 785 pass_rect, 786 child_pass_id, 787 false, 788 0, 789 pass_rect, 790 gfx::RectF(), 791 filters, 792 FilterOperations()); 793 794 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>()); 795 796 RenderPassList pass_list; 797 pass_list.push_back(child_pass.Pass()); 798 pass_list.push_back(root_pass.Pass()); 799 800 EXPECT_TRUE(this->RunPixelTest( 801 &pass_list, 802 PixelTest::NoOffscreenContext, 803 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")), 804 ExactPixelComparator(true))); 805 } 806 807 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) { 808 gfx::Rect viewport_rect(this->device_viewport_size_); 809 810 RenderPass::Id root_pass_id(1, 1); 811 scoped_ptr<RenderPass> root_pass = 812 CreateTestRootRenderPass(root_pass_id, viewport_rect); 813 814 RenderPass::Id child_pass_id(2, 2); 815 gfx::Rect pass_rect(this->device_viewport_size_); 816 gfx::Transform transform_to_root; 817 scoped_ptr<RenderPass> child_pass = 818 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 819 820 gfx::Transform content_to_target_transform; 821 scoped_ptr<SharedQuadState> shared_state = 822 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 823 shared_state->opacity = 0.5f; 824 825 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 826 blue->SetNew(shared_state.get(), 827 gfx::Rect(0, 828 0, 829 this->device_viewport_size_.width(), 830 this->device_viewport_size_.height() / 2), 831 SK_ColorBLUE, 832 false); 833 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 834 yellow->SetNew(shared_state.get(), 835 gfx::Rect(0, 836 this->device_viewport_size_.height() / 2, 837 this->device_viewport_size_.width(), 838 this->device_viewport_size_.height() / 2), 839 SK_ColorYELLOW, 840 false); 841 842 scoped_ptr<SharedQuadState> blank_state = 843 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 844 845 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create(); 846 white->SetNew(blank_state.get(), 847 viewport_rect, 848 SK_ColorWHITE, 849 false); 850 851 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 852 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 853 child_pass->quad_list.push_back(white.PassAs<DrawQuad>()); 854 855 scoped_ptr<SharedQuadState> pass_shared_state = 856 CreateTestSharedQuadState(gfx::Transform(), pass_rect); 857 858 SkScalar matrix[20]; 859 float amount = 0.5f; 860 matrix[0] = 0.213f + 0.787f * amount; 861 matrix[1] = 0.715f - 0.715f * amount; 862 matrix[2] = 1.f - (matrix[0] + matrix[1]); 863 matrix[3] = 0; 864 matrix[4] = 20.f; 865 matrix[5] = 0.213f - 0.213f * amount; 866 matrix[6] = 0.715f + 0.285f * amount; 867 matrix[7] = 1.f - (matrix[5] + matrix[6]); 868 matrix[8] = 0; 869 matrix[9] = 200.f; 870 matrix[10] = 0.213f - 0.213f * amount; 871 matrix[11] = 0.715f - 0.715f * amount; 872 matrix[12] = 1.f - (matrix[10] + matrix[11]); 873 matrix[13] = 0; 874 matrix[14] = 1.5f; 875 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; 876 matrix[18] = 1; 877 skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef( 878 new SkColorMatrixFilter(matrix))); 879 skia::RefPtr<SkImageFilter> filter = 880 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL)); 881 FilterOperations filters; 882 filters.Append(FilterOperation::CreateReferenceFilter(filter)); 883 884 scoped_ptr<RenderPassDrawQuad> render_pass_quad = 885 RenderPassDrawQuad::Create(); 886 render_pass_quad->SetNew(pass_shared_state.get(), 887 pass_rect, 888 child_pass_id, 889 false, 890 0, 891 pass_rect, 892 gfx::RectF(), 893 filters, 894 FilterOperations()); 895 896 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>()); 897 RenderPassList pass_list; 898 899 pass_list.push_back(child_pass.Pass()); 900 pass_list.push_back(root_pass.Pass()); 901 902 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl 903 // renderer so use a fuzzy comparator. 904 EXPECT_TRUE(this->RunPixelTest( 905 &pass_list, 906 PixelTest::NoOffscreenContext, 907 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")), 908 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); 909 } 910 911 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) { 912 gfx::Rect viewport_rect(this->device_viewport_size_); 913 914 RenderPass::Id root_pass_id(1, 1); 915 scoped_ptr<RenderPass> root_pass = 916 CreateTestRootRenderPass(root_pass_id, viewport_rect); 917 918 RenderPass::Id child_pass_id(2, 2); 919 gfx::Rect pass_rect(this->device_viewport_size_); 920 gfx::Transform transform_to_root; 921 scoped_ptr<RenderPass> child_pass = 922 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 923 924 gfx::Transform content_to_target_transform; 925 scoped_ptr<SharedQuadState> shared_state = 926 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 927 928 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 929 blue->SetNew(shared_state.get(), 930 gfx::Rect(0, 931 0, 932 this->device_viewport_size_.width(), 933 this->device_viewport_size_.height() / 2), 934 SK_ColorBLUE, 935 false); 936 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 937 yellow->SetNew(shared_state.get(), 938 gfx::Rect(0, 939 this->device_viewport_size_.height() / 2, 940 this->device_viewport_size_.width(), 941 this->device_viewport_size_.height() / 2), 942 SK_ColorYELLOW, 943 false); 944 945 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 946 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 947 948 scoped_ptr<SharedQuadState> pass_shared_state = 949 CreateTestSharedQuadState(gfx::Transform(), pass_rect); 950 root_pass->quad_list.push_back( 951 CreateTestRenderPassDrawQuad(pass_shared_state.get(), 952 pass_rect, 953 child_pass_id)); 954 955 RenderPassList pass_list; 956 pass_list.push_back(child_pass.Pass()); 957 pass_list.push_back(root_pass.Pass()); 958 959 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); 960 961 EXPECT_TRUE(this->RunPixelTest( 962 &pass_list, 963 PixelTest::NoOffscreenContext, 964 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), 965 ExactPixelComparator(true))); 966 } 967 968 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) { 969 gfx::Rect viewport_rect(this->device_viewport_size_); 970 971 RenderPass::Id root_pass_id(1, 1); 972 scoped_ptr<RenderPass> root_pass = 973 CreateTestRootRenderPass(root_pass_id, viewport_rect); 974 975 RenderPass::Id child_pass_id(2, 2); 976 gfx::Rect pass_rect(this->device_viewport_size_); 977 gfx::Transform transform_to_root; 978 scoped_ptr<RenderPass> child_pass = 979 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 980 981 gfx::Transform content_to_target_transform; 982 scoped_ptr<SharedQuadState> shared_state = 983 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 984 985 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 986 blue->SetNew(shared_state.get(), 987 gfx::Rect(0, 988 0, 989 this->device_viewport_size_.width(), 990 this->device_viewport_size_.height() / 2), 991 SK_ColorBLUE, 992 false); 993 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 994 yellow->SetNew(shared_state.get(), 995 gfx::Rect(0, 996 this->device_viewport_size_.height() / 2, 997 this->device_viewport_size_.width(), 998 this->device_viewport_size_.height() / 2), 999 SK_ColorYELLOW, 1000 false); 1001 1002 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1003 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 1004 1005 gfx::Transform aa_transform; 1006 aa_transform.Translate(0.5, 0.0); 1007 1008 scoped_ptr<SharedQuadState> pass_shared_state = 1009 CreateTestSharedQuadState(aa_transform, pass_rect); 1010 root_pass->quad_list.push_back( 1011 CreateTestRenderPassDrawQuad(pass_shared_state.get(), 1012 pass_rect, 1013 child_pass_id)); 1014 1015 scoped_ptr<SharedQuadState> root_shared_state = 1016 CreateTestSharedQuadState(gfx::Transform(), viewport_rect); 1017 scoped_ptr<SolidColorDrawQuad> background = SolidColorDrawQuad::Create(); 1018 background->SetNew(root_shared_state.get(), 1019 gfx::Rect(this->device_viewport_size_), 1020 SK_ColorWHITE, 1021 false); 1022 root_pass->quad_list.push_back(background.PassAs<DrawQuad>()); 1023 1024 RenderPassList pass_list; 1025 pass_list.push_back(child_pass.Pass()); 1026 pass_list.push_back(root_pass.Pass()); 1027 1028 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); 1029 1030 EXPECT_TRUE(this->RunPixelTest( 1031 &pass_list, 1032 PixelTest::NoOffscreenContext, 1033 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")), 1034 FuzzyPixelOffByOneComparator(true))); 1035 } 1036 1037 // This tests the case where we have a RenderPass with a mask, but the quad 1038 // for the masked surface does not include the full surface texture. 1039 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) { 1040 gfx::Rect viewport_rect(this->device_viewport_size_); 1041 1042 RenderPass::Id root_pass_id(1, 1); 1043 scoped_ptr<RenderPass> root_pass = 1044 CreateTestRootRenderPass(root_pass_id, viewport_rect); 1045 scoped_ptr<SharedQuadState> root_pass_shared_state = 1046 CreateTestSharedQuadState(gfx::Transform(), viewport_rect); 1047 1048 RenderPass::Id child_pass_id(2, 2); 1049 gfx::Transform transform_to_root; 1050 scoped_ptr<RenderPass> child_pass = 1051 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); 1052 scoped_ptr<SharedQuadState> child_pass_shared_state = 1053 CreateTestSharedQuadState(gfx::Transform(), viewport_rect); 1054 1055 // The child render pass is just a green box. 1056 static const SkColor kCSSGreen = 0xff008000; 1057 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create(); 1058 green->SetNew(child_pass_shared_state.get(), viewport_rect, kCSSGreen, false); 1059 child_pass->quad_list.push_back(green.PassAs<DrawQuad>()); 1060 1061 // Make a mask. 1062 gfx::Rect mask_rect = viewport_rect; 1063 SkBitmap bitmap; 1064 bitmap.setConfig( 1065 SkBitmap::kARGB_8888_Config, mask_rect.width(), mask_rect.height()); 1066 bitmap.allocPixels(); 1067 SkBitmapDevice bitmap_device(bitmap); 1068 skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(&bitmap_device)); 1069 SkPaint paint; 1070 paint.setStyle(SkPaint::kStroke_Style); 1071 paint.setStrokeWidth(SkIntToScalar(4)); 1072 paint.setColor(SK_ColorWHITE); 1073 canvas->clear(SK_ColorTRANSPARENT); 1074 gfx::Rect rect = mask_rect; 1075 while (!rect.IsEmpty()) { 1076 rect.Inset(6, 6, 4, 4); 1077 canvas->drawRect( 1078 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()), 1079 paint); 1080 rect.Inset(6, 6, 4, 4); 1081 } 1082 1083 ResourceProvider::ResourceId mask_resource_id = 1084 this->resource_provider_->CreateResource( 1085 mask_rect.size(), 1086 GL_CLAMP_TO_EDGE, 1087 ResourceProvider::TextureUsageAny, 1088 RGBA_8888); 1089 { 1090 SkAutoLockPixels lock(bitmap); 1091 this->resource_provider_->SetPixels( 1092 mask_resource_id, 1093 reinterpret_cast<uint8_t*>(bitmap.getPixels()), 1094 mask_rect, 1095 mask_rect, 1096 gfx::Vector2d()); 1097 } 1098 1099 // This RenderPassDrawQuad does not include the full |viewport_rect| which is 1100 // the size of the child render pass. 1101 gfx::Rect sub_rect = gfx::Rect(50, 50, 100, 100); 1102 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x()); 1103 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y()); 1104 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right()); 1105 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom()); 1106 EXPECT_TRUE(child_pass->output_rect.Contains(sub_rect)); 1107 1108 // Set up a mask on the RenderPassDrawQuad. 1109 scoped_ptr<RenderPassDrawQuad> mask_quad = RenderPassDrawQuad::Create(); 1110 mask_quad->SetNew(root_pass_shared_state.get(), 1111 sub_rect, 1112 child_pass_id, 1113 false, // is_replica 1114 mask_resource_id, 1115 sub_rect, // contents_changed_since_last_frame 1116 gfx::RectF(1.f, 1.f), // mask_uv_rect 1117 FilterOperations(), // foreground filters 1118 FilterOperations()); // background filters 1119 root_pass->quad_list.push_back(mask_quad.PassAs<DrawQuad>()); 1120 1121 // White background behind the masked render pass. 1122 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create(); 1123 white->SetNew( 1124 root_pass_shared_state.get(), viewport_rect, SK_ColorWHITE, false); 1125 root_pass->quad_list.push_back(white.PassAs<DrawQuad>()); 1126 1127 RenderPassList pass_list; 1128 pass_list.push_back(child_pass.Pass()); 1129 pass_list.push_back(root_pass.Pass()); 1130 1131 EXPECT_TRUE(this->RunPixelTest( 1132 &pass_list, 1133 PixelTest::NoOffscreenContext, 1134 base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")), 1135 ExactPixelComparator(true))); 1136 } 1137 1138 template <typename RendererType> 1139 class RendererPixelTestWithBackgroundFilter 1140 : public RendererPixelTest<RendererType> { 1141 protected: 1142 void SetUpRenderPassList() { 1143 gfx::Rect device_viewport_rect(this->device_viewport_size_); 1144 1145 RenderPass::Id root_id(1, 1); 1146 scoped_ptr<RenderPass> root_pass = 1147 CreateTestRootRenderPass(root_id, device_viewport_rect); 1148 root_pass->has_transparent_background = false; 1149 1150 gfx::Transform identity_content_to_target_transform; 1151 1152 RenderPass::Id filter_pass_id(2, 1); 1153 gfx::Transform transform_to_root; 1154 scoped_ptr<RenderPass> filter_pass = 1155 CreateTestRenderPass(filter_pass_id, 1156 filter_pass_content_rect_, 1157 transform_to_root); 1158 1159 // A non-visible quad in the filtering render pass. 1160 { 1161 scoped_ptr<SharedQuadState> shared_state = 1162 CreateTestSharedQuadState(identity_content_to_target_transform, 1163 filter_pass_content_rect_); 1164 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 1165 color_quad->SetNew(shared_state.get(), 1166 filter_pass_content_rect_, 1167 SK_ColorTRANSPARENT, 1168 false); 1169 filter_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 1170 filter_pass->shared_quad_state_list.push_back(shared_state.Pass()); 1171 } 1172 1173 { 1174 scoped_ptr<SharedQuadState> shared_state = 1175 CreateTestSharedQuadState(filter_pass_to_target_transform_, 1176 filter_pass_content_rect_); 1177 scoped_ptr<RenderPassDrawQuad> filter_pass_quad = 1178 RenderPassDrawQuad::Create(); 1179 filter_pass_quad->SetNew( 1180 shared_state.get(), 1181 filter_pass_content_rect_, 1182 filter_pass_id, 1183 false, // is_replica 1184 0, // mask_resource_id 1185 filter_pass_content_rect_, // contents_changed_since_last_frame 1186 gfx::RectF(), // mask_uv_rect 1187 FilterOperations(), // filters 1188 this->background_filters_); 1189 root_pass->quad_list.push_back(filter_pass_quad.PassAs<DrawQuad>()); 1190 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); 1191 } 1192 1193 const int kColumnWidth = device_viewport_rect.width() / 3; 1194 1195 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20); 1196 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) { 1197 scoped_ptr<SharedQuadState> shared_state = 1198 CreateTestSharedQuadState(identity_content_to_target_transform, 1199 left_rect); 1200 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 1201 color_quad->SetNew(shared_state.get(), left_rect, SK_ColorGREEN, false); 1202 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 1203 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); 1204 left_rect += gfx::Vector2d(0, left_rect.height() + 1); 1205 } 1206 1207 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20); 1208 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) { 1209 scoped_ptr<SharedQuadState> shared_state = 1210 CreateTestSharedQuadState(identity_content_to_target_transform, 1211 middle_rect); 1212 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 1213 color_quad->SetNew(shared_state.get(), middle_rect, SK_ColorRED, false); 1214 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 1215 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); 1216 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1); 1217 } 1218 1219 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20); 1220 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) { 1221 scoped_ptr<SharedQuadState> shared_state = 1222 CreateTestSharedQuadState(identity_content_to_target_transform, 1223 right_rect); 1224 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); 1225 color_quad->SetNew(shared_state.get(), right_rect, SK_ColorBLUE, false); 1226 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>()); 1227 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); 1228 right_rect += gfx::Vector2d(0, right_rect.height() + 1); 1229 } 1230 1231 scoped_ptr<SharedQuadState> shared_state = 1232 CreateTestSharedQuadState(identity_content_to_target_transform, 1233 device_viewport_rect); 1234 scoped_ptr<SolidColorDrawQuad> background_quad = 1235 SolidColorDrawQuad::Create(); 1236 background_quad->SetNew(shared_state.get(), 1237 device_viewport_rect, 1238 SK_ColorWHITE, 1239 false); 1240 root_pass->quad_list.push_back(background_quad.PassAs<DrawQuad>()); 1241 root_pass->shared_quad_state_list.push_back(shared_state.Pass()); 1242 1243 pass_list_.push_back(filter_pass.Pass()); 1244 pass_list_.push_back(root_pass.Pass()); 1245 } 1246 1247 RenderPassList pass_list_; 1248 FilterOperations background_filters_; 1249 gfx::Transform filter_pass_to_target_transform_; 1250 gfx::Rect filter_pass_content_rect_; 1251 }; 1252 1253 typedef ::testing::Types<GLRenderer, SoftwareRenderer> 1254 BackgroundFilterRendererTypes; 1255 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter, 1256 BackgroundFilterRendererTypes); 1257 1258 typedef RendererPixelTestWithBackgroundFilter<GLRenderer> 1259 GLRendererPixelTestWithBackgroundFilter; 1260 1261 // TODO(skaslev): The software renderer does not support filters yet. 1262 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) { 1263 this->background_filters_.Append( 1264 FilterOperation::CreateInvertFilter(1.f)); 1265 1266 this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_); 1267 this->filter_pass_content_rect_.Inset(12, 14, 16, 18); 1268 1269 this->SetUpRenderPassList(); 1270 EXPECT_TRUE(this->RunPixelTest( 1271 &this->pass_list_, 1272 PixelTest::WithOffscreenContext, 1273 base::FilePath(FILE_PATH_LITERAL("background_filter.png")), 1274 ExactPixelComparator(true))); 1275 } 1276 1277 class ExternalStencilPixelTest : public GLRendererPixelTest { 1278 protected: 1279 void ClearBackgroundToGreen() { 1280 blink::WebGraphicsContext3D* context3d = 1281 output_surface_->context_provider()->Context3d(); 1282 output_surface_->EnsureBackbuffer(); 1283 output_surface_->Reshape(device_viewport_size_, 1); 1284 context3d->clearColor(0.f, 1.f, 0.f, 1.f); 1285 context3d->clear(GL_COLOR_BUFFER_BIT); 1286 } 1287 1288 void PopulateStencilBuffer() { 1289 // Set two quadrants of the stencil buffer to 1. 1290 blink::WebGraphicsContext3D* context3d = 1291 output_surface_->context_provider()->Context3d(); 1292 ASSERT_TRUE(context3d->getContextAttributes().stencil); 1293 output_surface_->EnsureBackbuffer(); 1294 output_surface_->Reshape(device_viewport_size_, 1); 1295 context3d->clearStencil(0); 1296 context3d->clear(GL_STENCIL_BUFFER_BIT); 1297 context3d->enable(GL_SCISSOR_TEST); 1298 context3d->clearStencil(1); 1299 context3d->scissor(0, 1300 0, 1301 device_viewport_size_.width() / 2, 1302 device_viewport_size_.height() / 2); 1303 context3d->clear(GL_STENCIL_BUFFER_BIT); 1304 context3d->scissor(device_viewport_size_.width() / 2, 1305 device_viewport_size_.height() / 2, 1306 device_viewport_size_.width(), 1307 device_viewport_size_.height()); 1308 context3d->clear(GL_STENCIL_BUFFER_BIT); 1309 } 1310 }; 1311 1312 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) { 1313 ClearBackgroundToGreen(); 1314 PopulateStencilBuffer(); 1315 this->EnableExternalStencilTest(); 1316 1317 // Draw a blue quad that covers the entire device viewport. It should be 1318 // clipped to the bottom left and top right corners by the external stencil. 1319 gfx::Rect rect(this->device_viewport_size_); 1320 RenderPass::Id id(1, 1); 1321 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 1322 scoped_ptr<SharedQuadState> blue_shared_state = 1323 CreateTestSharedQuadState(gfx::Transform(), rect); 1324 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 1325 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false); 1326 pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1327 pass->has_transparent_background = false; 1328 RenderPassList pass_list; 1329 pass_list.push_back(pass.Pass()); 1330 1331 EXPECT_TRUE(this->RunPixelTest( 1332 &pass_list, 1333 PixelTest::NoOffscreenContext, 1334 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), 1335 ExactPixelComparator(true))); 1336 } 1337 1338 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) { 1339 PopulateStencilBuffer(); 1340 1341 // Draw a green quad that covers the entire device viewport. The stencil 1342 // buffer should be ignored. 1343 gfx::Rect rect(this->device_viewport_size_); 1344 RenderPass::Id id(1, 1); 1345 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 1346 scoped_ptr<SharedQuadState> green_shared_state = 1347 CreateTestSharedQuadState(gfx::Transform(), rect); 1348 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create(); 1349 green->SetNew(green_shared_state.get(), rect, SK_ColorGREEN, false); 1350 pass->quad_list.push_back(green.PassAs<DrawQuad>()); 1351 RenderPassList pass_list; 1352 pass_list.push_back(pass.Pass()); 1353 1354 EXPECT_TRUE(this->RunPixelTest( 1355 &pass_list, 1356 PixelTest::NoOffscreenContext, 1357 base::FilePath(FILE_PATH_LITERAL("green.png")), 1358 ExactPixelComparator(true))); 1359 } 1360 1361 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) { 1362 // The stencil test should apply only to the final render pass. 1363 ClearBackgroundToGreen(); 1364 PopulateStencilBuffer(); 1365 this->EnableExternalStencilTest(); 1366 1367 gfx::Rect viewport_rect(this->device_viewport_size_); 1368 1369 RenderPass::Id root_pass_id(1, 1); 1370 scoped_ptr<RenderPass> root_pass = 1371 CreateTestRootRenderPass(root_pass_id, viewport_rect); 1372 root_pass->has_transparent_background = false; 1373 1374 RenderPass::Id child_pass_id(2, 2); 1375 gfx::Rect pass_rect(this->device_viewport_size_); 1376 gfx::Transform transform_to_root; 1377 scoped_ptr<RenderPass> child_pass = 1378 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); 1379 1380 gfx::Transform content_to_target_transform; 1381 scoped_ptr<SharedQuadState> shared_state = 1382 CreateTestSharedQuadState(content_to_target_transform, viewport_rect); 1383 1384 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 1385 blue->SetNew(shared_state.get(), 1386 gfx::Rect(0, 1387 0, 1388 this->device_viewport_size_.width(), 1389 this->device_viewport_size_.height()), 1390 SK_ColorBLUE, 1391 false); 1392 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1393 1394 scoped_ptr<SharedQuadState> pass_shared_state = 1395 CreateTestSharedQuadState(gfx::Transform(), pass_rect); 1396 root_pass->quad_list.push_back( 1397 CreateTestRenderPassDrawQuad(pass_shared_state.get(), 1398 pass_rect, 1399 child_pass_id)); 1400 RenderPassList pass_list; 1401 pass_list.push_back(child_pass.Pass()); 1402 pass_list.push_back(root_pass.Pass()); 1403 1404 EXPECT_TRUE(this->RunPixelTest( 1405 &pass_list, 1406 PixelTest::NoOffscreenContext, 1407 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), 1408 ExactPixelComparator(true))); 1409 } 1410 1411 TEST_F(ExternalStencilPixelTest, DeviceClip) { 1412 ClearBackgroundToGreen(); 1413 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50)); 1414 this->ForceDeviceClip(clip_rect); 1415 1416 // Draw a blue quad that covers the entire device viewport. It should be 1417 // clipped to the bottom right corner by the device clip. 1418 gfx::Rect rect(this->device_viewport_size_); 1419 RenderPass::Id id(1, 1); 1420 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 1421 scoped_ptr<SharedQuadState> blue_shared_state = 1422 CreateTestSharedQuadState(gfx::Transform(), rect); 1423 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 1424 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false); 1425 pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1426 RenderPassList pass_list; 1427 pass_list.push_back(pass.Pass()); 1428 1429 EXPECT_TRUE(this->RunPixelTest( 1430 &pass_list, 1431 PixelTest::NoOffscreenContext, 1432 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), 1433 ExactPixelComparator(true))); 1434 } 1435 1436 // Software renderer does not support anti-aliased edges. 1437 TEST_F(GLRendererPixelTest, AntiAliasing) { 1438 gfx::Rect rect(this->device_viewport_size_); 1439 1440 RenderPass::Id id(1, 1); 1441 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 1442 1443 gfx::Transform red_content_to_target_transform; 1444 red_content_to_target_transform.Rotate(10); 1445 scoped_ptr<SharedQuadState> red_shared_state = 1446 CreateTestSharedQuadState(red_content_to_target_transform, rect); 1447 1448 scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create(); 1449 red->SetNew(red_shared_state.get(), rect, SK_ColorRED, false); 1450 1451 pass->quad_list.push_back(red.PassAs<DrawQuad>()); 1452 1453 gfx::Transform yellow_content_to_target_transform; 1454 yellow_content_to_target_transform.Rotate(5); 1455 scoped_ptr<SharedQuadState> yellow_shared_state = 1456 CreateTestSharedQuadState(yellow_content_to_target_transform, rect); 1457 1458 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 1459 yellow->SetNew(yellow_shared_state.get(), rect, SK_ColorYELLOW, false); 1460 1461 pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 1462 1463 gfx::Transform blue_content_to_target_transform; 1464 scoped_ptr<SharedQuadState> blue_shared_state = 1465 CreateTestSharedQuadState(blue_content_to_target_transform, rect); 1466 1467 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 1468 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false); 1469 1470 pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1471 1472 RenderPassList pass_list; 1473 pass_list.push_back(pass.Pass()); 1474 1475 EXPECT_TRUE(this->RunPixelTest( 1476 &pass_list, 1477 PixelTest::NoOffscreenContext, 1478 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")), 1479 FuzzyPixelOffByOneComparator(true))); 1480 } 1481 1482 // This test tests that anti-aliasing works for axis aligned quads. 1483 // Anti-aliasing is only supported in the gl renderer. 1484 TEST_F(GLRendererPixelTest, AxisAligned) { 1485 gfx::Rect rect(this->device_viewport_size_); 1486 1487 RenderPass::Id id(1, 1); 1488 gfx::Transform transform_to_root; 1489 scoped_ptr<RenderPass> pass = 1490 CreateTestRenderPass(id, rect, transform_to_root); 1491 1492 gfx::Transform red_content_to_target_transform; 1493 red_content_to_target_transform.Translate(50, 50); 1494 red_content_to_target_transform.Scale( 1495 0.5f + 1.0f / (rect.width() * 2.0f), 1496 0.5f + 1.0f / (rect.height() * 2.0f)); 1497 scoped_ptr<SharedQuadState> red_shared_state = 1498 CreateTestSharedQuadState(red_content_to_target_transform, rect); 1499 1500 scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create(); 1501 red->SetNew(red_shared_state.get(), rect, SK_ColorRED, false); 1502 1503 pass->quad_list.push_back(red.PassAs<DrawQuad>()); 1504 1505 gfx::Transform yellow_content_to_target_transform; 1506 yellow_content_to_target_transform.Translate(25.5f, 25.5f); 1507 yellow_content_to_target_transform.Scale(0.5f, 0.5f); 1508 scoped_ptr<SharedQuadState> yellow_shared_state = 1509 CreateTestSharedQuadState(yellow_content_to_target_transform, rect); 1510 1511 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create(); 1512 yellow->SetNew(yellow_shared_state.get(), rect, SK_ColorYELLOW, false); 1513 1514 pass->quad_list.push_back(yellow.PassAs<DrawQuad>()); 1515 1516 gfx::Transform blue_content_to_target_transform; 1517 scoped_ptr<SharedQuadState> blue_shared_state = 1518 CreateTestSharedQuadState(blue_content_to_target_transform, rect); 1519 1520 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 1521 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false); 1522 1523 pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1524 1525 RenderPassList pass_list; 1526 pass_list.push_back(pass.Pass()); 1527 1528 EXPECT_TRUE(this->RunPixelTest( 1529 &pass_list, 1530 PixelTest::NoOffscreenContext, 1531 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")), 1532 ExactPixelComparator(true))); 1533 } 1534 1535 // This test tests that forcing anti-aliasing off works as expected. 1536 // Anti-aliasing is only supported in the gl renderer. 1537 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) { 1538 gfx::Rect rect(this->device_viewport_size_); 1539 1540 RenderPass::Id id(1, 1); 1541 gfx::Transform transform_to_root; 1542 scoped_ptr<RenderPass> pass = 1543 CreateTestRenderPass(id, rect, transform_to_root); 1544 1545 gfx::Transform hole_content_to_target_transform; 1546 hole_content_to_target_transform.Translate(50, 50); 1547 hole_content_to_target_transform.Scale( 1548 0.5f + 1.0f / (rect.width() * 2.0f), 1549 0.5f + 1.0f / (rect.height() * 2.0f)); 1550 scoped_ptr<SharedQuadState> hole_shared_state = 1551 CreateTestSharedQuadState(hole_content_to_target_transform, rect); 1552 1553 scoped_ptr<SolidColorDrawQuad> hole = SolidColorDrawQuad::Create(); 1554 hole->SetAll(hole_shared_state.get(), rect, rect, rect, false, 1555 SK_ColorTRANSPARENT, true); 1556 pass->quad_list.push_back(hole.PassAs<DrawQuad>()); 1557 1558 gfx::Transform green_content_to_target_transform; 1559 scoped_ptr<SharedQuadState> green_shared_state = 1560 CreateTestSharedQuadState(green_content_to_target_transform, rect); 1561 1562 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create(); 1563 green->SetNew(green_shared_state.get(), rect, SK_ColorGREEN, false); 1564 1565 pass->quad_list.push_back(green.PassAs<DrawQuad>()); 1566 1567 RenderPassList pass_list; 1568 pass_list.push_back(pass.Pass()); 1569 1570 EXPECT_TRUE(this->RunPixelTest( 1571 &pass_list, 1572 PixelTest::NoOffscreenContext, 1573 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")), 1574 ExactPixelComparator(false))); 1575 } 1576 1577 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) { 1578 gfx::Rect rect(this->device_viewport_size_); 1579 1580 scoped_ptr<RenderPass> pass = 1581 CreateTestRootRenderPass(RenderPass::Id(1, 1), rect); 1582 1583 gfx::Rect red_rect(0, 0, 180, 500); 1584 gfx::Transform red_content_to_target_transform( 1585 1.0f, 2.4520f, 10.6206f, 19.0f, 1586 0.0f, 0.3528f, 5.9737f, 9.5f, 1587 0.0f, -0.2250f, -0.9744f, 0.0f, 1588 0.0f, 0.0225f, 0.0974f, 1.0f); 1589 scoped_ptr<SharedQuadState> red_shared_state = 1590 CreateTestSharedQuadState(red_content_to_target_transform, red_rect); 1591 scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create(); 1592 red->SetNew(red_shared_state.get(), red_rect, SK_ColorRED, false); 1593 pass->quad_list.push_back(red.PassAs<DrawQuad>()); 1594 1595 gfx::Rect green_rect(19, 7, 180, 10); 1596 scoped_ptr<SharedQuadState> green_shared_state = 1597 CreateTestSharedQuadState(gfx::Transform(), green_rect); 1598 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create(); 1599 green->SetNew(green_shared_state.get(), green_rect, SK_ColorGREEN, false); 1600 pass->quad_list.push_back(green.PassAs<DrawQuad>()); 1601 1602 scoped_ptr<SharedQuadState> blue_shared_state = 1603 CreateTestSharedQuadState(gfx::Transform(), rect); 1604 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create(); 1605 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false); 1606 pass->quad_list.push_back(blue.PassAs<DrawQuad>()); 1607 1608 RenderPassList pass_list; 1609 pass_list.push_back(pass.Pass()); 1610 1611 EXPECT_TRUE(this->RunPixelTest( 1612 &pass_list, 1613 PixelTest::NoOffscreenContext, 1614 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")), 1615 FuzzyPixelOffByOneComparator(true))); 1616 } 1617 1618 TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { 1619 gfx::Size pile_tile_size(1000, 1000); 1620 gfx::Rect viewport(this->device_viewport_size_); 1621 // TODO(enne): the renderer should figure this out on its own. 1622 ResourceFormat texture_format = RGBA_8888; 1623 1624 RenderPass::Id id(1, 1); 1625 gfx::Transform transform_to_root; 1626 scoped_ptr<RenderPass> pass = 1627 CreateTestRenderPass(id, viewport, transform_to_root); 1628 1629 // One clipped blue quad in the lower right corner. Outside the clip 1630 // is red, which should not appear. 1631 gfx::Rect blue_rect(gfx::Size(100, 100)); 1632 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50)); 1633 scoped_refptr<FakePicturePileImpl> blue_pile = 1634 FakePicturePileImpl::CreateFilledPile(pile_tile_size, blue_rect.size()); 1635 SkPaint red_paint; 1636 red_paint.setColor(SK_ColorRED); 1637 blue_pile->add_draw_rect_with_paint(blue_rect, red_paint); 1638 SkPaint blue_paint; 1639 blue_paint.setColor(SK_ColorBLUE); 1640 blue_pile->add_draw_rect_with_paint(blue_clip_rect, blue_paint); 1641 blue_pile->RerecordPile(); 1642 1643 gfx::Transform blue_content_to_target_transform; 1644 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right()); 1645 blue_content_to_target_transform.Translate(offset.x(), offset.y()); 1646 gfx::RectF blue_scissor_rect = blue_clip_rect; 1647 blue_content_to_target_transform.TransformRect(&blue_scissor_rect); 1648 scoped_ptr<SharedQuadState> blue_shared_state = 1649 CreateTestSharedQuadStateClipped(blue_content_to_target_transform, 1650 blue_rect, 1651 gfx::ToEnclosingRect(blue_scissor_rect)); 1652 1653 scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create(); 1654 1655 blue_quad->SetNew(blue_shared_state.get(), 1656 viewport, // Intentionally bigger than clip. 1657 gfx::Rect(), 1658 viewport, 1659 viewport.size(), 1660 texture_format, 1661 viewport, 1662 1.f, 1663 blue_pile); 1664 pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); 1665 1666 // One viewport-filling green quad. 1667 scoped_refptr<FakePicturePileImpl> green_pile = 1668 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); 1669 SkPaint green_paint; 1670 green_paint.setColor(SK_ColorGREEN); 1671 green_pile->add_draw_rect_with_paint(viewport, green_paint); 1672 green_pile->RerecordPile(); 1673 1674 gfx::Transform green_content_to_target_transform; 1675 scoped_ptr<SharedQuadState> green_shared_state = 1676 CreateTestSharedQuadState(green_content_to_target_transform, viewport); 1677 1678 scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create(); 1679 green_quad->SetNew(green_shared_state.get(), 1680 viewport, 1681 gfx::Rect(), 1682 gfx::RectF(0.f, 0.f, 1.f, 1.f), 1683 viewport.size(), 1684 texture_format, 1685 viewport, 1686 1.f, 1687 green_pile); 1688 pass->quad_list.push_back(green_quad.PassAs<DrawQuad>()); 1689 1690 RenderPassList pass_list; 1691 pass_list.push_back(pass.Pass()); 1692 1693 EXPECT_TRUE(this->RunPixelTest( 1694 &pass_list, 1695 PixelTest::NoOffscreenContext, 1696 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), 1697 ExactPixelComparator(true))); 1698 } 1699 1700 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity. 1701 TYPED_TEST(RendererPixelTest, PictureDrawQuadOpacity) { 1702 gfx::Size pile_tile_size(1000, 1000); 1703 gfx::Rect viewport(this->device_viewport_size_); 1704 ResourceFormat texture_format = RGBA_8888; 1705 1706 RenderPass::Id id(1, 1); 1707 gfx::Transform transform_to_root; 1708 scoped_ptr<RenderPass> pass = 1709 CreateTestRenderPass(id, viewport, transform_to_root); 1710 1711 // One viewport-filling 0.5-opacity green quad. 1712 scoped_refptr<FakePicturePileImpl> green_pile = 1713 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); 1714 SkPaint green_paint; 1715 green_paint.setColor(SK_ColorGREEN); 1716 green_pile->add_draw_rect_with_paint(viewport, green_paint); 1717 green_pile->RerecordPile(); 1718 1719 gfx::Transform green_content_to_target_transform; 1720 scoped_ptr<SharedQuadState> green_shared_state = 1721 CreateTestSharedQuadState(green_content_to_target_transform, viewport); 1722 green_shared_state->opacity = 0.5f; 1723 1724 scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create(); 1725 green_quad->SetNew(green_shared_state.get(), 1726 viewport, 1727 gfx::Rect(), 1728 gfx::RectF(0, 0, 1, 1), 1729 viewport.size(), 1730 texture_format, 1731 viewport, 1732 1.f, 1733 green_pile); 1734 pass->quad_list.push_back(green_quad.PassAs<DrawQuad>()); 1735 1736 // One viewport-filling white quad. 1737 scoped_refptr<FakePicturePileImpl> white_pile = 1738 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); 1739 SkPaint white_paint; 1740 white_paint.setColor(SK_ColorWHITE); 1741 white_pile->add_draw_rect_with_paint(viewport, white_paint); 1742 white_pile->RerecordPile(); 1743 1744 gfx::Transform white_content_to_target_transform; 1745 scoped_ptr<SharedQuadState> white_shared_state = 1746 CreateTestSharedQuadState(white_content_to_target_transform, viewport); 1747 1748 scoped_ptr<PictureDrawQuad> white_quad = PictureDrawQuad::Create(); 1749 white_quad->SetNew(white_shared_state.get(), 1750 viewport, 1751 gfx::Rect(), 1752 gfx::RectF(0, 0, 1, 1), 1753 viewport.size(), 1754 texture_format, 1755 viewport, 1756 1.f, 1757 white_pile); 1758 pass->quad_list.push_back(white_quad.PassAs<DrawQuad>()); 1759 1760 RenderPassList pass_list; 1761 pass_list.push_back(pass.Pass()); 1762 1763 EXPECT_TRUE(this->RunPixelTest( 1764 &pass_list, 1765 PixelTest::NoOffscreenContext, 1766 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), 1767 FuzzyPixelOffByOneComparator(true))); 1768 } 1769 1770 template<typename TypeParam> bool IsSoftwareRenderer() { 1771 return false; 1772 } 1773 1774 template<> 1775 bool IsSoftwareRenderer<SoftwareRenderer>() { 1776 return true; 1777 } 1778 1779 template<> 1780 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() { 1781 return true; 1782 } 1783 1784 // If we disable image filtering, then a 2x2 bitmap should appear as four 1785 // huge sharp squares. 1786 TYPED_TEST(RendererPixelTest, PictureDrawQuadDisableImageFiltering) { 1787 // We only care about this in software mode since bilinear filtering is 1788 // cheap in hardware. 1789 if (!IsSoftwareRenderer<TypeParam>()) 1790 return; 1791 1792 gfx::Size pile_tile_size(1000, 1000); 1793 gfx::Rect viewport(this->device_viewport_size_); 1794 ResourceFormat texture_format = RGBA_8888; 1795 1796 RenderPass::Id id(1, 1); 1797 gfx::Transform transform_to_root; 1798 scoped_ptr<RenderPass> pass = 1799 CreateTestRenderPass(id, viewport, transform_to_root); 1800 1801 SkBitmap bitmap; 1802 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); 1803 bitmap.allocPixels(); 1804 { 1805 SkAutoLockPixels lock(bitmap); 1806 SkCanvas canvas(bitmap); 1807 canvas.drawPoint(0, 0, SK_ColorGREEN); 1808 canvas.drawPoint(0, 1, SK_ColorBLUE); 1809 canvas.drawPoint(1, 0, SK_ColorBLUE); 1810 canvas.drawPoint(1, 1, SK_ColorGREEN); 1811 } 1812 1813 scoped_refptr<FakePicturePileImpl> pile = 1814 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); 1815 SkPaint paint; 1816 paint.setFilterLevel(SkPaint::kLow_FilterLevel); 1817 pile->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint); 1818 pile->RerecordPile(); 1819 1820 gfx::Transform content_to_target_transform; 1821 scoped_ptr<SharedQuadState> shared_state = 1822 CreateTestSharedQuadState(content_to_target_transform, viewport); 1823 1824 scoped_ptr<PictureDrawQuad> quad = PictureDrawQuad::Create(); 1825 quad->SetNew(shared_state.get(), 1826 viewport, 1827 gfx::Rect(), 1828 gfx::RectF(0, 0, 2, 2), 1829 viewport.size(), 1830 texture_format, 1831 viewport, 1832 1.f, 1833 pile); 1834 pass->quad_list.push_back(quad.PassAs<DrawQuad>()); 1835 1836 RenderPassList pass_list; 1837 pass_list.push_back(pass.Pass()); 1838 1839 this->disable_picture_quad_image_filtering_ = true; 1840 1841 EXPECT_TRUE(this->RunPixelTest( 1842 &pass_list, 1843 PixelTest::NoOffscreenContext, 1844 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), 1845 ExactPixelComparator(true))); 1846 } 1847 1848 TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { 1849 gfx::Size pile_tile_size(1000, 1000); 1850 gfx::Rect viewport(this->device_viewport_size_); 1851 // TODO(enne): the renderer should figure this out on its own. 1852 ResourceFormat texture_format = RGBA_8888; 1853 1854 RenderPass::Id id(1, 1); 1855 gfx::Transform transform_to_root; 1856 scoped_ptr<RenderPass> pass = 1857 CreateTestRenderPass(id, viewport, transform_to_root); 1858 1859 // As scaling up the blue checkerboards will cause sampling on the GPU, 1860 // a few extra "cleanup rects" need to be added to clobber the blending 1861 // to make the output image more clean. This will also test subrects 1862 // of the layer. 1863 gfx::Transform green_content_to_target_transform; 1864 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100)); 1865 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20)); 1866 scoped_refptr<FakePicturePileImpl> green_pile = 1867 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); 1868 SkPaint red_paint; 1869 red_paint.setColor(SK_ColorRED); 1870 green_pile->add_draw_rect_with_paint(viewport, red_paint); 1871 SkPaint green_paint; 1872 green_paint.setColor(SK_ColorGREEN); 1873 green_pile->add_draw_rect_with_paint(green_rect1, green_paint); 1874 green_pile->add_draw_rect_with_paint(green_rect2, green_paint); 1875 green_pile->RerecordPile(); 1876 1877 scoped_ptr<SharedQuadState> top_right_green_shared_quad_state = 1878 CreateTestSharedQuadState(green_content_to_target_transform, viewport); 1879 1880 scoped_ptr<PictureDrawQuad> green_quad1 = PictureDrawQuad::Create(); 1881 green_quad1->SetNew(top_right_green_shared_quad_state.get(), 1882 green_rect1, 1883 gfx::Rect(), 1884 gfx::RectF(green_rect1.size()), 1885 green_rect1.size(), 1886 texture_format, 1887 green_rect1, 1888 1.f, 1889 green_pile); 1890 pass->quad_list.push_back(green_quad1.PassAs<DrawQuad>()); 1891 1892 scoped_ptr<PictureDrawQuad> green_quad2 = PictureDrawQuad::Create(); 1893 green_quad2->SetNew(top_right_green_shared_quad_state.get(), 1894 green_rect2, 1895 gfx::Rect(), 1896 gfx::RectF(green_rect2.size()), 1897 green_rect2.size(), 1898 texture_format, 1899 green_rect2, 1900 1.f, 1901 green_pile); 1902 pass->quad_list.push_back(green_quad2.PassAs<DrawQuad>()); 1903 1904 // Add a green clipped checkerboard in the bottom right to help test 1905 // interleaving picture quad content and solid color content. 1906 gfx::Rect bottom_right_rect( 1907 gfx::Point(viewport.width() / 2, viewport.height() / 2), 1908 gfx::Size(viewport.width() / 2, viewport.height() / 2)); 1909 scoped_ptr<SharedQuadState> bottom_right_green_shared_state = 1910 CreateTestSharedQuadStateClipped( 1911 green_content_to_target_transform, viewport, bottom_right_rect); 1912 scoped_ptr<SolidColorDrawQuad> bottom_right_color_quad = 1913 SolidColorDrawQuad::Create(); 1914 bottom_right_color_quad->SetNew( 1915 bottom_right_green_shared_state.get(), viewport, SK_ColorGREEN, false); 1916 pass->quad_list.push_back(bottom_right_color_quad.PassAs<DrawQuad>()); 1917 1918 // Add two blue checkerboards taking up the bottom left and top right, 1919 // but use content scales as content rects to make this happen. 1920 // The content is at a 4x content scale. 1921 gfx::Rect layer_rect(gfx::Size(20, 30)); 1922 float contents_scale = 4.f; 1923 // Two rects that touch at their corners, arbitrarily placed in the layer. 1924 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f)); 1925 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f)); 1926 gfx::RectF union_layer_rect = blue_layer_rect1; 1927 union_layer_rect.Union(blue_layer_rect2); 1928 1929 // Because scaling up will cause sampling outside the rects, add one extra 1930 // pixel of buffer at the final content scale. 1931 float inset = -1.f / contents_scale; 1932 blue_layer_rect1.Inset(inset, inset, inset, inset); 1933 blue_layer_rect2.Inset(inset, inset, inset, inset); 1934 1935 scoped_refptr<FakePicturePileImpl> pile = 1936 FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size()); 1937 1938 Region outside(layer_rect); 1939 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect)); 1940 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) { 1941 pile->add_draw_rect_with_paint(iter.rect(), red_paint); 1942 } 1943 1944 SkPaint blue_paint; 1945 blue_paint.setColor(SK_ColorBLUE); 1946 pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint); 1947 pile->add_draw_rect_with_paint(blue_layer_rect2, blue_paint); 1948 pile->RerecordPile(); 1949 1950 gfx::Rect content_rect( 1951 gfx::ScaleToEnclosingRect(layer_rect, contents_scale)); 1952 gfx::Rect content_union_rect( 1953 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale))); 1954 1955 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels, 1956 // so scale an additional 10x to make them 100x100. 1957 gfx::Transform content_to_target_transform; 1958 content_to_target_transform.Scale(10.0, 10.0); 1959 gfx::Rect quad_content_rect(gfx::Size(20, 20)); 1960 scoped_ptr<SharedQuadState> blue_shared_state = 1961 CreateTestSharedQuadState(content_to_target_transform, quad_content_rect); 1962 1963 scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create(); 1964 blue_quad->SetNew(blue_shared_state.get(), 1965 quad_content_rect, 1966 gfx::Rect(), 1967 quad_content_rect, 1968 content_union_rect.size(), 1969 texture_format, 1970 content_union_rect, 1971 contents_scale, 1972 pile); 1973 pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); 1974 1975 // Fill left half of viewport with green. 1976 gfx::Transform half_green_content_to_target_transform; 1977 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height())); 1978 scoped_ptr<SharedQuadState> half_green_shared_state = 1979 CreateTestSharedQuadState(half_green_content_to_target_transform, 1980 half_green_rect); 1981 scoped_ptr<SolidColorDrawQuad> half_color_quad = SolidColorDrawQuad::Create(); 1982 half_color_quad->SetNew( 1983 half_green_shared_state.get(), half_green_rect, SK_ColorGREEN, false); 1984 pass->quad_list.push_back(half_color_quad.PassAs<DrawQuad>()); 1985 1986 RenderPassList pass_list; 1987 pass_list.push_back(pass.Pass()); 1988 1989 EXPECT_TRUE(this->RunPixelTest( 1990 &pass_list, 1991 PixelTest::NoOffscreenContext, 1992 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), 1993 ExactPixelComparator(true))); 1994 } 1995 1996 TYPED_TEST(RendererPixelTest, WrapModeRepeat) { 1997 gfx::Rect rect(this->device_viewport_size_); 1998 1999 RenderPass::Id id(1, 1); 2000 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); 2001 2002 scoped_ptr<SharedQuadState> shared_state = 2003 CreateTestSharedQuadState(gfx::Transform(), rect); 2004 2005 gfx::Rect texture_rect(4, 4); 2006 SkPMColor colors[4] = { 2007 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)), 2008 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)), 2009 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)), 2010 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)), 2011 }; 2012 uint32_t pixels[16] = { 2013 colors[0], colors[0], colors[1], colors[1], 2014 colors[0], colors[0], colors[1], colors[1], 2015 colors[2], colors[2], colors[3], colors[3], 2016 colors[2], colors[2], colors[3], colors[3], 2017 }; 2018 ResourceProvider::ResourceId resource = 2019 this->resource_provider_->CreateResource( 2020 texture_rect.size(), 2021 GL_REPEAT, 2022 ResourceProvider::TextureUsageAny, 2023 RGBA_8888); 2024 this->resource_provider_->SetPixels( 2025 resource, 2026 reinterpret_cast<uint8_t*>(pixels), 2027 texture_rect, 2028 texture_rect, 2029 gfx::Vector2d()); 2030 2031 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; 2032 scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create(); 2033 texture_quad->SetNew( 2034 shared_state.get(), 2035 gfx::Rect(this->device_viewport_size_), 2036 gfx::Rect(), 2037 resource, 2038 true, // premultiplied_alpha 2039 gfx::PointF(0.0f, 0.0f), // uv_top_left 2040 gfx::PointF( // uv_bottom_right 2041 this->device_viewport_size_.width() / texture_rect.width(), 2042 this->device_viewport_size_.height() / texture_rect.height()), 2043 SK_ColorWHITE, 2044 vertex_opacity, 2045 false); // flipped 2046 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>()); 2047 2048 RenderPassList pass_list; 2049 pass_list.push_back(pass.Pass()); 2050 2051 EXPECT_TRUE(this->RunPixelTest( 2052 &pass_list, 2053 PixelTest::NoOffscreenContext, 2054 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), 2055 FuzzyPixelOffByOneComparator(true))); 2056 } 2057 2058 #endif // !defined(OS_ANDROID) 2059 2060 } // namespace 2061 } // namespace cc 2062