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