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