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