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