Home | History | Annotate | Download | only in output
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/output/gl_renderer.h"
      6 
      7 #include <set>
      8 
      9 #include "cc/base/math_util.h"
     10 #include "cc/output/compositor_frame_metadata.h"
     11 #include "cc/resources/prioritized_resource_manager.h"
     12 #include "cc/resources/resource_provider.h"
     13 #include "cc/test/fake_impl_proxy.h"
     14 #include "cc/test/fake_layer_tree_host_impl.h"
     15 #include "cc/test/fake_output_surface.h"
     16 #include "cc/test/fake_output_surface_client.h"
     17 #include "cc/test/fake_renderer_client.h"
     18 #include "cc/test/mock_quad_culler.h"
     19 #include "cc/test/pixel_test.h"
     20 #include "cc/test/render_pass_test_common.h"
     21 #include "cc/test/render_pass_test_utils.h"
     22 #include "cc/test/test_shared_bitmap_manager.h"
     23 #include "cc/test/test_web_graphics_context_3d.h"
     24 #include "gpu/GLES2/gl2extchromium.h"
     25 #include "gpu/command_buffer/client/context_support.h"
     26 #include "testing/gmock/include/gmock/gmock.h"
     27 #include "testing/gtest/include/gtest/gtest.h"
     28 #include "third_party/khronos/GLES2/gl2.h"
     29 #include "third_party/skia/include/core/SkImageFilter.h"
     30 #include "third_party/skia/include/core/SkMatrix.h"
     31 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
     32 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
     33 #include "ui/gfx/transform.h"
     34 
     35 using testing::_;
     36 using testing::AnyNumber;
     37 using testing::Args;
     38 using testing::AtLeast;
     39 using testing::ElementsAre;
     40 using testing::Expectation;
     41 using testing::InSequence;
     42 using testing::Mock;
     43 using testing::Return;
     44 using testing::StrictMock;
     45 
     46 namespace cc {
     47 
     48 class GLRendererTest : public testing::Test {
     49  protected:
     50   RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
     51 
     52   RenderPassList render_passes_in_draw_order_;
     53 };
     54 
     55 #define EXPECT_PROGRAM_VALID(program_binding)      \
     56   do {                                             \
     57     EXPECT_TRUE((program_binding)->program());     \
     58     EXPECT_TRUE((program_binding)->initialized()); \
     59   } while (false)
     60 
     61 // Explicitly named to be a friend in GLRenderer for shader access.
     62 class GLRendererShaderPixelTest : public GLRendererPixelTest {
     63  public:
     64   void TestShaders() {
     65     ASSERT_FALSE(renderer()->IsContextLost());
     66     EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
     67     EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
     68     EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
     69     EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
     70     TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium);
     71     TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh);
     72     ASSERT_FALSE(renderer()->IsContextLost());
     73   }
     74 
     75   void TestShadersWithTexCoordPrecision(TexCoordPrecision precision) {
     76     EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision));
     77     EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision));
     78     EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision));
     79     EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision));
     80     EXPECT_PROGRAM_VALID(
     81         renderer()->GetRenderPassColorMatrixProgram(precision));
     82     EXPECT_PROGRAM_VALID(
     83         renderer()->GetRenderPassMaskColorMatrixProgramAA(precision));
     84     EXPECT_PROGRAM_VALID(
     85         renderer()->GetRenderPassColorMatrixProgramAA(precision));
     86     EXPECT_PROGRAM_VALID(
     87         renderer()->GetRenderPassMaskColorMatrixProgram(precision));
     88     EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
     89     EXPECT_PROGRAM_VALID(
     90         renderer()->GetNonPremultipliedTextureProgram(precision));
     91     EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision));
     92     EXPECT_PROGRAM_VALID(
     93         renderer()->GetNonPremultipliedTextureBackgroundProgram(precision));
     94     EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
     95     EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision));
     96     EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision));
     97     // This is unlikely to be ever true in tests due to usage of osmesa.
     98     if (renderer()->Capabilities().using_egl_image)
     99       EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
    100     else
    101       EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
    102     TestShadersWithSamplerType(precision, SamplerType2D);
    103     TestShadersWithSamplerType(precision, SamplerType2DRect);
    104     // This is unlikely to be ever true in tests due to usage of osmesa.
    105     if (renderer()->Capabilities().using_egl_image)
    106       TestShadersWithSamplerType(precision, SamplerTypeExternalOES);
    107   }
    108 
    109   void TestShadersWithSamplerType(TexCoordPrecision precision,
    110                                   SamplerType sampler) {
    111     EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
    112     EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
    113     EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
    114     EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
    115     EXPECT_PROGRAM_VALID(
    116         renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
    117     EXPECT_PROGRAM_VALID(
    118         renderer()->GetTileProgramSwizzleAA(precision, sampler));
    119   }
    120 };
    121 
    122 namespace {
    123 
    124 #if !defined(OS_ANDROID)
    125 TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); }
    126 #endif
    127 
    128 class FakeRendererGL : public GLRenderer {
    129  public:
    130   FakeRendererGL(RendererClient* client,
    131                  const LayerTreeSettings* settings,
    132                  OutputSurface* output_surface,
    133                  ResourceProvider* resource_provider)
    134       : GLRenderer(client,
    135                    settings,
    136                    output_surface,
    137                    resource_provider,
    138                    NULL,
    139                    0) {}
    140 
    141   // GLRenderer methods.
    142 
    143   // Changing visibility to public.
    144   using GLRenderer::IsBackbufferDiscarded;
    145   using GLRenderer::DoDrawQuad;
    146   using GLRenderer::BeginDrawingFrame;
    147   using GLRenderer::FinishDrawingQuadList;
    148   using GLRenderer::stencil_enabled;
    149 };
    150 
    151 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
    152  protected:
    153   GLRendererWithDefaultHarnessTest() {
    154     output_surface_ =
    155         FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
    156     CHECK(output_surface_->BindToClient(&output_surface_client_));
    157 
    158     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
    159     resource_provider_ =
    160         ResourceProvider::Create(
    161             output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
    162             false).Pass();
    163     renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
    164                                                    &settings_,
    165                                                    output_surface_.get(),
    166                                                    resource_provider_.get()));
    167   }
    168 
    169   void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
    170 
    171   LayerTreeSettings settings_;
    172   FakeOutputSurfaceClient output_surface_client_;
    173   scoped_ptr<FakeOutputSurface> output_surface_;
    174   FakeRendererClient renderer_client_;
    175   scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
    176   scoped_ptr<ResourceProvider> resource_provider_;
    177   scoped_ptr<FakeRendererGL> renderer_;
    178 };
    179 
    180 // Closing the namespace here so that GLRendererShaderTest can take advantage
    181 // of the friend relationship with GLRenderer and all of the mock classes
    182 // declared above it.
    183 }  // namespace
    184 
    185 class GLRendererShaderTest : public GLRendererTest {
    186  protected:
    187   GLRendererShaderTest() {
    188     output_surface_ = FakeOutputSurface::Create3d().Pass();
    189     CHECK(output_surface_->BindToClient(&output_surface_client_));
    190 
    191     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
    192     resource_provider_ =
    193         ResourceProvider::Create(
    194             output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
    195             false).Pass();
    196     renderer_.reset(new FakeRendererGL(&renderer_client_,
    197                                        &settings_,
    198                                        output_surface_.get(),
    199                                        resource_provider_.get()));
    200   }
    201 
    202   void TestRenderPassProgram(TexCoordPrecision precision) {
    203     EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_[precision]);
    204     EXPECT_EQ(renderer_->render_pass_program_[precision].program(),
    205               renderer_->program_shadow_);
    206   }
    207 
    208   void TestRenderPassColorMatrixProgram(TexCoordPrecision precision) {
    209     EXPECT_PROGRAM_VALID(
    210         &renderer_->render_pass_color_matrix_program_[precision]);
    211     EXPECT_EQ(renderer_->render_pass_color_matrix_program_[precision].program(),
    212               renderer_->program_shadow_);
    213   }
    214 
    215   void TestRenderPassMaskProgram(TexCoordPrecision precision) {
    216     EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_[precision]);
    217     EXPECT_EQ(renderer_->render_pass_mask_program_[precision].program(),
    218               renderer_->program_shadow_);
    219   }
    220 
    221   void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
    222     EXPECT_PROGRAM_VALID(
    223         &renderer_->render_pass_mask_color_matrix_program_[precision]);
    224     EXPECT_EQ(
    225         renderer_->render_pass_mask_color_matrix_program_[precision].program(),
    226         renderer_->program_shadow_);
    227   }
    228 
    229   void TestRenderPassProgramAA(TexCoordPrecision precision) {
    230     EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_aa_[precision]);
    231     EXPECT_EQ(renderer_->render_pass_program_aa_[precision].program(),
    232               renderer_->program_shadow_);
    233   }
    234 
    235   void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
    236     EXPECT_PROGRAM_VALID(
    237         &renderer_->render_pass_color_matrix_program_aa_[precision]);
    238     EXPECT_EQ(
    239         renderer_->render_pass_color_matrix_program_aa_[precision].program(),
    240         renderer_->program_shadow_);
    241   }
    242 
    243   void TestRenderPassMaskProgramAA(TexCoordPrecision precision) {
    244     EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_aa_[precision]);
    245     EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision].program(),
    246               renderer_->program_shadow_);
    247   }
    248 
    249   void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
    250     EXPECT_PROGRAM_VALID(
    251         &renderer_->render_pass_mask_color_matrix_program_aa_[precision]);
    252     EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_[precision]
    253                   .program(),
    254               renderer_->program_shadow_);
    255   }
    256 
    257   void TestSolidColorProgramAA() {
    258     EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
    259     EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
    260               renderer_->program_shadow_);
    261   }
    262 
    263   LayerTreeSettings settings_;
    264   FakeOutputSurfaceClient output_surface_client_;
    265   scoped_ptr<FakeOutputSurface> output_surface_;
    266   FakeRendererClient renderer_client_;
    267   scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
    268   scoped_ptr<ResourceProvider> resource_provider_;
    269   scoped_ptr<FakeRendererGL> renderer_;
    270 };
    271 
    272 namespace {
    273 
    274 // Test GLRenderer DiscardBackbuffer functionality:
    275 // Suggest discarding framebuffer when one exists and the renderer is not
    276 // visible.
    277 // Expected: it is discarded and damage tracker is reset.
    278 TEST_F(
    279     GLRendererWithDefaultHarnessTest,
    280     SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
    281   renderer_->SetVisible(false);
    282   EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
    283   EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
    284 }
    285 
    286 // Test GLRenderer DiscardBackbuffer functionality:
    287 // Suggest discarding framebuffer when one exists and the renderer is visible.
    288 // Expected: the allocation is ignored.
    289 TEST_F(GLRendererWithDefaultHarnessTest,
    290        SuggestBackbufferNoDoNothingWhenVisible) {
    291   renderer_->SetVisible(true);
    292   EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
    293   EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
    294 }
    295 
    296 // Test GLRenderer DiscardBackbuffer functionality:
    297 // Suggest discarding framebuffer when one does not exist.
    298 // Expected: it does nothing.
    299 TEST_F(GLRendererWithDefaultHarnessTest,
    300        SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
    301   renderer_->SetVisible(false);
    302   EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
    303   EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
    304 
    305   EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
    306   EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
    307 }
    308 
    309 // Test GLRenderer DiscardBackbuffer functionality:
    310 // Begin drawing a frame while a framebuffer is discarded.
    311 // Expected: will recreate framebuffer.
    312 TEST_F(GLRendererWithDefaultHarnessTest,
    313        DiscardedBackbufferIsRecreatedForScopeDuration) {
    314   gfx::Rect viewport_rect(1, 1);
    315   renderer_->SetVisible(false);
    316   EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
    317   EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
    318 
    319   AddRenderPass(&render_passes_in_draw_order_,
    320                 RenderPass::Id(1, 0),
    321                 viewport_rect,
    322                 gfx::Transform());
    323 
    324   renderer_->SetVisible(true);
    325   renderer_->DrawFrame(&render_passes_in_draw_order_,
    326                        1.f,
    327                        viewport_rect,
    328                        viewport_rect,
    329                        false);
    330   EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
    331 
    332   SwapBuffers();
    333   EXPECT_EQ(1u, output_surface_->num_sent_frames());
    334 }
    335 
    336 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
    337   gfx::Rect viewport_rect(1, 1);
    338   EXPECT_FALSE(renderer_->stencil_enabled());
    339 
    340   output_surface_->set_has_external_stencil_test(true);
    341 
    342   TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
    343                                             RenderPass::Id(1, 0),
    344                                             viewport_rect,
    345                                             gfx::Transform());
    346   root_pass->has_transparent_background = false;
    347 
    348   renderer_->DrawFrame(&render_passes_in_draw_order_,
    349                        1.f,
    350                        viewport_rect,
    351                        viewport_rect,
    352                        false);
    353   EXPECT_TRUE(renderer_->stencil_enabled());
    354 }
    355 
    356 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
    357  public:
    358   ForbidSynchronousCallContext() {}
    359 
    360   virtual void getAttachedShaders(GLuint program,
    361                                   GLsizei max_count,
    362                                   GLsizei* count,
    363                                   GLuint* shaders) OVERRIDE {
    364     ADD_FAILURE();
    365   }
    366   virtual GLint getAttribLocation(GLuint program, const GLchar* name) OVERRIDE {
    367     ADD_FAILURE();
    368     return 0;
    369   }
    370   virtual void getBooleanv(GLenum pname, GLboolean* value) OVERRIDE {
    371     ADD_FAILURE();
    372   }
    373   virtual void getBufferParameteriv(GLenum target,
    374                                     GLenum pname,
    375                                     GLint* value) OVERRIDE {
    376     ADD_FAILURE();
    377   }
    378   virtual GLenum getError() OVERRIDE {
    379     ADD_FAILURE();
    380     return GL_NO_ERROR;
    381   }
    382   virtual void getFloatv(GLenum pname, GLfloat* value) OVERRIDE {
    383     ADD_FAILURE();
    384   }
    385   virtual void getFramebufferAttachmentParameteriv(GLenum target,
    386                                                    GLenum attachment,
    387                                                    GLenum pname,
    388                                                    GLint* value) OVERRIDE {
    389     ADD_FAILURE();
    390   }
    391   virtual void getIntegerv(GLenum pname, GLint* value) OVERRIDE {
    392     if (pname == GL_MAX_TEXTURE_SIZE) {
    393       // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
    394       *value = 1024;
    395     } else {
    396       ADD_FAILURE();
    397     }
    398   }
    399 
    400   // We allow querying the shader compilation and program link status in debug
    401   // mode, but not release.
    402   virtual void getProgramiv(GLuint program,
    403                             GLenum pname,
    404                             GLint* value) OVERRIDE {
    405 #ifndef NDEBUG
    406     *value = 1;
    407 #else
    408     ADD_FAILURE();
    409 #endif
    410   }
    411 
    412   virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
    413 #ifndef NDEBUG
    414     *value = 1;
    415 #else
    416     ADD_FAILURE();
    417 #endif
    418   }
    419 
    420   virtual void getRenderbufferParameteriv(GLenum target,
    421                                           GLenum pname,
    422                                           GLint* value) OVERRIDE {
    423     ADD_FAILURE();
    424   }
    425 
    426   virtual void getShaderPrecisionFormat(GLenum shadertype,
    427                                         GLenum precisiontype,
    428                                         GLint* range,
    429                                         GLint* precision) OVERRIDE {
    430     ADD_FAILURE();
    431   }
    432   virtual void getTexParameterfv(GLenum target,
    433                                  GLenum pname,
    434                                  GLfloat* value) OVERRIDE {
    435     ADD_FAILURE();
    436   }
    437   virtual void getTexParameteriv(GLenum target,
    438                                  GLenum pname,
    439                                  GLint* value) OVERRIDE {
    440     ADD_FAILURE();
    441   }
    442   virtual void getUniformfv(GLuint program,
    443                             GLint location,
    444                             GLfloat* value) OVERRIDE {
    445     ADD_FAILURE();
    446   }
    447   virtual void getUniformiv(GLuint program,
    448                             GLint location,
    449                             GLint* value) OVERRIDE {
    450     ADD_FAILURE();
    451   }
    452   virtual GLint getUniformLocation(GLuint program,
    453                                    const GLchar* name) OVERRIDE {
    454     ADD_FAILURE();
    455     return 0;
    456   }
    457   virtual void getVertexAttribfv(GLuint index,
    458                                  GLenum pname,
    459                                  GLfloat* value) OVERRIDE {
    460     ADD_FAILURE();
    461   }
    462   virtual void getVertexAttribiv(GLuint index,
    463                                  GLenum pname,
    464                                  GLint* value) OVERRIDE {
    465     ADD_FAILURE();
    466   }
    467   virtual GLsizeiptr getVertexAttribOffset(GLuint index,
    468                                            GLenum pname) OVERRIDE {
    469     ADD_FAILURE();
    470     return 0;
    471   }
    472 };
    473 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
    474   FakeOutputSurfaceClient output_surface_client;
    475   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    476       scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
    477   CHECK(output_surface->BindToClient(&output_surface_client));
    478 
    479   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    480       new TestSharedBitmapManager());
    481   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    482       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    483 
    484   LayerTreeSettings settings;
    485   FakeRendererClient renderer_client;
    486   FakeRendererGL renderer(&renderer_client,
    487                           &settings,
    488                           output_surface.get(),
    489                           resource_provider.get());
    490 }
    491 
    492 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
    493  public:
    494   LoseContextOnFirstGetContext() {}
    495 
    496   virtual void getProgramiv(GLuint program,
    497                             GLenum pname,
    498                             GLint* value) OVERRIDE {
    499     context_lost_ = true;
    500     *value = 0;
    501   }
    502 
    503   virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
    504     context_lost_ = true;
    505     *value = 0;
    506   }
    507 };
    508 
    509 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
    510   FakeOutputSurfaceClient output_surface_client;
    511   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    512       scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
    513   CHECK(output_surface->BindToClient(&output_surface_client));
    514 
    515   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    516       new TestSharedBitmapManager());
    517   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    518       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    519 
    520   LayerTreeSettings settings;
    521   FakeRendererClient renderer_client;
    522   FakeRendererGL renderer(&renderer_client,
    523                           &settings,
    524                           output_surface.get(),
    525                           resource_provider.get());
    526 }
    527 
    528 class ClearCountingContext : public TestWebGraphicsContext3D {
    529  public:
    530   ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
    531 
    532   MOCK_METHOD3(discardFramebufferEXT,
    533                void(GLenum target,
    534                     GLsizei numAttachments,
    535                     const GLenum* attachments));
    536   MOCK_METHOD1(clear, void(GLbitfield mask));
    537 };
    538 
    539 TEST_F(GLRendererTest, OpaqueBackground) {
    540   scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
    541   ClearCountingContext* context = context_owned.get();
    542 
    543   FakeOutputSurfaceClient output_surface_client;
    544   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    545       context_owned.PassAs<TestWebGraphicsContext3D>()));
    546   CHECK(output_surface->BindToClient(&output_surface_client));
    547 
    548   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    549       new TestSharedBitmapManager());
    550   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    551       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    552 
    553   LayerTreeSettings settings;
    554   FakeRendererClient renderer_client;
    555   FakeRendererGL renderer(&renderer_client,
    556                           &settings,
    557                           output_surface.get(),
    558                           resource_provider.get());
    559 
    560   gfx::Rect viewport_rect(1, 1);
    561   TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
    562                                             RenderPass::Id(1, 0),
    563                                             viewport_rect,
    564                                             gfx::Transform());
    565   root_pass->has_transparent_background = false;
    566 
    567   // On DEBUG builds, render passes with opaque background clear to blue to
    568   // easily see regions that were not drawn on the screen.
    569   EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
    570       .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
    571       .Times(1);
    572 #ifdef NDEBUG
    573   EXPECT_CALL(*context, clear(_)).Times(0);
    574 #else
    575   EXPECT_CALL(*context, clear(_)).Times(1);
    576 #endif
    577   renderer.DrawFrame(&render_passes_in_draw_order_,
    578                      1.f,
    579                      viewport_rect,
    580                      viewport_rect,
    581                      false);
    582   Mock::VerifyAndClearExpectations(context);
    583 }
    584 
    585 TEST_F(GLRendererTest, TransparentBackground) {
    586   scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
    587   ClearCountingContext* context = context_owned.get();
    588 
    589   FakeOutputSurfaceClient output_surface_client;
    590   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    591       context_owned.PassAs<TestWebGraphicsContext3D>()));
    592   CHECK(output_surface->BindToClient(&output_surface_client));
    593 
    594   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    595       new TestSharedBitmapManager());
    596   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    597       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    598 
    599   LayerTreeSettings settings;
    600   FakeRendererClient renderer_client;
    601   FakeRendererGL renderer(&renderer_client,
    602                           &settings,
    603                           output_surface.get(),
    604                           resource_provider.get());
    605 
    606   gfx::Rect viewport_rect(1, 1);
    607   TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
    608                                             RenderPass::Id(1, 0),
    609                                             viewport_rect,
    610                                             gfx::Transform());
    611   root_pass->has_transparent_background = true;
    612 
    613   EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
    614   EXPECT_CALL(*context, clear(_)).Times(1);
    615   renderer.DrawFrame(&render_passes_in_draw_order_,
    616                      1.f,
    617                      viewport_rect,
    618                      viewport_rect,
    619                      false);
    620 
    621   Mock::VerifyAndClearExpectations(context);
    622 }
    623 
    624 TEST_F(GLRendererTest, OffscreenOutputSurface) {
    625   scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
    626   ClearCountingContext* context = context_owned.get();
    627 
    628   FakeOutputSurfaceClient output_surface_client;
    629   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateOffscreen(
    630       context_owned.PassAs<TestWebGraphicsContext3D>()));
    631   CHECK(output_surface->BindToClient(&output_surface_client));
    632 
    633   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    634       new TestSharedBitmapManager());
    635   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    636       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    637 
    638   LayerTreeSettings settings;
    639   FakeRendererClient renderer_client;
    640   FakeRendererGL renderer(&renderer_client,
    641                           &settings,
    642                           output_surface.get(),
    643                           resource_provider.get());
    644 
    645   gfx::Rect viewport_rect(1, 1);
    646   AddRenderPass(&render_passes_in_draw_order_,
    647                 RenderPass::Id(1, 0),
    648                 viewport_rect,
    649                 gfx::Transform());
    650 
    651   EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
    652       .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
    653       .Times(1);
    654   EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
    655   renderer.DrawFrame(&render_passes_in_draw_order_,
    656                      1.f,
    657                      viewport_rect,
    658                      viewport_rect,
    659                      false);
    660   Mock::VerifyAndClearExpectations(context);
    661 }
    662 
    663 class VisibilityChangeIsLastCallTrackingContext
    664     : public TestWebGraphicsContext3D {
    665  public:
    666   VisibilityChangeIsLastCallTrackingContext()
    667       : last_call_was_set_visibility_(false) {}
    668 
    669   // TestWebGraphicsContext3D methods.
    670   virtual void flush() OVERRIDE { last_call_was_set_visibility_ = false; }
    671   virtual void deleteTexture(GLuint) OVERRIDE {
    672     last_call_was_set_visibility_ = false;
    673   }
    674   virtual void deleteFramebuffer(GLuint) OVERRIDE {
    675     last_call_was_set_visibility_ = false;
    676   }
    677   virtual void deleteQueryEXT(GLuint) OVERRIDE {
    678     last_call_was_set_visibility_ = false;
    679   }
    680   virtual void deleteRenderbuffer(GLuint) OVERRIDE {
    681     last_call_was_set_visibility_ = false;
    682   }
    683 
    684   // Methods added for test.
    685   void set_last_call_was_visibility(bool visible) {
    686     DCHECK(last_call_was_set_visibility_ == false);
    687     last_call_was_set_visibility_ = true;
    688   }
    689   bool last_call_was_set_visibility() const {
    690     return last_call_was_set_visibility_;
    691   }
    692 
    693  private:
    694   bool last_call_was_set_visibility_;
    695 };
    696 
    697 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
    698   scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
    699       new VisibilityChangeIsLastCallTrackingContext);
    700   VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
    701 
    702   scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(
    703       context_owned.PassAs<TestWebGraphicsContext3D>());
    704 
    705   provider->support()->SetSurfaceVisibleCallback(base::Bind(
    706       &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
    707       base::Unretained(context)));
    708 
    709   FakeOutputSurfaceClient output_surface_client;
    710   scoped_ptr<OutputSurface> output_surface(
    711       FakeOutputSurface::Create3d(provider));
    712   CHECK(output_surface->BindToClient(&output_surface_client));
    713 
    714   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    715       new TestSharedBitmapManager());
    716   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    717       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    718 
    719   LayerTreeSettings settings;
    720   FakeRendererClient renderer_client;
    721   FakeRendererGL renderer(&renderer_client,
    722                           &settings,
    723                           output_surface.get(),
    724                           resource_provider.get());
    725 
    726   gfx::Rect viewport_rect(1, 1);
    727   AddRenderPass(&render_passes_in_draw_order_,
    728                 RenderPass::Id(1, 0),
    729                 viewport_rect,
    730                 gfx::Transform());
    731 
    732   // Ensure that the call to SetSurfaceVisible is the last call issue to the
    733   // GPU process, after glFlush is called, and after the RendererClient's
    734   // SetManagedMemoryPolicy is called. Plumb this tracking between both the
    735   // RenderClient and the Context by giving them both a pointer to a variable on
    736   // the stack.
    737   renderer.SetVisible(true);
    738   renderer.DrawFrame(&render_passes_in_draw_order_,
    739                      1.f,
    740                      viewport_rect,
    741                      viewport_rect,
    742                      false);
    743   renderer.SetVisible(false);
    744   EXPECT_TRUE(context->last_call_was_set_visibility());
    745 }
    746 
    747 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
    748  public:
    749   TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
    750     test_capabilities_.gpu.egl_image_external = true;
    751   }
    752 
    753   MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
    754   MOCK_METHOD4(drawElements,
    755                void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
    756 
    757   virtual void activeTexture(GLenum texture) {
    758     EXPECT_NE(texture, active_texture_);
    759     active_texture_ = texture;
    760   }
    761 
    762   GLenum active_texture() const { return active_texture_; }
    763 
    764  private:
    765   GLenum active_texture_;
    766 };
    767 
    768 TEST_F(GLRendererTest, ActiveTextureState) {
    769   scoped_ptr<TextureStateTrackingContext> context_owned(
    770       new TextureStateTrackingContext);
    771   TextureStateTrackingContext* context = context_owned.get();
    772 
    773   FakeOutputSurfaceClient output_surface_client;
    774   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    775       context_owned.PassAs<TestWebGraphicsContext3D>()));
    776   CHECK(output_surface->BindToClient(&output_surface_client));
    777 
    778   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    779       new TestSharedBitmapManager());
    780   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    781       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    782 
    783   LayerTreeSettings settings;
    784   FakeRendererClient renderer_client;
    785   FakeRendererGL renderer(&renderer_client,
    786                           &settings,
    787                           output_surface.get(),
    788                           resource_provider.get());
    789 
    790   // During initialization we are allowed to set any texture parameters.
    791   EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
    792 
    793   RenderPass::Id id(1, 1);
    794   TestRenderPass* root_pass = AddRenderPass(
    795       &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
    796   root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
    797                                       RenderPass::Id(2, 1));
    798 
    799   renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
    800 
    801   // Set up expected texture filter state transitions that match the quads
    802   // created in AppendOneOfEveryQuadType().
    803   Mock::VerifyAndClearExpectations(context);
    804   {
    805     InSequence sequence;
    806 
    807     // yuv_quad is drawn with the default linear filter.
    808     EXPECT_CALL(*context, drawElements(_, _, _, _));
    809 
    810     // tile_quad is drawn with GL_NEAREST because it is not transformed or
    811     // scaled.
    812     EXPECT_CALL(
    813         *context,
    814         texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    815     EXPECT_CALL(
    816         *context,
    817         texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
    818     EXPECT_CALL(*context, drawElements(_, _, _, _));
    819 
    820     // transformed_tile_quad uses GL_LINEAR.
    821     EXPECT_CALL(*context, drawElements(_, _, _, _));
    822 
    823     // scaled_tile_quad also uses GL_LINEAR.
    824     EXPECT_CALL(*context, drawElements(_, _, _, _));
    825 
    826     // The remaining quads also use GL_LINEAR because nearest neighbor
    827     // filtering is currently only used with tile quads.
    828     EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6);
    829   }
    830 
    831   gfx::Rect viewport_rect(100, 100);
    832   renderer.DrawFrame(&render_passes_in_draw_order_,
    833                      1.f,
    834                      viewport_rect,
    835                      viewport_rect,
    836                      false);
    837   Mock::VerifyAndClearExpectations(context);
    838 }
    839 
    840 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
    841  public:
    842   MOCK_METHOD1(clear, void(GLbitfield mask));
    843   MOCK_METHOD4(drawElements,
    844                void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
    845 };
    846 
    847 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
    848   scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
    849       new NoClearRootRenderPassMockContext);
    850   NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
    851 
    852   FakeOutputSurfaceClient output_surface_client;
    853   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    854       mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
    855   CHECK(output_surface->BindToClient(&output_surface_client));
    856 
    857   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    858       new TestSharedBitmapManager());
    859   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    860       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    861 
    862   LayerTreeSettings settings;
    863   settings.should_clear_root_render_pass = false;
    864 
    865   FakeRendererClient renderer_client;
    866   FakeRendererGL renderer(&renderer_client,
    867                           &settings,
    868                           output_surface.get(),
    869                           resource_provider.get());
    870 
    871   gfx::Rect viewport_rect(10, 10);
    872 
    873   RenderPass::Id root_pass_id(1, 0);
    874   TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
    875                                             root_pass_id,
    876                                             viewport_rect,
    877                                             gfx::Transform());
    878   AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
    879 
    880   RenderPass::Id child_pass_id(2, 0);
    881   TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
    882                                              child_pass_id,
    883                                              viewport_rect,
    884                                              gfx::Transform());
    885   AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
    886 
    887   AddRenderPassQuad(root_pass, child_pass);
    888 
    889 #ifdef NDEBUG
    890   GLint clear_bits = GL_COLOR_BUFFER_BIT;
    891 #else
    892   GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
    893 #endif
    894 
    895   // First render pass is not the root one, clearing should happen.
    896   EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
    897 
    898   Expectation first_render_pass =
    899       EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
    900 
    901   // The second render pass is the root one, clearing should be prevented.
    902   EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
    903       first_render_pass);
    904 
    905   EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
    906       first_render_pass);
    907 
    908   renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
    909   renderer.DrawFrame(&render_passes_in_draw_order_,
    910                      1.f,
    911                      viewport_rect,
    912                      viewport_rect,
    913                      false);
    914 
    915   // In multiple render passes all but the root pass should clear the
    916   // framebuffer.
    917   Mock::VerifyAndClearExpectations(&mock_context);
    918 }
    919 
    920 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
    921  public:
    922   ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
    923 
    924   virtual void clear(GLbitfield) OVERRIDE { EXPECT_FALSE(scissor_enabled_); }
    925 
    926   virtual void enable(GLenum cap) OVERRIDE {
    927     if (cap == GL_SCISSOR_TEST)
    928       scissor_enabled_ = true;
    929   }
    930 
    931   virtual void disable(GLenum cap) OVERRIDE {
    932     if (cap == GL_SCISSOR_TEST)
    933       scissor_enabled_ = false;
    934   }
    935 
    936  private:
    937   bool scissor_enabled_;
    938 };
    939 
    940 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
    941   scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
    942       new ScissorTestOnClearCheckingContext);
    943 
    944   FakeOutputSurfaceClient output_surface_client;
    945   scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
    946       context_owned.PassAs<TestWebGraphicsContext3D>()));
    947   CHECK(output_surface->BindToClient(&output_surface_client));
    948 
    949   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
    950       new TestSharedBitmapManager());
    951   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
    952       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
    953 
    954   LayerTreeSettings settings;
    955   FakeRendererClient renderer_client;
    956   FakeRendererGL renderer(&renderer_client,
    957                           &settings,
    958                           output_surface.get(),
    959                           resource_provider.get());
    960   EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
    961 
    962   gfx::Rect viewport_rect(1, 1);
    963 
    964   gfx::Rect grand_child_rect(25, 25);
    965   RenderPass::Id grand_child_pass_id(3, 0);
    966   TestRenderPass* grand_child_pass =
    967       AddRenderPass(&render_passes_in_draw_order_,
    968                     grand_child_pass_id,
    969                     grand_child_rect,
    970                     gfx::Transform());
    971   AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
    972 
    973   gfx::Rect child_rect(50, 50);
    974   RenderPass::Id child_pass_id(2, 0);
    975   TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
    976                                              child_pass_id,
    977                                              child_rect,
    978                                              gfx::Transform());
    979   AddQuad(child_pass, child_rect, SK_ColorBLUE);
    980 
    981   RenderPass::Id root_pass_id(1, 0);
    982   TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
    983                                             root_pass_id,
    984                                             viewport_rect,
    985                                             gfx::Transform());
    986   AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
    987 
    988   AddRenderPassQuad(root_pass, child_pass);
    989   AddRenderPassQuad(child_pass, grand_child_pass);
    990 
    991   renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
    992   renderer.DrawFrame(&render_passes_in_draw_order_,
    993                      1.f,
    994                      viewport_rect,
    995                      viewport_rect,
    996                      false);
    997 }
    998 
    999 class DiscardCheckingContext : public TestWebGraphicsContext3D {
   1000  public:
   1001   DiscardCheckingContext() : discarded_(0) {
   1002     set_have_post_sub_buffer(true);
   1003     set_have_discard_framebuffer(true);
   1004   }
   1005 
   1006   virtual void discardFramebufferEXT(GLenum target,
   1007                                      GLsizei numAttachments,
   1008                                      const GLenum* attachments) OVERRIDE {
   1009     ++discarded_;
   1010   }
   1011 
   1012   int discarded() const { return discarded_; }
   1013   void reset() { discarded_ = 0; }
   1014 
   1015  private:
   1016   int discarded_;
   1017 };
   1018 
   1019 class NonReshapableOutputSurface : public FakeOutputSurface {
   1020  public:
   1021   explicit NonReshapableOutputSurface(
   1022       scoped_ptr<TestWebGraphicsContext3D> context3d)
   1023       : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
   1024                           false) {
   1025     surface_size_ = gfx::Size(500, 500);
   1026   }
   1027   virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {}
   1028   void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
   1029 };
   1030 
   1031 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
   1032   scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
   1033   DiscardCheckingContext* context = context_owned.get();
   1034 
   1035   FakeOutputSurfaceClient output_surface_client;
   1036   scoped_ptr<NonReshapableOutputSurface> output_surface(
   1037       new NonReshapableOutputSurface(
   1038           context_owned.PassAs<TestWebGraphicsContext3D>()));
   1039   CHECK(output_surface->BindToClient(&output_surface_client));
   1040   output_surface->set_fixed_size(gfx::Size(100, 100));
   1041 
   1042   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
   1043       new TestSharedBitmapManager());
   1044   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
   1045       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
   1046 
   1047   LayerTreeSettings settings;
   1048   settings.partial_swap_enabled = true;
   1049   FakeRendererClient renderer_client;
   1050   FakeRendererGL renderer(&renderer_client,
   1051                           &settings,
   1052                           output_surface.get(),
   1053                           resource_provider.get());
   1054   EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
   1055 
   1056   gfx::Rect viewport_rect(100, 100);
   1057   gfx::Rect clip_rect(100, 100);
   1058 
   1059   {
   1060     // Partial frame, should not discard.
   1061     RenderPass::Id root_pass_id(1, 0);
   1062     TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1063                                               root_pass_id,
   1064                                               viewport_rect,
   1065                                               gfx::Transform());
   1066     AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
   1067     root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
   1068 
   1069     renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1070     renderer.DrawFrame(&render_passes_in_draw_order_,
   1071                        1.f,
   1072                        viewport_rect,
   1073                        clip_rect,
   1074                        false);
   1075     EXPECT_EQ(0, context->discarded());
   1076     context->reset();
   1077   }
   1078   {
   1079     // Full frame, should discard.
   1080     RenderPass::Id root_pass_id(1, 0);
   1081     TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1082                                               root_pass_id,
   1083                                               viewport_rect,
   1084                                               gfx::Transform());
   1085     AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
   1086     root_pass->damage_rect = root_pass->output_rect;
   1087 
   1088     renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1089     renderer.DrawFrame(&render_passes_in_draw_order_,
   1090                        1.f,
   1091                        viewport_rect,
   1092                        clip_rect,
   1093                        false);
   1094     EXPECT_EQ(1, context->discarded());
   1095     context->reset();
   1096   }
   1097   {
   1098     // Full frame, external scissor is set, should not discard.
   1099     output_surface->set_has_external_stencil_test(true);
   1100     RenderPass::Id root_pass_id(1, 0);
   1101     TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1102                                               root_pass_id,
   1103                                               viewport_rect,
   1104                                               gfx::Transform());
   1105     AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
   1106     root_pass->damage_rect = root_pass->output_rect;
   1107     root_pass->has_transparent_background = false;
   1108 
   1109     renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1110     renderer.DrawFrame(&render_passes_in_draw_order_,
   1111                        1.f,
   1112                        viewport_rect,
   1113                        clip_rect,
   1114                        false);
   1115     EXPECT_EQ(0, context->discarded());
   1116     context->reset();
   1117     output_surface->set_has_external_stencil_test(false);
   1118   }
   1119   {
   1120     // Full frame, clipped, should not discard.
   1121     clip_rect = gfx::Rect(10, 10, 10, 10);
   1122     RenderPass::Id root_pass_id(1, 0);
   1123     TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1124                                               root_pass_id,
   1125                                               viewport_rect,
   1126                                               gfx::Transform());
   1127     AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
   1128     root_pass->damage_rect = root_pass->output_rect;
   1129 
   1130     renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1131     renderer.DrawFrame(&render_passes_in_draw_order_,
   1132                        1.f,
   1133                        viewport_rect,
   1134                        clip_rect,
   1135                        false);
   1136     EXPECT_EQ(0, context->discarded());
   1137     context->reset();
   1138   }
   1139   {
   1140     // Full frame, doesn't cover the surface, should not discard.
   1141     viewport_rect = gfx::Rect(10, 10, 10, 10);
   1142     RenderPass::Id root_pass_id(1, 0);
   1143     TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1144                                               root_pass_id,
   1145                                               viewport_rect,
   1146                                               gfx::Transform());
   1147     AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
   1148     root_pass->damage_rect = root_pass->output_rect;
   1149 
   1150     renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1151     renderer.DrawFrame(&render_passes_in_draw_order_,
   1152                        1.f,
   1153                        viewport_rect,
   1154                        clip_rect,
   1155                        false);
   1156     EXPECT_EQ(0, context->discarded());
   1157     context->reset();
   1158   }
   1159   {
   1160     // Full frame, doesn't cover the surface (no offset), should not discard.
   1161     clip_rect = gfx::Rect(100, 100);
   1162     viewport_rect = gfx::Rect(50, 50);
   1163     RenderPass::Id root_pass_id(1, 0);
   1164     TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1165                                               root_pass_id,
   1166                                               viewport_rect,
   1167                                               gfx::Transform());
   1168     AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
   1169     root_pass->damage_rect = root_pass->output_rect;
   1170 
   1171     renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1172     renderer.DrawFrame(&render_passes_in_draw_order_,
   1173                        1.f,
   1174                        viewport_rect,
   1175                        clip_rect,
   1176                        false);
   1177     EXPECT_EQ(0, context->discarded());
   1178     context->reset();
   1179   }
   1180 }
   1181 
   1182 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
   1183  public:
   1184   FlippedScissorAndViewportContext()
   1185       : did_call_viewport_(false), did_call_scissor_(false) {}
   1186   virtual ~FlippedScissorAndViewportContext() {
   1187     EXPECT_TRUE(did_call_viewport_);
   1188     EXPECT_TRUE(did_call_scissor_);
   1189   }
   1190 
   1191   virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height)
   1192       OVERRIDE {
   1193     EXPECT_EQ(10, x);
   1194     EXPECT_EQ(390, y);
   1195     EXPECT_EQ(100, width);
   1196     EXPECT_EQ(100, height);
   1197     did_call_viewport_ = true;
   1198   }
   1199 
   1200   virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height)
   1201       OVERRIDE {
   1202     EXPECT_EQ(30, x);
   1203     EXPECT_EQ(450, y);
   1204     EXPECT_EQ(20, width);
   1205     EXPECT_EQ(20, height);
   1206     did_call_scissor_ = true;
   1207   }
   1208 
   1209  private:
   1210   bool did_call_viewport_;
   1211   bool did_call_scissor_;
   1212 };
   1213 
   1214 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
   1215   // In Android WebView, the OutputSurface is unable to respect reshape() calls
   1216   // and maintains a fixed size. This test verifies that glViewport and
   1217   // glScissor's Y coordinate is flipped correctly in this environment, and that
   1218   // the glViewport can be at a nonzero origin within the surface.
   1219   scoped_ptr<FlippedScissorAndViewportContext> context_owned(
   1220       new FlippedScissorAndViewportContext);
   1221 
   1222   FakeOutputSurfaceClient output_surface_client;
   1223   scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface(
   1224       context_owned.PassAs<TestWebGraphicsContext3D>()));
   1225   CHECK(output_surface->BindToClient(&output_surface_client));
   1226 
   1227   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
   1228       new TestSharedBitmapManager());
   1229   scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
   1230       output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
   1231 
   1232   LayerTreeSettings settings;
   1233   FakeRendererClient renderer_client;
   1234   FakeRendererGL renderer(&renderer_client,
   1235                           &settings,
   1236                           output_surface.get(),
   1237                           resource_provider.get());
   1238   EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
   1239 
   1240   gfx::Rect device_viewport_rect(10, 10, 100, 100);
   1241   gfx::Rect viewport_rect(device_viewport_rect.size());
   1242   gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
   1243 
   1244   RenderPass::Id root_pass_id(1, 0);
   1245   TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1246                                             root_pass_id,
   1247                                             viewport_rect,
   1248                                             gfx::Transform());
   1249   AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
   1250 
   1251   renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1252   renderer.DrawFrame(&render_passes_in_draw_order_,
   1253                      1.f,
   1254                      device_viewport_rect,
   1255                      device_viewport_rect,
   1256                      false);
   1257 }
   1258 
   1259 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
   1260   gfx::Rect viewport_rect(1, 1);
   1261 
   1262   gfx::Rect child_rect(50, 50);
   1263   RenderPass::Id child_pass_id(2, 0);
   1264   TestRenderPass* child_pass;
   1265 
   1266   RenderPass::Id root_pass_id(1, 0);
   1267   TestRenderPass* root_pass;
   1268 
   1269   ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
   1270       gfx::Size(20, 12),
   1271       GL_CLAMP_TO_EDGE,
   1272       ResourceProvider::TextureUsageAny,
   1273       resource_provider_->best_texture_format());
   1274   resource_provider_->AllocateForTesting(mask);
   1275 
   1276   SkScalar matrix[20];
   1277   float amount = 0.5f;
   1278   matrix[0] = 0.213f + 0.787f * amount;
   1279   matrix[1] = 0.715f - 0.715f * amount;
   1280   matrix[2] = 1.f - (matrix[0] + matrix[1]);
   1281   matrix[3] = matrix[4] = 0;
   1282   matrix[5] = 0.213f - 0.213f * amount;
   1283   matrix[6] = 0.715f + 0.285f * amount;
   1284   matrix[7] = 1.f - (matrix[5] + matrix[6]);
   1285   matrix[8] = matrix[9] = 0;
   1286   matrix[10] = 0.213f - 0.213f * amount;
   1287   matrix[11] = 0.715f - 0.715f * amount;
   1288   matrix[12] = 1.f - (matrix[10] + matrix[11]);
   1289   matrix[13] = matrix[14] = 0;
   1290   matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
   1291   matrix[18] = 1;
   1292   skia::RefPtr<SkColorFilter> color_filter(
   1293       skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
   1294   skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
   1295       SkColorFilterImageFilter::Create(color_filter.get(), NULL));
   1296   FilterOperations filters;
   1297   filters.Append(FilterOperation::CreateReferenceFilter(filter));
   1298 
   1299   gfx::Transform transform_causing_aa;
   1300   transform_causing_aa.Rotate(20.0);
   1301 
   1302   // RenderPassProgram
   1303   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1304                              child_pass_id,
   1305                              child_rect,
   1306                              gfx::Transform());
   1307 
   1308   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1309                             root_pass_id,
   1310                             viewport_rect,
   1311                             gfx::Transform());
   1312 
   1313   AddRenderPassQuad(
   1314       root_pass, child_pass, 0, FilterOperations(), gfx::Transform());
   1315 
   1316   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1317   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1318                        1.f,
   1319                        viewport_rect,
   1320                        viewport_rect,
   1321                        false);
   1322   TestRenderPassProgram(TexCoordPrecisionMedium);
   1323 
   1324   // RenderPassColorMatrixProgram
   1325   render_passes_in_draw_order_.clear();
   1326 
   1327   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1328                              child_pass_id,
   1329                              child_rect,
   1330                              transform_causing_aa);
   1331 
   1332   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1333                             root_pass_id,
   1334                             viewport_rect,
   1335                             gfx::Transform());
   1336 
   1337   AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform());
   1338 
   1339   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1340   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1341                        1.f,
   1342                        viewport_rect,
   1343                        viewport_rect,
   1344                        false);
   1345   TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium);
   1346 
   1347   // RenderPassMaskProgram
   1348   render_passes_in_draw_order_.clear();
   1349 
   1350   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1351                              child_pass_id,
   1352                              child_rect,
   1353                              gfx::Transform());
   1354 
   1355   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1356                             root_pass_id,
   1357                             viewport_rect,
   1358                             gfx::Transform());
   1359 
   1360   AddRenderPassQuad(
   1361       root_pass, child_pass, mask, FilterOperations(), gfx::Transform());
   1362 
   1363   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1364   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1365                        1.f,
   1366                        viewport_rect,
   1367                        viewport_rect,
   1368                        false);
   1369   TestRenderPassMaskProgram(TexCoordPrecisionMedium);
   1370 
   1371   // RenderPassMaskColorMatrixProgram
   1372   render_passes_in_draw_order_.clear();
   1373 
   1374   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1375                              child_pass_id,
   1376                              child_rect,
   1377                              gfx::Transform());
   1378 
   1379   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1380                             root_pass_id,
   1381                             viewport_rect,
   1382                             gfx::Transform());
   1383 
   1384   AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform());
   1385 
   1386   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1387   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1388                        1.f,
   1389                        viewport_rect,
   1390                        viewport_rect,
   1391                        false);
   1392   TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium);
   1393 
   1394   // RenderPassProgramAA
   1395   render_passes_in_draw_order_.clear();
   1396 
   1397   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1398                              child_pass_id,
   1399                              child_rect,
   1400                              transform_causing_aa);
   1401 
   1402   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1403                             root_pass_id,
   1404                             viewport_rect,
   1405                             gfx::Transform());
   1406 
   1407   AddRenderPassQuad(
   1408       root_pass, child_pass, 0, FilterOperations(), transform_causing_aa);
   1409 
   1410   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1411   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1412                        1.f,
   1413                        viewport_rect,
   1414                        viewport_rect,
   1415                        false);
   1416   TestRenderPassProgramAA(TexCoordPrecisionMedium);
   1417 
   1418   // RenderPassColorMatrixProgramAA
   1419   render_passes_in_draw_order_.clear();
   1420 
   1421   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1422                              child_pass_id,
   1423                              child_rect,
   1424                              transform_causing_aa);
   1425 
   1426   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1427                             root_pass_id,
   1428                             viewport_rect,
   1429                             gfx::Transform());
   1430 
   1431   AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa);
   1432 
   1433   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1434   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1435                        1.f,
   1436                        viewport_rect,
   1437                        viewport_rect,
   1438                        false);
   1439   TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium);
   1440 
   1441   // RenderPassMaskProgramAA
   1442   render_passes_in_draw_order_.clear();
   1443 
   1444   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1445                              child_pass_id,
   1446                              child_rect,
   1447                              transform_causing_aa);
   1448 
   1449   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1450                             root_pass_id,
   1451                             viewport_rect,
   1452                             gfx::Transform());
   1453 
   1454   AddRenderPassQuad(
   1455       root_pass, child_pass, mask, FilterOperations(), transform_causing_aa);
   1456 
   1457   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1458   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1459                        1.f,
   1460                        viewport_rect,
   1461                        viewport_rect,
   1462                        false);
   1463   TestRenderPassMaskProgramAA(TexCoordPrecisionMedium);
   1464 
   1465   // RenderPassMaskColorMatrixProgramAA
   1466   render_passes_in_draw_order_.clear();
   1467 
   1468   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1469                              child_pass_id,
   1470                              child_rect,
   1471                              transform_causing_aa);
   1472 
   1473   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1474                             root_pass_id,
   1475                             viewport_rect,
   1476                             transform_causing_aa);
   1477 
   1478   AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa);
   1479 
   1480   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1481   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1482                        1.f,
   1483                        viewport_rect,
   1484                        viewport_rect,
   1485                        false);
   1486   TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium);
   1487 }
   1488 
   1489 // At this time, the AA code path cannot be taken if the surface's rect would
   1490 // project incorrectly by the given transform, because of w<0 clipping.
   1491 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
   1492   gfx::Rect child_rect(50, 50);
   1493   RenderPass::Id child_pass_id(2, 0);
   1494   TestRenderPass* child_pass;
   1495 
   1496   gfx::Rect viewport_rect(1, 1);
   1497   RenderPass::Id root_pass_id(1, 0);
   1498   TestRenderPass* root_pass;
   1499 
   1500   gfx::Transform transform_preventing_aa;
   1501   transform_preventing_aa.ApplyPerspectiveDepth(40.0);
   1502   transform_preventing_aa.RotateAboutYAxis(-20.0);
   1503   transform_preventing_aa.Scale(30.0, 1.0);
   1504 
   1505   // Verify that the test transform and test rect actually do cause the clipped
   1506   // flag to trigger. Otherwise we are not testing the intended scenario.
   1507   bool clipped = false;
   1508   MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
   1509   ASSERT_TRUE(clipped);
   1510 
   1511   child_pass = AddRenderPass(&render_passes_in_draw_order_,
   1512                              child_pass_id,
   1513                              child_rect,
   1514                              transform_preventing_aa);
   1515 
   1516   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1517                             root_pass_id,
   1518                             viewport_rect,
   1519                             gfx::Transform());
   1520 
   1521   AddRenderPassQuad(
   1522       root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa);
   1523 
   1524   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1525   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1526                        1.f,
   1527                        viewport_rect,
   1528                        viewport_rect,
   1529                        false);
   1530 
   1531   // If use_aa incorrectly ignores clipping, it will use the
   1532   // RenderPassProgramAA shader instead of the RenderPassProgram.
   1533   TestRenderPassProgram(TexCoordPrecisionMedium);
   1534 }
   1535 
   1536 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
   1537   gfx::Rect viewport_rect(1, 1);
   1538   RenderPass::Id root_pass_id(1, 0);
   1539   TestRenderPass* root_pass;
   1540 
   1541   gfx::Transform pixel_aligned_transform_causing_aa;
   1542   pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
   1543   pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
   1544 
   1545   root_pass = AddRenderPass(&render_passes_in_draw_order_,
   1546                             root_pass_id,
   1547                             viewport_rect,
   1548                             gfx::Transform());
   1549   AddTransformedQuad(root_pass,
   1550                      viewport_rect,
   1551                      SK_ColorYELLOW,
   1552                      pixel_aligned_transform_causing_aa);
   1553 
   1554   renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
   1555   renderer_->DrawFrame(&render_passes_in_draw_order_,
   1556                        1.f,
   1557                        viewport_rect,
   1558                        viewport_rect,
   1559                        false);
   1560 
   1561   TestSolidColorProgramAA();
   1562 }
   1563 
   1564 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
   1565  public:
   1566   OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
   1567 
   1568   // Specifically override methods even if they are unused (used in conjunction
   1569   // with StrictMock). We need to make sure that GLRenderer does not issue
   1570   // framebuffer-related GLuint calls directly. Instead these are supposed to go
   1571   // through the OutputSurface abstraction.
   1572   MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
   1573   MOCK_METHOD3(reshapeWithScaleFactor,
   1574                void(int width, int height, float scale_factor));
   1575   MOCK_METHOD4(drawElements,
   1576                void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
   1577 };
   1578 
   1579 class MockOutputSurface : public OutputSurface {
   1580  public:
   1581   MockOutputSurface()
   1582       : OutputSurface(
   1583             TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
   1584                 new StrictMock<OutputSurfaceMockContext>))) {
   1585     surface_size_ = gfx::Size(100, 100);
   1586   }
   1587   virtual ~MockOutputSurface() {}
   1588 
   1589   MOCK_METHOD0(EnsureBackbuffer, void());
   1590   MOCK_METHOD0(DiscardBackbuffer, void());
   1591   MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
   1592   MOCK_METHOD0(BindFramebuffer, void());
   1593   MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
   1594 };
   1595 
   1596 class MockOutputSurfaceTest : public GLRendererTest {
   1597  protected:
   1598   virtual void SetUp() {
   1599     FakeOutputSurfaceClient output_surface_client_;
   1600     CHECK(output_surface_.BindToClient(&output_surface_client_));
   1601 
   1602     shared_bitmap_manager_.reset(new TestSharedBitmapManager());
   1603     resource_provider_ =
   1604         ResourceProvider::Create(
   1605             &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false)
   1606             .Pass();
   1607 
   1608     renderer_.reset(new FakeRendererGL(&renderer_client_,
   1609                                        &settings_,
   1610                                        &output_surface_,
   1611                                        resource_provider_.get()));
   1612   }
   1613 
   1614   void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
   1615 
   1616   void DrawFrame(float device_scale_factor,
   1617                  const gfx::Rect& device_viewport_rect) {
   1618     RenderPass::Id render_pass_id(1, 0);
   1619     TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
   1620                                                 render_pass_id,
   1621                                                 device_viewport_rect,
   1622                                                 gfx::Transform());
   1623     AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
   1624 
   1625     EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
   1626 
   1627     EXPECT_CALL(output_surface_,
   1628                 Reshape(device_viewport_rect.size(), device_scale_factor))
   1629         .Times(1);
   1630 
   1631     EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
   1632 
   1633     EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
   1634 
   1635     renderer_->DecideRenderPassAllocationsForFrame(
   1636         render_passes_in_draw_order_);
   1637     renderer_->DrawFrame(&render_passes_in_draw_order_,
   1638                          device_scale_factor,
   1639                          device_viewport_rect,
   1640                          device_viewport_rect,
   1641                          false);
   1642   }
   1643 
   1644   OutputSurfaceMockContext* Context() {
   1645     return static_cast<OutputSurfaceMockContext*>(
   1646         static_cast<TestContextProvider*>(
   1647             output_surface_.context_provider().get())->TestContext3d());
   1648   }
   1649 
   1650   LayerTreeSettings settings_;
   1651   FakeOutputSurfaceClient output_surface_client_;
   1652   StrictMock<MockOutputSurface> output_surface_;
   1653   scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
   1654   scoped_ptr<ResourceProvider> resource_provider_;
   1655   FakeRendererClient renderer_client_;
   1656   scoped_ptr<FakeRendererGL> renderer_;
   1657 };
   1658 
   1659 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
   1660   gfx::Rect device_viewport_rect(1, 1);
   1661   DrawFrame(1.f, device_viewport_rect);
   1662 
   1663   EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
   1664   renderer_->SwapBuffers(CompositorFrameMetadata());
   1665 }
   1666 
   1667 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
   1668   gfx::Rect device_viewport_rect(1, 1);
   1669 
   1670   DrawFrame(1.f, device_viewport_rect);
   1671   EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
   1672   renderer_->SwapBuffers(CompositorFrameMetadata());
   1673 
   1674   device_viewport_rect = gfx::Rect(2, 2);
   1675 
   1676   DrawFrame(2.f, device_viewport_rect);
   1677   EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
   1678   renderer_->SwapBuffers(CompositorFrameMetadata());
   1679 
   1680   DrawFrame(2.f, device_viewport_rect);
   1681   EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
   1682   renderer_->SwapBuffers(CompositorFrameMetadata());
   1683 
   1684   device_viewport_rect = gfx::Rect(1, 1);
   1685 
   1686   DrawFrame(1.f, device_viewport_rect);
   1687   EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
   1688   renderer_->SwapBuffers(CompositorFrameMetadata());
   1689 }
   1690 
   1691 class GLRendererTestSyncPoint : public GLRendererPixelTest {
   1692  protected:
   1693   static void SyncPointCallback(int* callback_count) {
   1694     ++(*callback_count);
   1695     base::MessageLoop::current()->QuitWhenIdle();
   1696   }
   1697 
   1698   static void OtherCallback(int* callback_count) {
   1699     ++(*callback_count);
   1700     base::MessageLoop::current()->QuitWhenIdle();
   1701   }
   1702 };
   1703 
   1704 #if !defined(OS_ANDROID)
   1705 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
   1706   int sync_point_callback_count = 0;
   1707   int other_callback_count = 0;
   1708   gpu::gles2::GLES2Interface* gl =
   1709       output_surface_->context_provider()->ContextGL();
   1710   gpu::ContextSupport* context_support =
   1711       output_surface_->context_provider()->ContextSupport();
   1712 
   1713   uint32 sync_point = gl->InsertSyncPointCHROMIUM();
   1714 
   1715   gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
   1716                           GL_INNOCENT_CONTEXT_RESET_ARB);
   1717 
   1718   context_support->SignalSyncPoint(
   1719       sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
   1720   EXPECT_EQ(0, sync_point_callback_count);
   1721   EXPECT_EQ(0, other_callback_count);
   1722 
   1723   // Make the sync point happen.
   1724   gl->Finish();
   1725   // Post a task after the sync point.
   1726   base::MessageLoop::current()->PostTask(
   1727       FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
   1728 
   1729   base::MessageLoop::current()->Run();
   1730 
   1731   // The sync point shouldn't have happened since the context was lost.
   1732   EXPECT_EQ(0, sync_point_callback_count);
   1733   EXPECT_EQ(1, other_callback_count);
   1734 }
   1735 
   1736 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
   1737   int sync_point_callback_count = 0;
   1738   int other_callback_count = 0;
   1739 
   1740   gpu::gles2::GLES2Interface* gl =
   1741       output_surface_->context_provider()->ContextGL();
   1742   gpu::ContextSupport* context_support =
   1743       output_surface_->context_provider()->ContextSupport();
   1744 
   1745   uint32 sync_point = gl->InsertSyncPointCHROMIUM();
   1746 
   1747   context_support->SignalSyncPoint(
   1748       sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
   1749   EXPECT_EQ(0, sync_point_callback_count);
   1750   EXPECT_EQ(0, other_callback_count);
   1751 
   1752   // Make the sync point happen.
   1753   gl->Finish();
   1754   // Post a task after the sync point.
   1755   base::MessageLoop::current()->PostTask(
   1756       FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
   1757 
   1758   base::MessageLoop::current()->Run();
   1759 
   1760   // The sync point should have happened.
   1761   EXPECT_EQ(1, sync_point_callback_count);
   1762   EXPECT_EQ(1, other_callback_count);
   1763 }
   1764 #endif  // OS_ANDROID
   1765 
   1766 }  // namespace
   1767 }  // namespace cc
   1768