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