| // Copyright 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/message_loop/message_loop.h" | 
 | #include "cc/layers/append_quads_data.h" | 
 | #include "cc/output/gl_renderer.h" | 
 | #include "cc/quads/draw_quad.h" | 
 | #include "cc/quads/picture_draw_quad.h" | 
 | #include "cc/quads/texture_draw_quad.h" | 
 | #include "cc/resources/video_resource_updater.h" | 
 | #include "cc/test/fake_picture_pile_impl.h" | 
 | #include "cc/test/pixel_test.h" | 
 | #include "gpu/command_buffer/client/gles2_interface.h" | 
 | #include "third_party/skia/include/core/SkColorPriv.h" | 
 | #include "third_party/skia/include/core/SkImageFilter.h" | 
 | #include "third_party/skia/include/core/SkMatrix.h" | 
 | #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" | 
 | #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 
 | #include "ui/gfx/geometry/rect_conversions.h" | 
 |  | 
 | using gpu::gles2::GLES2Interface; | 
 |  | 
 | namespace cc { | 
 | namespace { | 
 |  | 
 | #if !defined(OS_ANDROID) | 
 | scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id, | 
 |                                                 const gfx::Rect& rect) { | 
 |   scoped_ptr<RenderPass> pass = RenderPass::Create(); | 
 |   const gfx::Rect output_rect = rect; | 
 |   const gfx::Rect damage_rect = rect; | 
 |   const gfx::Transform transform_to_root_target; | 
 |   pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); | 
 |   return pass.Pass(); | 
 | } | 
 |  | 
 | scoped_ptr<RenderPass> CreateTestRenderPass( | 
 |     RenderPassId id, | 
 |     const gfx::Rect& rect, | 
 |     const gfx::Transform& transform_to_root_target) { | 
 |   scoped_ptr<RenderPass> pass = RenderPass::Create(); | 
 |   const gfx::Rect output_rect = rect; | 
 |   const gfx::Rect damage_rect = rect; | 
 |   pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); | 
 |   return pass.Pass(); | 
 | } | 
 |  | 
 | SharedQuadState* CreateTestSharedQuadState( | 
 |     gfx::Transform content_to_target_transform, | 
 |     const gfx::Rect& rect, | 
 |     RenderPass* render_pass) { | 
 |   const gfx::Size content_bounds = rect.size(); | 
 |   const gfx::Rect visible_content_rect = rect; | 
 |   const gfx::Rect clip_rect = rect; | 
 |   const bool is_clipped = false; | 
 |   const float opacity = 1.0f; | 
 |   const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; | 
 |   int sorting_context_id = 0; | 
 |   SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); | 
 |   shared_state->SetAll(content_to_target_transform, | 
 |                        content_bounds, | 
 |                        visible_content_rect, | 
 |                        clip_rect, | 
 |                        is_clipped, | 
 |                        opacity, | 
 |                        blend_mode, | 
 |                        sorting_context_id); | 
 |   return shared_state; | 
 | } | 
 |  | 
 | SharedQuadState* CreateTestSharedQuadStateClipped( | 
 |     gfx::Transform content_to_target_transform, | 
 |     const gfx::Rect& rect, | 
 |     const gfx::Rect& clip_rect, | 
 |     RenderPass* render_pass) { | 
 |   const gfx::Size content_bounds = rect.size(); | 
 |   const gfx::Rect visible_content_rect = clip_rect; | 
 |   const bool is_clipped = true; | 
 |   const float opacity = 1.0f; | 
 |   const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; | 
 |   int sorting_context_id = 0; | 
 |   SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); | 
 |   shared_state->SetAll(content_to_target_transform, | 
 |                        content_bounds, | 
 |                        visible_content_rect, | 
 |                        clip_rect, | 
 |                        is_clipped, | 
 |                        opacity, | 
 |                        blend_mode, | 
 |                        sorting_context_id); | 
 |   return shared_state; | 
 | } | 
 |  | 
 | void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state, | 
 |                                   const gfx::Rect& rect, | 
 |                                   RenderPassId pass_id, | 
 |                                   RenderPass* render_pass) { | 
 |   RenderPassDrawQuad* quad = | 
 |       render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |   quad->SetNew(shared_state, | 
 |                rect, | 
 |                rect, | 
 |                pass_id, | 
 |                0,                    // mask_resource_id | 
 |                gfx::Vector2dF(),     // mask_uv_scale | 
 |                gfx::Size(),          // mask_texture_size | 
 |                FilterOperations(),   // foreground filters | 
 |                gfx::Vector2dF(),     // filters scale | 
 |                FilterOperations());  // background filters | 
 | } | 
 |  | 
 | void CreateTestTextureDrawQuad(const gfx::Rect& rect, | 
 |                                SkColor texel_color, | 
 |                                SkColor background_color, | 
 |                                bool premultiplied_alpha, | 
 |                                const SharedQuadState* shared_state, | 
 |                                ResourceProvider* resource_provider, | 
 |                                RenderPass* render_pass) { | 
 |   SkPMColor pixel_color = premultiplied_alpha ? | 
 |       SkPreMultiplyColor(texel_color) : | 
 |       SkPackARGB32NoCheck(SkColorGetA(texel_color), | 
 |                           SkColorGetR(texel_color), | 
 |                           SkColorGetG(texel_color), | 
 |                           SkColorGetB(texel_color)); | 
 |   std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color); | 
 |  | 
 |   ResourceProvider::ResourceId resource = | 
 |       resource_provider->CreateResource(rect.size(), | 
 |                                         GL_CLAMP_TO_EDGE, | 
 |                                         ResourceProvider::TextureHintImmutable, | 
 |                                         RGBA_8888); | 
 |   resource_provider->SetPixels( | 
 |       resource, | 
 |       reinterpret_cast<uint8_t*>(&pixels.front()), | 
 |       rect, | 
 |       rect, | 
 |       gfx::Vector2d()); | 
 |  | 
 |   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | 
 |  | 
 |   TextureDrawQuad* quad = | 
 |       render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | 
 |   quad->SetNew(shared_state, | 
 |                rect, | 
 |                gfx::Rect(), | 
 |                rect, | 
 |                resource, | 
 |                premultiplied_alpha, | 
 |                gfx::PointF(0.0f, 0.0f),  // uv_top_left | 
 |                gfx::PointF(1.0f, 1.0f),  // uv_bottom_right | 
 |                background_color, | 
 |                vertex_opacity, | 
 |                false,   // flipped | 
 |                false);  // nearest_neighbor | 
 | } | 
 |  | 
 | typedef ::testing::Types<GLRenderer, | 
 |                          SoftwareRenderer, | 
 |                          GLRendererWithExpandedViewport, | 
 |                          SoftwareRendererWithExpandedViewport> RendererTypes; | 
 | TYPED_TEST_CASE(RendererPixelTest, RendererTypes); | 
 |  | 
 | template <typename RendererType> | 
 | class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator { | 
 |  public: | 
 |   explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha) | 
 |       : fuzzy_(discard_alpha), exact_(discard_alpha) {} | 
 |  | 
 |   bool Compare(const SkBitmap& actual_bmp, | 
 |                const SkBitmap& expected_bmp) const override; | 
 |  | 
 |  private: | 
 |   FuzzyPixelOffByOneComparator fuzzy_; | 
 |   ExactPixelComparator exact_; | 
 | }; | 
 |  | 
 | template<> | 
 | bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare( | 
 |     const SkBitmap& actual_bmp, | 
 |     const SkBitmap& expected_bmp) const { | 
 |   return fuzzy_.Compare(actual_bmp, expected_bmp); | 
 | } | 
 |  | 
 | template <> | 
 | bool FuzzyForSoftwareOnlyPixelComparator< | 
 |     SoftwareRendererWithExpandedViewport>::Compare( | 
 |     const SkBitmap& actual_bmp, | 
 |     const SkBitmap& expected_bmp) const { | 
 |   return fuzzy_.Compare(actual_bmp, expected_bmp); | 
 | } | 
 |  | 
 | template<typename RendererType> | 
 | bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare( | 
 |     const SkBitmap& actual_bmp, | 
 |     const SkBitmap& expected_bmp) const { | 
 |   return exact_.Compare(actual_bmp, expected_bmp); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, SimpleGreenRect) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   SharedQuadState* shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |   gfx::Rect small_rect(100, 100); | 
 |  | 
 |   RenderPassId child_id(2, 1); | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_id, small_rect, gfx::Transform()); | 
 |  | 
 |   SharedQuadState* child_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* color_quad = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false); | 
 |  | 
 |   RenderPassId root_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRenderPass(root_id, rect, gfx::Transform()); | 
 |  | 
 |   SharedQuadState* root_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get()); | 
 |  | 
 |   CreateTestRenderPassDrawQuad( | 
 |       root_shared_state, small_rect, child_id, root_pass.get()); | 
 |  | 
 |   RenderPass* child_pass_ptr = child_pass.get(); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTestWithReadbackTarget( | 
 |       &pass_list, | 
 |       child_pass_ptr, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_small.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   SharedQuadState* shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |  | 
 |   CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | 
 |                             SkColorSetARGB(128, 0, 255, 0),  // Texel color. | 
 |                             SK_ColorTRANSPARENT,  // Background color. | 
 |                             true,                 // Premultiplied alpha. | 
 |                             shared_state, | 
 |                             this->resource_provider_.get(), | 
 |                             pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   SharedQuadState* texture_quad_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   texture_quad_state->opacity = 0.8f; | 
 |  | 
 |   CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | 
 |                             SkColorSetARGB(204, 120, 255, 120),  // Texel color. | 
 |                             SK_ColorGREEN,  // Background color. | 
 |                             true,           // Premultiplied alpha. | 
 |                             texture_quad_state, | 
 |                             this->resource_provider_.get(), | 
 |                             pass.get()); | 
 |  | 
 |   SharedQuadState* color_quad_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   SolidColorDrawQuad* color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | // TODO(skaslev): The software renderer does not support non-premultplied alpha. | 
 | TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   SharedQuadState* shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |  | 
 |   CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | 
 |                             SkColorSetARGB(128, 0, 255, 0),  // Texel color. | 
 |                             SK_ColorTRANSPARENT,  // Background color. | 
 |                             false,                // Premultiplied alpha. | 
 |                             shared_state, | 
 |                             this->resource_provider_.get(), | 
 |                             pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | // TODO(skaslev): The software renderer does not support non-premultplied alpha. | 
 | TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   SharedQuadState* texture_quad_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   texture_quad_state->opacity = 0.8f; | 
 |  | 
 |   CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | 
 |                             SkColorSetARGB(204, 120, 255, 120),  // Texel color. | 
 |                             SK_ColorGREEN,  // Background color. | 
 |                             false,          // Premultiplied alpha. | 
 |                             texture_quad_state, | 
 |                             this->resource_provider_.get(), | 
 |                             pass.get()); | 
 |  | 
 |   SharedQuadState* color_quad_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   SolidColorDrawQuad* color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |   shared_state->opacity = 0.5f; | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* blank_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* white = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   white->SetNew( | 
 |       blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |  | 
 |   SkScalar matrix[20]; | 
 |   float amount = 0.5f; | 
 |   matrix[0] = 0.213f + 0.787f * amount; | 
 |   matrix[1] = 0.715f - 0.715f * amount; | 
 |   matrix[2] = 1.f - (matrix[0] + matrix[1]); | 
 |   matrix[3] = matrix[4] = 0; | 
 |   matrix[5] = 0.213f - 0.213f * amount; | 
 |   matrix[6] = 0.715f + 0.285f * amount; | 
 |   matrix[7] = 1.f - (matrix[5] + matrix[6]); | 
 |   matrix[8] = matrix[9] = 0; | 
 |   matrix[10] = 0.213f - 0.213f * amount; | 
 |   matrix[11] = 0.715f - 0.715f * amount; | 
 |   matrix[12] = 1.f - (matrix[10] + matrix[11]); | 
 |   matrix[13] = matrix[14] = 0; | 
 |   matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; | 
 |   matrix[18] = 1; | 
 |   skia::RefPtr<SkColorFilter> colorFilter( | 
 |       skia::AdoptRef(SkColorMatrixFilter::Create(matrix))); | 
 |   skia::RefPtr<SkImageFilter> filter = | 
 |       skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL)); | 
 |   FilterOperations filters; | 
 |   filters.Append(FilterOperation::CreateReferenceFilter(filter)); | 
 |  | 
 |   RenderPassDrawQuad* render_pass_quad = | 
 |       root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |   render_pass_quad->SetNew(pass_shared_state, | 
 |                            pass_rect, | 
 |                            pass_rect, | 
 |                            child_pass_id, | 
 |                            0, | 
 |                            gfx::Vector2dF(), | 
 |                            gfx::Size(), | 
 |                            filters, | 
 |                            gfx::Vector2dF(), | 
 |                            FilterOperations()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   // This test has alpha=254 for the software renderer vs. alpha=255 for the gl | 
 |   // renderer so use a fuzzy comparator. | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), | 
 |       FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |   shared_state->opacity = 0.5f; | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* blank_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* white = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   white->SetNew( | 
 |       blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |  | 
 |   FilterOperations filters; | 
 |   filters.Append(FilterOperation::CreateSaturateFilter(0.5f)); | 
 |  | 
 |   RenderPassDrawQuad* render_pass_quad = | 
 |       root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |   render_pass_quad->SetNew(pass_shared_state, | 
 |                            pass_rect, | 
 |                            pass_rect, | 
 |                            child_pass_id, | 
 |                            0, | 
 |                            gfx::Vector2dF(), | 
 |                            gfx::Size(), | 
 |                            filters, | 
 |                            gfx::Vector2dF(), | 
 |                            FilterOperations()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, FastPassFilterChain) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |   shared_state->opacity = 0.5f; | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* blank_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* white = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   white->SetNew( | 
 |       blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |  | 
 |   FilterOperations filters; | 
 |   filters.Append(FilterOperation::CreateGrayscaleFilter(1.f)); | 
 |   filters.Append(FilterOperation::CreateBrightnessFilter(0.5f)); | 
 |  | 
 |   RenderPassDrawQuad* render_pass_quad = | 
 |       root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |   render_pass_quad->SetNew(pass_shared_state, | 
 |                            pass_rect, | 
 |                            pass_rect, | 
 |                            child_pass_id, | 
 |                            0, | 
 |                            gfx::Vector2dF(), | 
 |                            gfx::Size(), | 
 |                            filters, | 
 |                            gfx::Vector2dF(), | 
 |                            FilterOperations()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |   shared_state->opacity = 0.5f; | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* blank_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* white = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   white->SetNew( | 
 |       blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |  | 
 |   SkScalar matrix[20]; | 
 |   float amount = 0.5f; | 
 |   matrix[0] = 0.213f + 0.787f * amount; | 
 |   matrix[1] = 0.715f - 0.715f * amount; | 
 |   matrix[2] = 1.f - (matrix[0] + matrix[1]); | 
 |   matrix[3] = 0; | 
 |   matrix[4] = 20.f; | 
 |   matrix[5] = 0.213f - 0.213f * amount; | 
 |   matrix[6] = 0.715f + 0.285f * amount; | 
 |   matrix[7] = 1.f - (matrix[5] + matrix[6]); | 
 |   matrix[8] = 0; | 
 |   matrix[9] = 200.f; | 
 |   matrix[10] = 0.213f - 0.213f * amount; | 
 |   matrix[11] = 0.715f - 0.715f * amount; | 
 |   matrix[12] = 1.f - (matrix[10] + matrix[11]); | 
 |   matrix[13] = 0; | 
 |   matrix[14] = 1.5f; | 
 |   matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; | 
 |   matrix[18] = 1; | 
 |   skia::RefPtr<SkColorFilter> colorFilter( | 
 |       skia::AdoptRef(SkColorMatrixFilter::Create(matrix))); | 
 |   skia::RefPtr<SkImageFilter> filter = | 
 |       skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL)); | 
 |   FilterOperations filters; | 
 |   filters.Append(FilterOperation::CreateReferenceFilter(filter)); | 
 |  | 
 |   RenderPassDrawQuad* render_pass_quad = | 
 |       root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |   render_pass_quad->SetNew(pass_shared_state, | 
 |                            pass_rect, | 
 |                            pass_rect, | 
 |                            child_pass_id, | 
 |                            0, | 
 |                            gfx::Vector2dF(), | 
 |                            gfx::Size(), | 
 |                            filters, | 
 |                            gfx::Vector2dF(), | 
 |                            FilterOperations()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |  | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   // This test has alpha=254 for the software renderer vs. alpha=255 for the gl | 
 |   // renderer so use a fuzzy comparator. | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")), | 
 |       FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |   CreateTestRenderPassDrawQuad( | 
 |       pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   gfx::Transform aa_transform; | 
 |   aa_transform.Translate(0.5, 0.0); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get()); | 
 |   CreateTestRenderPassDrawQuad( | 
 |       pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | 
 |  | 
 |   SharedQuadState* root_shared_state = CreateTestSharedQuadState( | 
 |       gfx::Transform(), viewport_rect, root_pass.get()); | 
 |   SolidColorDrawQuad* background = | 
 |       root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   background->SetNew(root_shared_state, | 
 |                      gfx::Rect(this->device_viewport_size_), | 
 |                      gfx::Rect(this->device_viewport_size_), | 
 |                      SK_ColorWHITE, | 
 |                      false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | // This tests the case where we have a RenderPass with a mask, but the quad | 
 | // for the masked surface does not include the full surface texture. | 
 | TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |   SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( | 
 |       gfx::Transform(), viewport_rect, root_pass.get()); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); | 
 |   SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( | 
 |       gfx::Transform(), viewport_rect, child_pass.get()); | 
 |  | 
 |   // The child render pass is just a green box. | 
 |   static const SkColor kCSSGreen = 0xff008000; | 
 |   SolidColorDrawQuad* green = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   green->SetNew( | 
 |       child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false); | 
 |  | 
 |   // Make a mask. | 
 |   gfx::Rect mask_rect = viewport_rect; | 
 |   SkBitmap bitmap; | 
 |   bitmap.allocPixels( | 
 |       SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height())); | 
 |   SkCanvas canvas(bitmap); | 
 |   SkPaint paint; | 
 |   paint.setStyle(SkPaint::kStroke_Style); | 
 |   paint.setStrokeWidth(SkIntToScalar(4)); | 
 |   paint.setColor(SK_ColorWHITE); | 
 |   canvas.clear(SK_ColorTRANSPARENT); | 
 |   gfx::Rect rect = mask_rect; | 
 |   while (!rect.IsEmpty()) { | 
 |     rect.Inset(6, 6, 4, 4); | 
 |     canvas.drawRect( | 
 |         SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()), | 
 |         paint); | 
 |     rect.Inset(6, 6, 4, 4); | 
 |   } | 
 |  | 
 |   ResourceProvider::ResourceId mask_resource_id = | 
 |       this->resource_provider_->CreateResource( | 
 |           mask_rect.size(), | 
 |           GL_CLAMP_TO_EDGE, | 
 |           ResourceProvider::TextureHintImmutable, | 
 |           RGBA_8888); | 
 |   { | 
 |     SkAutoLockPixels lock(bitmap); | 
 |     this->resource_provider_->SetPixels( | 
 |         mask_resource_id, | 
 |         reinterpret_cast<uint8_t*>(bitmap.getPixels()), | 
 |         mask_rect, | 
 |         mask_rect, | 
 |         gfx::Vector2d()); | 
 |   } | 
 |  | 
 |   // This RenderPassDrawQuad does not include the full |viewport_rect| which is | 
 |   // the size of the child render pass. | 
 |   gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100); | 
 |   EXPECT_NE(sub_rect.x(), child_pass->output_rect.x()); | 
 |   EXPECT_NE(sub_rect.y(), child_pass->output_rect.y()); | 
 |   EXPECT_NE(sub_rect.right(), child_pass->output_rect.right()); | 
 |   EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom()); | 
 |  | 
 |   // Set up a mask on the RenderPassDrawQuad. | 
 |   RenderPassDrawQuad* mask_quad = | 
 |       root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |   mask_quad->SetNew(root_pass_shared_state, | 
 |                     sub_rect, | 
 |                     sub_rect, | 
 |                     child_pass_id, | 
 |                     mask_resource_id, | 
 |                     gfx::Vector2dF(2.f, 1.f),     // mask_uv_scale | 
 |                     gfx::Size(mask_rect.size()),  // mask_texture_size | 
 |                     FilterOperations(),           // foreground filters | 
 |                     gfx::Vector2dF(),             // filters scale | 
 |                     FilterOperations());          // background filters | 
 |  | 
 |   // White background behind the masked render pass. | 
 |   SolidColorDrawQuad* white = | 
 |       root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   white->SetNew(root_pass_shared_state, | 
 |                 viewport_rect, | 
 |                 viewport_rect, | 
 |                 SK_ColorWHITE, | 
 |                 false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | template <typename RendererType> | 
 | class RendererPixelTestWithBackgroundFilter | 
 |     : public RendererPixelTest<RendererType> { | 
 |  protected: | 
 |   void SetUpRenderPassList() { | 
 |     gfx::Rect device_viewport_rect(this->device_viewport_size_); | 
 |  | 
 |     RenderPassId root_id(1, 1); | 
 |     scoped_ptr<RenderPass> root_pass = | 
 |         CreateTestRootRenderPass(root_id, device_viewport_rect); | 
 |     root_pass->has_transparent_background = false; | 
 |  | 
 |     gfx::Transform identity_content_to_target_transform; | 
 |  | 
 |     RenderPassId filter_pass_id(2, 1); | 
 |     gfx::Transform transform_to_root; | 
 |     scoped_ptr<RenderPass> filter_pass = | 
 |         CreateTestRenderPass(filter_pass_id, | 
 |                              filter_pass_content_rect_, | 
 |                              transform_to_root); | 
 |  | 
 |     // A non-visible quad in the filtering render pass. | 
 |     { | 
 |       SharedQuadState* shared_state = | 
 |           CreateTestSharedQuadState(identity_content_to_target_transform, | 
 |                                     filter_pass_content_rect_, | 
 |                                     filter_pass.get()); | 
 |       SolidColorDrawQuad* color_quad = | 
 |           filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |       color_quad->SetNew(shared_state, | 
 |                          filter_pass_content_rect_, | 
 |                          filter_pass_content_rect_, | 
 |                          SK_ColorTRANSPARENT, | 
 |                          false); | 
 |     } | 
 |  | 
 |     { | 
 |       SharedQuadState* shared_state = | 
 |           CreateTestSharedQuadState(filter_pass_to_target_transform_, | 
 |                                     filter_pass_content_rect_, | 
 |                                     filter_pass.get()); | 
 |       RenderPassDrawQuad* filter_pass_quad = | 
 |           root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | 
 |       filter_pass_quad->SetNew(shared_state, | 
 |                                filter_pass_content_rect_, | 
 |                                filter_pass_content_rect_, | 
 |                                filter_pass_id, | 
 |                                0,                   // mask_resource_id | 
 |                                gfx::Vector2dF(),    // mask_uv_scale | 
 |                                gfx::Size(),         // mask_texture_size | 
 |                                FilterOperations(),  // filters | 
 |                                gfx::Vector2dF(),    // filters_scale | 
 |                                this->background_filters_); | 
 |     } | 
 |  | 
 |     const int kColumnWidth = device_viewport_rect.width() / 3; | 
 |  | 
 |     gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20); | 
 |     for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) { | 
 |       SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |           identity_content_to_target_transform, left_rect, root_pass.get()); | 
 |       SolidColorDrawQuad* color_quad = | 
 |           root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |       color_quad->SetNew( | 
 |           shared_state, left_rect, left_rect, SK_ColorGREEN, false); | 
 |       left_rect += gfx::Vector2d(0, left_rect.height() + 1); | 
 |     } | 
 |  | 
 |     gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20); | 
 |     for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) { | 
 |       SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |           identity_content_to_target_transform, middle_rect, root_pass.get()); | 
 |       SolidColorDrawQuad* color_quad = | 
 |           root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |       color_quad->SetNew( | 
 |           shared_state, middle_rect, middle_rect, SK_ColorRED, false); | 
 |       middle_rect += gfx::Vector2d(0, middle_rect.height() + 1); | 
 |     } | 
 |  | 
 |     gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20); | 
 |     for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) { | 
 |       SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |           identity_content_to_target_transform, right_rect, root_pass.get()); | 
 |       SolidColorDrawQuad* color_quad = | 
 |           root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |       color_quad->SetNew( | 
 |           shared_state, right_rect, right_rect, SK_ColorBLUE, false); | 
 |       right_rect += gfx::Vector2d(0, right_rect.height() + 1); | 
 |     } | 
 |  | 
 |     SharedQuadState* shared_state = | 
 |         CreateTestSharedQuadState(identity_content_to_target_transform, | 
 |                                   device_viewport_rect, | 
 |                                   root_pass.get()); | 
 |     SolidColorDrawQuad* background_quad = | 
 |         root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |     background_quad->SetNew(shared_state, | 
 |                             device_viewport_rect, | 
 |                             device_viewport_rect, | 
 |                             SK_ColorWHITE, | 
 |                             false); | 
 |  | 
 |     pass_list_.push_back(filter_pass.Pass()); | 
 |     pass_list_.push_back(root_pass.Pass()); | 
 |   } | 
 |  | 
 |   RenderPassList pass_list_; | 
 |   FilterOperations background_filters_; | 
 |   gfx::Transform filter_pass_to_target_transform_; | 
 |   gfx::Rect filter_pass_content_rect_; | 
 | }; | 
 |  | 
 | typedef ::testing::Types<GLRenderer, SoftwareRenderer> | 
 |     BackgroundFilterRendererTypes; | 
 | TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter, | 
 |                 BackgroundFilterRendererTypes); | 
 |  | 
 | typedef RendererPixelTestWithBackgroundFilter<GLRenderer> | 
 | GLRendererPixelTestWithBackgroundFilter; | 
 |  | 
 | // TODO(skaslev): The software renderer does not support filters yet. | 
 | TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) { | 
 |   this->background_filters_.Append( | 
 |       FilterOperation::CreateInvertFilter(1.f)); | 
 |  | 
 |   this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_); | 
 |   this->filter_pass_content_rect_.Inset(12, 14, 16, 18); | 
 |  | 
 |   this->SetUpRenderPassList(); | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &this->pass_list_, | 
 |       base::FilePath(FILE_PATH_LITERAL("background_filter.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | class ExternalStencilPixelTest : public GLRendererPixelTest { | 
 |  protected: | 
 |   void ClearBackgroundToGreen() { | 
 |     GLES2Interface* gl = output_surface_->context_provider()->ContextGL(); | 
 |     output_surface_->EnsureBackbuffer(); | 
 |     output_surface_->Reshape(device_viewport_size_, 1); | 
 |     gl->ClearColor(0.f, 1.f, 0.f, 1.f); | 
 |     gl->Clear(GL_COLOR_BUFFER_BIT); | 
 |   } | 
 |  | 
 |   void PopulateStencilBuffer() { | 
 |     // Set two quadrants of the stencil buffer to 1. | 
 |     GLES2Interface* gl = output_surface_->context_provider()->ContextGL(); | 
 |     output_surface_->EnsureBackbuffer(); | 
 |     output_surface_->Reshape(device_viewport_size_, 1); | 
 |     gl->ClearStencil(0); | 
 |     gl->Clear(GL_STENCIL_BUFFER_BIT); | 
 |     gl->Enable(GL_SCISSOR_TEST); | 
 |     gl->ClearStencil(1); | 
 |     gl->Scissor(0, | 
 |                 0, | 
 |                 device_viewport_size_.width() / 2, | 
 |                 device_viewport_size_.height() / 2); | 
 |     gl->Clear(GL_STENCIL_BUFFER_BIT); | 
 |     gl->Scissor(device_viewport_size_.width() / 2, | 
 |                 device_viewport_size_.height() / 2, | 
 |                 device_viewport_size_.width(), | 
 |                 device_viewport_size_.height()); | 
 |     gl->Clear(GL_STENCIL_BUFFER_BIT); | 
 |   } | 
 | }; | 
 |  | 
 | TEST_F(ExternalStencilPixelTest, StencilTestEnabled) { | 
 |   ClearBackgroundToGreen(); | 
 |   PopulateStencilBuffer(); | 
 |   this->EnableExternalStencilTest(); | 
 |  | 
 |   // Draw a blue quad that covers the entire device viewport. It should be | 
 |   // clipped to the bottom left and top right corners by the external stencil. | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |   SharedQuadState* blue_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   SolidColorDrawQuad* blue = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | 
 |   pass->has_transparent_background = false; | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TEST_F(ExternalStencilPixelTest, StencilTestDisabled) { | 
 |   PopulateStencilBuffer(); | 
 |  | 
 |   // Draw a green quad that covers the entire device viewport. The stencil | 
 |   // buffer should be ignored. | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |   SharedQuadState* green_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   SolidColorDrawQuad* green = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false); | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) { | 
 |   // The stencil test should apply only to the final render pass. | 
 |   ClearBackgroundToGreen(); | 
 |   PopulateStencilBuffer(); | 
 |   this->EnableExternalStencilTest(); | 
 |  | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |   root_pass->has_transparent_background = false; | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height()); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |   CreateTestRenderPassDrawQuad( | 
 |       pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TEST_F(ExternalStencilPixelTest, DeviceClip) { | 
 |   ClearBackgroundToGreen(); | 
 |   gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50)); | 
 |   this->ForceDeviceClip(clip_rect); | 
 |  | 
 |   // Draw a blue quad that covers the entire device viewport. It should be | 
 |   // clipped to the bottom right corner by the device clip. | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |   SharedQuadState* blue_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   SolidColorDrawQuad* blue = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | // Software renderer does not support anti-aliased edges. | 
 | TEST_F(GLRendererPixelTest, AntiAliasing) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   gfx::Transform red_content_to_target_transform; | 
 |   red_content_to_target_transform.Rotate(10); | 
 |   SharedQuadState* red_shared_state = CreateTestSharedQuadState( | 
 |       red_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false); | 
 |  | 
 |   gfx::Transform yellow_content_to_target_transform; | 
 |   yellow_content_to_target_transform.Rotate(5); | 
 |   SharedQuadState* yellow_shared_state = CreateTestSharedQuadState( | 
 |       yellow_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* yellow = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false); | 
 |  | 
 |   gfx::Transform blue_content_to_target_transform; | 
 |   SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | 
 |       blue_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* blue = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | // This test tests that anti-aliasing works for axis aligned quads. | 
 | // Anti-aliasing is only supported in the gl renderer. | 
 | TEST_F(GLRendererPixelTest, AxisAligned) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, rect, transform_to_root); | 
 |  | 
 |   gfx::Transform red_content_to_target_transform; | 
 |   red_content_to_target_transform.Translate(50, 50); | 
 |   red_content_to_target_transform.Scale( | 
 |       0.5f + 1.0f / (rect.width() * 2.0f), | 
 |       0.5f + 1.0f / (rect.height() * 2.0f)); | 
 |   SharedQuadState* red_shared_state = CreateTestSharedQuadState( | 
 |       red_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false); | 
 |  | 
 |   gfx::Transform yellow_content_to_target_transform; | 
 |   yellow_content_to_target_transform.Translate(25.5f, 25.5f); | 
 |   yellow_content_to_target_transform.Scale(0.5f, 0.5f); | 
 |   SharedQuadState* yellow_shared_state = CreateTestSharedQuadState( | 
 |       yellow_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* yellow = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false); | 
 |  | 
 |   gfx::Transform blue_content_to_target_transform; | 
 |   SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | 
 |       blue_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* blue = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | // This test tests that forcing anti-aliasing off works as expected. | 
 | // Anti-aliasing is only supported in the gl renderer. | 
 | TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, rect, transform_to_root); | 
 |  | 
 |   gfx::Transform hole_content_to_target_transform; | 
 |   hole_content_to_target_transform.Translate(50, 50); | 
 |   hole_content_to_target_transform.Scale( | 
 |       0.5f + 1.0f / (rect.width() * 2.0f), | 
 |       0.5f + 1.0f / (rect.height() * 2.0f)); | 
 |   SharedQuadState* hole_shared_state = CreateTestSharedQuadState( | 
 |       hole_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* hole = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   hole->SetAll( | 
 |       hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true); | 
 |  | 
 |   gfx::Transform green_content_to_target_transform; | 
 |   SharedQuadState* green_shared_state = CreateTestSharedQuadState( | 
 |       green_content_to_target_transform, rect, pass.get()); | 
 |  | 
 |   SolidColorDrawQuad* green = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")), | 
 |       ExactPixelComparator(false))); | 
 | } | 
 |  | 
 | TEST_F(GLRendererPixelTest, AntiAliasingPerspective) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRootRenderPass(RenderPassId(1, 1), rect); | 
 |  | 
 |   gfx::Rect red_rect(0, 0, 180, 500); | 
 |   gfx::Transform red_content_to_target_transform( | 
 |       1.0f,  2.4520f,  10.6206f, 19.0f, | 
 |       0.0f,  0.3528f,  5.9737f,  9.5f, | 
 |       0.0f, -0.2250f, -0.9744f,  0.0f, | 
 |       0.0f,  0.0225f,  0.0974f,  1.0f); | 
 |   SharedQuadState* red_shared_state = CreateTestSharedQuadState( | 
 |       red_content_to_target_transform, red_rect, pass.get()); | 
 |   SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false); | 
 |  | 
 |   gfx::Rect green_rect(19, 7, 180, 10); | 
 |   SharedQuadState* green_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get()); | 
 |   SolidColorDrawQuad* green = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   green->SetNew( | 
 |       green_shared_state, green_rect, green_rect, SK_ColorGREEN, false); | 
 |  | 
 |   SharedQuadState* blue_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |   SolidColorDrawQuad* blue = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { | 
 |   gfx::Size pile_tile_size(1000, 1000); | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   // TODO(enne): the renderer should figure this out on its own. | 
 |   ResourceFormat texture_format = RGBA_8888; | 
 |   bool nearest_neighbor = false; | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   // One clipped blue quad in the lower right corner.  Outside the clip | 
 |   // is red, which should not appear. | 
 |   gfx::Rect blue_rect(gfx::Size(100, 100)); | 
 |   gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50)); | 
 |   scoped_refptr<FakePicturePileImpl> blue_pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, blue_rect.size()); | 
 |   SkPaint red_paint; | 
 |   red_paint.setColor(SK_ColorRED); | 
 |   blue_pile->add_draw_rect_with_paint(blue_rect, red_paint); | 
 |   SkPaint blue_paint; | 
 |   blue_paint.setColor(SK_ColorBLUE); | 
 |   blue_pile->add_draw_rect_with_paint(blue_clip_rect, blue_paint); | 
 |   blue_pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform blue_content_to_target_transform; | 
 |   gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right()); | 
 |   blue_content_to_target_transform.Translate(offset.x(), offset.y()); | 
 |   gfx::RectF blue_scissor_rect = blue_clip_rect; | 
 |   blue_content_to_target_transform.TransformRect(&blue_scissor_rect); | 
 |   SharedQuadState* blue_shared_state = | 
 |       CreateTestSharedQuadStateClipped(blue_content_to_target_transform, | 
 |                                        blue_rect, | 
 |                                        gfx::ToEnclosingRect(blue_scissor_rect), | 
 |                                        pass.get()); | 
 |  | 
 |   PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |  | 
 |   blue_quad->SetNew(blue_shared_state, | 
 |                     viewport,  // Intentionally bigger than clip. | 
 |                     gfx::Rect(), viewport, gfx::RectF(viewport), | 
 |                     viewport.size(), nearest_neighbor, texture_format, viewport, | 
 |                     1.f, blue_pile.get()); | 
 |  | 
 |   // One viewport-filling green quad. | 
 |   scoped_refptr<FakePicturePileImpl> green_pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint green_paint; | 
 |   green_paint.setColor(SK_ColorGREEN); | 
 |   green_pile->add_draw_rect_with_paint(viewport, green_paint); | 
 |   green_pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform green_content_to_target_transform; | 
 |   SharedQuadState* green_shared_state = CreateTestSharedQuadState( | 
 |       green_content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   PictureDrawQuad* green_quad = | 
 |       pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport, | 
 |                      gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(), | 
 |                      nearest_neighbor, texture_format, viewport, 1.f, | 
 |                      green_pile.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | // Not WithSkiaGPUBackend since that path currently requires tiles for opacity. | 
 | TYPED_TEST(RendererPixelTest, PictureDrawQuadOpacity) { | 
 |   gfx::Size pile_tile_size(1000, 1000); | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   ResourceFormat texture_format = RGBA_8888; | 
 |   bool nearest_neighbor = false; | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   // One viewport-filling 0.5-opacity green quad. | 
 |   scoped_refptr<FakePicturePileImpl> green_pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint green_paint; | 
 |   green_paint.setColor(SK_ColorGREEN); | 
 |   green_pile->add_draw_rect_with_paint(viewport, green_paint); | 
 |   green_pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform green_content_to_target_transform; | 
 |   SharedQuadState* green_shared_state = CreateTestSharedQuadState( | 
 |       green_content_to_target_transform, viewport, pass.get()); | 
 |   green_shared_state->opacity = 0.5f; | 
 |  | 
 |   PictureDrawQuad* green_quad = | 
 |       pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport, | 
 |                      gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor, | 
 |                      texture_format, viewport, 1.f, green_pile.get()); | 
 |  | 
 |   // One viewport-filling white quad. | 
 |   scoped_refptr<FakePicturePileImpl> white_pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint white_paint; | 
 |   white_paint.setColor(SK_ColorWHITE); | 
 |   white_pile->add_draw_rect_with_paint(viewport, white_paint); | 
 |   white_pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform white_content_to_target_transform; | 
 |   SharedQuadState* white_shared_state = CreateTestSharedQuadState( | 
 |       white_content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   PictureDrawQuad* white_quad = | 
 |       pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport, | 
 |                      gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor, | 
 |                      texture_format, viewport, 1.f, white_pile.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | template<typename TypeParam> bool IsSoftwareRenderer() { | 
 |   return false; | 
 | } | 
 |  | 
 | template<> | 
 | bool IsSoftwareRenderer<SoftwareRenderer>() { | 
 |   return true; | 
 | } | 
 |  | 
 | template<> | 
 | bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() { | 
 |   return true; | 
 | } | 
 |  | 
 | // If we disable image filtering, then a 2x2 bitmap should appear as four | 
 | // huge sharp squares. | 
 | TYPED_TEST(RendererPixelTest, PictureDrawQuadDisableImageFiltering) { | 
 |   // We only care about this in software mode since bilinear filtering is | 
 |   // cheap in hardware. | 
 |   if (!IsSoftwareRenderer<TypeParam>()) | 
 |     return; | 
 |  | 
 |   gfx::Size pile_tile_size(1000, 1000); | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   ResourceFormat texture_format = RGBA_8888; | 
 |   bool nearest_neighbor = false; | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   SkBitmap bitmap; | 
 |   bitmap.allocN32Pixels(2, 2); | 
 |   { | 
 |     SkAutoLockPixels lock(bitmap); | 
 |     SkCanvas canvas(bitmap); | 
 |     canvas.drawPoint(0, 0, SK_ColorGREEN); | 
 |     canvas.drawPoint(0, 1, SK_ColorBLUE); | 
 |     canvas.drawPoint(1, 0, SK_ColorBLUE); | 
 |     canvas.drawPoint(1, 1, SK_ColorGREEN); | 
 |   } | 
 |  | 
 |   scoped_refptr<FakePicturePileImpl> pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint paint; | 
 |   paint.setFilterLevel(SkPaint::kLow_FilterLevel); | 
 |   pile->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint); | 
 |   pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, | 
 |                gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor, | 
 |                texture_format, viewport, 1.f, pile.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   this->disable_picture_quad_image_filtering_ = true; | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad. | 
 | TYPED_TEST(RendererPixelTest, PictureDrawQuadNearestNeighbor) { | 
 |   gfx::Size pile_tile_size(1000, 1000); | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   ResourceFormat texture_format = RGBA_8888; | 
 |   bool nearest_neighbor = true; | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   SkBitmap bitmap; | 
 |   bitmap.allocN32Pixels(2, 2); | 
 |   { | 
 |     SkAutoLockPixels lock(bitmap); | 
 |     SkCanvas canvas(bitmap); | 
 |     canvas.drawPoint(0, 0, SK_ColorGREEN); | 
 |     canvas.drawPoint(0, 1, SK_ColorBLUE); | 
 |     canvas.drawPoint(1, 0, SK_ColorBLUE); | 
 |     canvas.drawPoint(1, 1, SK_ColorGREEN); | 
 |   } | 
 |  | 
 |   scoped_refptr<FakePicturePileImpl> pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint paint; | 
 |   paint.setFilterLevel(SkPaint::kLow_FilterLevel); | 
 |   pile->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint); | 
 |   pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, | 
 |                gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor, | 
 |                texture_format, viewport, 1.f, pile.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad. | 
 | TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) { | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   bool swizzle_contents = true; | 
 |   bool nearest_neighbor = true; | 
 |  | 
 |   SkBitmap bitmap; | 
 |   bitmap.allocN32Pixels(2, 2); | 
 |   { | 
 |     SkAutoLockPixels lock(bitmap); | 
 |     SkCanvas canvas(bitmap); | 
 |     canvas.drawPoint(0, 0, SK_ColorGREEN); | 
 |     canvas.drawPoint(0, 1, SK_ColorBLUE); | 
 |     canvas.drawPoint(1, 0, SK_ColorBLUE); | 
 |     canvas.drawPoint(1, 1, SK_ColorGREEN); | 
 |   } | 
 |  | 
 |   gfx::Size tile_size(2, 2); | 
 |   ResourceProvider::ResourceId resource = | 
 |       this->resource_provider_->CreateResource( | 
 |           tile_size, | 
 |           GL_CLAMP_TO_EDGE, | 
 |           ResourceProvider::TextureHintImmutable, | 
 |           RGBA_8888); | 
 |  | 
 |   { | 
 |     SkAutoLockPixels lock(bitmap); | 
 |     this->resource_provider_->SetPixels( | 
 |         resource, | 
 |         static_cast<uint8_t*>(bitmap.getPixels()), | 
 |         gfx::Rect(tile_size), | 
 |         gfx::Rect(tile_size), | 
 |         gfx::Vector2d()); | 
 |   } | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>(); | 
 |   quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, | 
 |                gfx::Rect(tile_size), tile_size, swizzle_contents, | 
 |                nearest_neighbor); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { | 
 |   gfx::Size pile_tile_size(1000, 1000); | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   // TODO(enne): the renderer should figure this out on its own. | 
 |   ResourceFormat texture_format = RGBA_8888; | 
 |   bool nearest_neighbor = false; | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   // As scaling up the blue checkerboards will cause sampling on the GPU, | 
 |   // a few extra "cleanup rects" need to be added to clobber the blending | 
 |   // to make the output image more clean.  This will also test subrects | 
 |   // of the layer. | 
 |   gfx::Transform green_content_to_target_transform; | 
 |   gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100)); | 
 |   gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20)); | 
 |   scoped_refptr<FakePicturePileImpl> green_pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint red_paint; | 
 |   red_paint.setColor(SK_ColorRED); | 
 |   green_pile->add_draw_rect_with_paint(viewport, red_paint); | 
 |   SkPaint green_paint; | 
 |   green_paint.setColor(SK_ColorGREEN); | 
 |   green_pile->add_draw_rect_with_paint(green_rect1, green_paint); | 
 |   green_pile->add_draw_rect_with_paint(green_rect2, green_paint); | 
 |   green_pile->RerecordPile(); | 
 |  | 
 |   SharedQuadState* top_right_green_shared_quad_state = | 
 |       CreateTestSharedQuadState( | 
 |           green_content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   PictureDrawQuad* green_quad1 = | 
 |       pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1, | 
 |                       gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()), | 
 |                       green_rect1.size(), nearest_neighbor, texture_format, | 
 |                       green_rect1, 1.f, green_pile.get()); | 
 |  | 
 |   PictureDrawQuad* green_quad2 = | 
 |       pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2, | 
 |                       gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()), | 
 |                       green_rect2.size(), nearest_neighbor, texture_format, | 
 |                       green_rect2, 1.f, green_pile.get()); | 
 |  | 
 |   // Add a green clipped checkerboard in the bottom right to help test | 
 |   // interleaving picture quad content and solid color content. | 
 |   gfx::Rect bottom_right_rect( | 
 |       gfx::Point(viewport.width() / 2, viewport.height() / 2), | 
 |       gfx::Size(viewport.width() / 2, viewport.height() / 2)); | 
 |   SharedQuadState* bottom_right_green_shared_state = | 
 |       CreateTestSharedQuadStateClipped(green_content_to_target_transform, | 
 |                                        viewport, | 
 |                                        bottom_right_rect, | 
 |                                        pass.get()); | 
 |   SolidColorDrawQuad* bottom_right_color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   bottom_right_color_quad->SetNew(bottom_right_green_shared_state, | 
 |                                   viewport, | 
 |                                   viewport, | 
 |                                   SK_ColorGREEN, | 
 |                                   false); | 
 |  | 
 |   // Add two blue checkerboards taking up the bottom left and top right, | 
 |   // but use content scales as content rects to make this happen. | 
 |   // The content is at a 4x content scale. | 
 |   gfx::Rect layer_rect(gfx::Size(20, 30)); | 
 |   float contents_scale = 4.f; | 
 |   // Two rects that touch at their corners, arbitrarily placed in the layer. | 
 |   gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f)); | 
 |   gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f)); | 
 |   gfx::RectF union_layer_rect = blue_layer_rect1; | 
 |   union_layer_rect.Union(blue_layer_rect2); | 
 |  | 
 |   // Because scaling up will cause sampling outside the rects, add one extra | 
 |   // pixel of buffer at the final content scale. | 
 |   float inset = -1.f / contents_scale; | 
 |   blue_layer_rect1.Inset(inset, inset, inset, inset); | 
 |   blue_layer_rect2.Inset(inset, inset, inset, inset); | 
 |  | 
 |   scoped_refptr<FakePicturePileImpl> pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size()); | 
 |  | 
 |   Region outside(layer_rect); | 
 |   outside.Subtract(gfx::ToEnclosingRect(union_layer_rect)); | 
 |   for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) { | 
 |     pile->add_draw_rect_with_paint(iter.rect(), red_paint); | 
 |   } | 
 |  | 
 |   SkPaint blue_paint; | 
 |   blue_paint.setColor(SK_ColorBLUE); | 
 |   pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint); | 
 |   pile->add_draw_rect_with_paint(blue_layer_rect2, blue_paint); | 
 |   pile->RerecordPile(); | 
 |  | 
 |   gfx::Rect content_rect( | 
 |       gfx::ScaleToEnclosingRect(layer_rect, contents_scale)); | 
 |   gfx::Rect content_union_rect( | 
 |       gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale))); | 
 |  | 
 |   // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels, | 
 |   // so scale an additional 10x to make them 100x100. | 
 |   gfx::Transform content_to_target_transform; | 
 |   content_to_target_transform.Scale(10.0, 10.0); | 
 |   gfx::Rect quad_content_rect(gfx::Size(20, 20)); | 
 |   SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, quad_content_rect, pass.get()); | 
 |  | 
 |   PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(), | 
 |                     quad_content_rect, gfx::RectF(quad_content_rect), | 
 |                     content_union_rect.size(), nearest_neighbor, texture_format, | 
 |                     content_union_rect, contents_scale, pile.get()); | 
 |  | 
 |   // Fill left half of viewport with green. | 
 |   gfx::Transform half_green_content_to_target_transform; | 
 |   gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height())); | 
 |   SharedQuadState* half_green_shared_state = CreateTestSharedQuadState( | 
 |       half_green_content_to_target_transform, half_green_rect, pass.get()); | 
 |   SolidColorDrawQuad* half_color_quad = | 
 |       pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   half_color_quad->SetNew(half_green_shared_state, | 
 |                           half_green_rect, | 
 |                           half_green_rect, | 
 |                           SK_ColorGREEN, | 
 |                           false); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | typedef RendererPixelTest<GLRendererWithFlippedSurface> | 
 |     GLRendererPixelTestWithFlippedOutputSurface; | 
 |  | 
 | TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) { | 
 |   // This draws a blue rect above a yellow rect with an inverted output surface. | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |   CreateTestRenderPassDrawQuad( | 
 |       pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) { | 
 |   // This draws a blue rect above a yellow rect with an inverted output surface. | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   gfx::Rect blue_rect(0, | 
 |                       0, | 
 |                       this->device_viewport_size_.width(), | 
 |                       this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect yellow_rect(0, | 
 |                         this->device_viewport_size_.height() / 2, | 
 |                         this->device_viewport_size_.width(), | 
 |                         this->device_viewport_size_.height() / 2); | 
 |   SolidColorDrawQuad* yellow = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |   CreateTestRenderPassDrawQuad( | 
 |       pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   // Check that the child pass remains unflipped. | 
 |   EXPECT_TRUE(this->RunPixelTestWithReadbackTarget( | 
 |       &pass_list, | 
 |       pass_list.front(), | 
 |       base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), | 
 |       ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TEST_F(GLRendererPixelTest, CheckReadbackSubset) { | 
 |   gfx::Rect viewport_rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId root_pass_id(1, 1); | 
 |   scoped_ptr<RenderPass> root_pass = | 
 |       CreateTestRootRenderPass(root_pass_id, viewport_rect); | 
 |  | 
 |   RenderPassId child_pass_id(2, 2); | 
 |   gfx::Rect pass_rect(this->device_viewport_size_); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> child_pass = | 
 |       CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | 
 |  | 
 |   gfx::Transform content_to_target_transform; | 
 |   SharedQuadState* shared_state = CreateTestSharedQuadState( | 
 |       content_to_target_transform, viewport_rect, child_pass.get()); | 
 |  | 
 |   // Draw a green quad full-size with a blue quad in the lower-right corner. | 
 |   gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4, | 
 |                       this->device_viewport_size_.height() * 3 / 4, | 
 |                       this->device_viewport_size_.width() * 3 / 4, | 
 |                       this->device_viewport_size_.height() * 3 / 4); | 
 |   SolidColorDrawQuad* blue = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | 
 |   gfx::Rect green_rect(0, | 
 |                        0, | 
 |                        this->device_viewport_size_.width(), | 
 |                        this->device_viewport_size_.height()); | 
 |   SolidColorDrawQuad* green = | 
 |       child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 
 |   green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false); | 
 |  | 
 |   SharedQuadState* pass_shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | 
 |   CreateTestRenderPassDrawQuad( | 
 |       pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(child_pass.Pass()); | 
 |   pass_list.push_back(root_pass.Pass()); | 
 |  | 
 |   // Check that the child pass remains unflipped. | 
 |   gfx::Rect capture_rect(this->device_viewport_size_.width() / 2, | 
 |                          this->device_viewport_size_.height() / 2, | 
 |                          this->device_viewport_size_.width() / 2, | 
 |                          this->device_viewport_size_.height() / 2); | 
 |   EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea( | 
 |       &pass_list, | 
 |       pass_list.front(), | 
 |       base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")), | 
 |       ExactPixelComparator(true), | 
 |       &capture_rect)); | 
 | } | 
 |  | 
 | TEST_F(GLRendererPixelTest, PictureDrawQuadTexture4444) { | 
 |   gfx::Size pile_tile_size(1000, 1000); | 
 |   gfx::Rect viewport(this->device_viewport_size_); | 
 |   ResourceFormat texture_format = RGBA_4444; | 
 |   bool nearest_neighbor = false; | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   gfx::Transform transform_to_root; | 
 |   scoped_ptr<RenderPass> pass = | 
 |       CreateTestRenderPass(id, viewport, transform_to_root); | 
 |  | 
 |   // One viewport-filling blue quad | 
 |   scoped_refptr<FakePicturePileImpl> blue_pile = | 
 |       FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size()); | 
 |   SkPaint blue_paint; | 
 |   blue_paint.setColor(SK_ColorBLUE); | 
 |   blue_pile->add_draw_rect_with_paint(viewport, blue_paint); | 
 |   blue_pile->RerecordPile(); | 
 |  | 
 |   gfx::Transform blue_content_to_target_transform; | 
 |   SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | 
 |       blue_content_to_target_transform, viewport, pass.get()); | 
 |  | 
 |   PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | 
 |   blue_quad->SetNew(blue_shared_state, viewport, gfx::Rect(), viewport, | 
 |                     gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(), | 
 |                     nearest_neighbor, texture_format, viewport, 1.f, | 
 |                     blue_pile.get()); | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest(&pass_list, | 
 |                                  base::FilePath(FILE_PATH_LITERAL("blue.png")), | 
 |                                  ExactPixelComparator(true))); | 
 | } | 
 |  | 
 | TYPED_TEST(RendererPixelTest, WrapModeRepeat) { | 
 |   gfx::Rect rect(this->device_viewport_size_); | 
 |  | 
 |   RenderPassId id(1, 1); | 
 |   scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 
 |  | 
 |   SharedQuadState* shared_state = | 
 |       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 
 |  | 
 |   gfx::Rect texture_rect(4, 4); | 
 |   SkPMColor colors[4] = { | 
 |     SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)), | 
 |     SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)), | 
 |     SkPreMultiplyColor(SkColorSetARGB(255, 0,  64, 0)), | 
 |     SkPreMultiplyColor(SkColorSetARGB(255, 0,   0, 0)), | 
 |   }; | 
 |   uint32_t pixels[16] = { | 
 |     colors[0], colors[0], colors[1], colors[1], | 
 |     colors[0], colors[0], colors[1], colors[1], | 
 |     colors[2], colors[2], colors[3], colors[3], | 
 |     colors[2], colors[2], colors[3], colors[3], | 
 |   }; | 
 |   ResourceProvider::ResourceId resource = | 
 |       this->resource_provider_->CreateResource( | 
 |           texture_rect.size(), | 
 |           GL_REPEAT, | 
 |           ResourceProvider::TextureHintImmutable, | 
 |           RGBA_8888); | 
 |   this->resource_provider_->SetPixels( | 
 |       resource, | 
 |       reinterpret_cast<uint8_t*>(pixels), | 
 |       texture_rect, | 
 |       texture_rect, | 
 |       gfx::Vector2d()); | 
 |  | 
 |   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | 
 |   TextureDrawQuad* texture_quad = | 
 |       pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | 
 |   texture_quad->SetNew( | 
 |       shared_state, | 
 |       gfx::Rect(this->device_viewport_size_), | 
 |       gfx::Rect(), | 
 |       gfx::Rect(this->device_viewport_size_), | 
 |       resource, | 
 |       true,                     // premultiplied_alpha | 
 |       gfx::PointF(0.0f, 0.0f),  // uv_top_left | 
 |       gfx::PointF(              // uv_bottom_right | 
 |           this->device_viewport_size_.width() / texture_rect.width(), | 
 |           this->device_viewport_size_.height() / texture_rect.height()), | 
 |       SK_ColorWHITE, | 
 |       vertex_opacity, | 
 |       false,   // flipped | 
 |       false);  // nearest_neighbor | 
 |  | 
 |   RenderPassList pass_list; | 
 |   pass_list.push_back(pass.Pass()); | 
 |  | 
 |   EXPECT_TRUE(this->RunPixelTest( | 
 |       &pass_list, | 
 |       base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), | 
 |       FuzzyPixelOffByOneComparator(true))); | 
 | } | 
 |  | 
 | #endif  // !defined(OS_ANDROID) | 
 |  | 
 | }  // namespace | 
 | }  // namespace cc |