445695cbcb15969f61a8c1dfc10ed7012f131518
[platform/framework/web/crosswalk.git] / src / cc / output / gl_renderer_unittest.cc
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