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"
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"
33 using testing::AnyNumber
;
35 using testing::AtLeast
;
36 using testing::ElementsAre
;
37 using testing::Expectation
;
38 using testing::InSequence
;
40 using testing::Return
;
41 using testing::StrictMock
;
45 class GLRendererTest
: public testing::Test
{
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) \
54 EXPECT_TRUE((program_binding)->program()); \
55 EXPECT_TRUE((program_binding)->initialized()); \
58 static inline SkXfermode::Mode
BlendModeToSkXfermode(BlendMode blend_mode
) {
61 case BLEND_MODE_NORMAL
:
62 return SkXfermode::kSrcOver_Mode
;
63 case BLEND_MODE_SCREEN
:
64 return SkXfermode::kScreen_Mode
;
65 case BLEND_MODE_OVERLAY
:
66 return SkXfermode::kOverlay_Mode
;
67 case BLEND_MODE_DARKEN
:
68 return SkXfermode::kDarken_Mode
;
69 case BLEND_MODE_LIGHTEN
:
70 return SkXfermode::kLighten_Mode
;
71 case BLEND_MODE_COLOR_DODGE
:
72 return SkXfermode::kColorDodge_Mode
;
73 case BLEND_MODE_COLOR_BURN
:
74 return SkXfermode::kColorBurn_Mode
;
75 case BLEND_MODE_HARD_LIGHT
:
76 return SkXfermode::kHardLight_Mode
;
77 case BLEND_MODE_SOFT_LIGHT
:
78 return SkXfermode::kSoftLight_Mode
;
79 case BLEND_MODE_DIFFERENCE
:
80 return SkXfermode::kDifference_Mode
;
81 case BLEND_MODE_EXCLUSION
:
82 return SkXfermode::kExclusion_Mode
;
83 case BLEND_MODE_MULTIPLY
:
84 return SkXfermode::kMultiply_Mode
;
86 return SkXfermode::kHue_Mode
;
87 case BLEND_MODE_SATURATION
:
88 return SkXfermode::kSaturation_Mode
;
89 case BLEND_MODE_COLOR
:
90 return SkXfermode::kColor_Mode
;
91 case BLEND_MODE_LUMINOSITY
:
92 return SkXfermode::kLuminosity_Mode
;
94 return SkXfermode::kSrcOver_Mode
;
97 // Explicitly named to be a friend in GLRenderer for shader access.
98 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
100 void SetUp() override
{
101 GLRendererPixelTest::SetUp();
102 ASSERT_FALSE(renderer()->IsContextLost());
105 void TearDown() override
{
106 GLRendererPixelTest::TearDown();
107 ASSERT_FALSE(renderer()->IsContextLost());
110 void TestBasicShaders() {
111 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
112 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
113 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
114 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
117 void TestShadersWithPrecision(TexCoordPrecision precision
) {
118 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
));
119 EXPECT_PROGRAM_VALID(
120 renderer()->GetNonPremultipliedTextureProgram(precision
));
121 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision
));
122 EXPECT_PROGRAM_VALID(
123 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
));
124 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
125 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
));
126 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
));
127 if (renderer()->Capabilities().using_egl_image
)
128 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
130 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
133 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision
,
134 BlendMode blend_mode
) {
135 EXPECT_PROGRAM_VALID(
136 renderer()->GetRenderPassProgram(precision
, blend_mode
));
137 EXPECT_PROGRAM_VALID(
138 renderer()->GetRenderPassProgramAA(precision
, blend_mode
));
141 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision
,
142 SamplerType sampler
) {
143 if (!renderer()->Capabilities().using_egl_image
&&
144 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
145 // This will likely be hit in tests due to usage of osmesa.
149 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
150 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
151 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
152 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
153 EXPECT_PROGRAM_VALID(
154 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
155 EXPECT_PROGRAM_VALID(
156 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
159 void TestShadersWithMasks(TexCoordPrecision precision
,
161 BlendMode blend_mode
,
162 bool mask_for_background
) {
163 if (!renderer()->Capabilities().using_egl_image
&&
164 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
165 // This will likely be hit in tests due to usage of osmesa.
169 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
170 precision
, sampler
, blend_mode
, mask_for_background
));
171 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
172 precision
, sampler
, blend_mode
, mask_for_background
));
173 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
174 precision
, sampler
, blend_mode
, mask_for_background
));
175 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
176 precision
, sampler
, blend_mode
, mask_for_background
));
182 #if !defined(OS_ANDROID) && !defined(OS_WIN)
183 static const TexCoordPrecision kPrecisionList
[] = {TEX_COORD_PRECISION_MEDIUM
,
184 TEX_COORD_PRECISION_HIGH
};
186 static const BlendMode kBlendModeList
[LAST_BLEND_MODE
+ 1] = {
193 BLEND_MODE_COLOR_DODGE
,
194 BLEND_MODE_COLOR_BURN
,
195 BLEND_MODE_HARD_LIGHT
,
196 BLEND_MODE_SOFT_LIGHT
,
197 BLEND_MODE_DIFFERENCE
,
198 BLEND_MODE_EXCLUSION
,
201 BLEND_MODE_SATURATION
,
203 BLEND_MODE_LUMINOSITY
,
206 static const SamplerType kSamplerList
[] = {
208 SAMPLER_TYPE_2D_RECT
,
209 SAMPLER_TYPE_EXTERNAL_OES
,
212 TEST_F(GLRendererShaderPixelTest
, BasicShadersCompile
) {
216 class PrecisionShaderPixelTest
217 : public GLRendererShaderPixelTest
,
218 public ::testing::WithParamInterface
<TexCoordPrecision
> {};
220 TEST_P(PrecisionShaderPixelTest
, ShadersCompile
) {
221 TestShadersWithPrecision(GetParam());
224 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile
,
225 PrecisionShaderPixelTest
,
226 ::testing::ValuesIn(kPrecisionList
));
228 class PrecisionBlendShaderPixelTest
229 : public GLRendererShaderPixelTest
,
230 public ::testing::WithParamInterface
<
231 std::tr1::tuple
<TexCoordPrecision
, BlendMode
>> {};
233 TEST_P(PrecisionBlendShaderPixelTest
, ShadersCompile
) {
234 TestShadersWithPrecisionAndBlend(std::tr1::get
<0>(GetParam()),
235 std::tr1::get
<1>(GetParam()));
238 INSTANTIATE_TEST_CASE_P(
239 PrecisionBlendShadersCompile
,
240 PrecisionBlendShaderPixelTest
,
241 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
242 ::testing::ValuesIn(kBlendModeList
)));
244 class PrecisionSamplerShaderPixelTest
245 : public GLRendererShaderPixelTest
,
246 public ::testing::WithParamInterface
<
247 std::tr1::tuple
<TexCoordPrecision
, SamplerType
>> {};
249 TEST_P(PrecisionSamplerShaderPixelTest
, ShadersCompile
) {
250 TestShadersWithPrecisionAndSampler(std::tr1::get
<0>(GetParam()),
251 std::tr1::get
<1>(GetParam()));
254 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile
,
255 PrecisionSamplerShaderPixelTest
,
256 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
257 ::testing::ValuesIn(kSamplerList
)));
259 class MaskShaderPixelTest
260 : public GLRendererShaderPixelTest
,
261 public ::testing::WithParamInterface
<
262 std::tr1::tuple
<TexCoordPrecision
, SamplerType
, BlendMode
, bool>> {};
264 TEST_P(MaskShaderPixelTest
, ShadersCompile
) {
265 TestShadersWithMasks(
266 std::tr1::get
<0>(GetParam()), std::tr1::get
<1>(GetParam()),
267 std::tr1::get
<2>(GetParam()), std::tr1::get
<3>(GetParam()));
270 INSTANTIATE_TEST_CASE_P(MaskShadersCompile
,
272 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
273 ::testing::ValuesIn(kSamplerList
),
274 ::testing::ValuesIn(kBlendModeList
),
279 class FakeRendererGL
: public GLRenderer
{
281 FakeRendererGL(RendererClient
* client
,
282 const RendererSettings
* settings
,
283 OutputSurface
* output_surface
,
284 ResourceProvider
* resource_provider
)
292 // GLRenderer methods.
294 // Changing visibility to public.
295 using GLRenderer::IsBackbufferDiscarded
;
296 using GLRenderer::DoDrawQuad
;
297 using GLRenderer::BeginDrawingFrame
;
298 using GLRenderer::FinishDrawingQuadList
;
299 using GLRenderer::stencil_enabled
;
302 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
304 GLRendererWithDefaultHarnessTest() {
306 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
307 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
309 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
310 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
311 shared_bitmap_manager_
.get(),
317 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
319 output_surface_
.get(),
320 resource_provider_
.get()));
323 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
325 RendererSettings settings_
;
326 FakeOutputSurfaceClient output_surface_client_
;
327 scoped_ptr
<FakeOutputSurface
> output_surface_
;
328 FakeRendererClient renderer_client_
;
329 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
330 scoped_ptr
<ResourceProvider
> resource_provider_
;
331 scoped_ptr
<FakeRendererGL
> renderer_
;
334 // Closing the namespace here so that GLRendererShaderTest can take advantage
335 // of the friend relationship with GLRenderer and all of the mock classes
336 // declared above it.
339 class GLRendererShaderTest
: public GLRendererTest
{
341 GLRendererShaderTest() {
342 output_surface_
= FakeOutputSurface::Create3d().Pass();
343 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
345 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
346 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
347 shared_bitmap_manager_
.get(),
353 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
355 output_surface_
.get(),
356 resource_provider_
.get()));
359 void TestRenderPassProgram(TexCoordPrecision precision
,
360 BlendMode blend_mode
) {
361 EXPECT_PROGRAM_VALID(
362 &renderer_
->render_pass_program_
[precision
][blend_mode
]);
363 EXPECT_EQ(renderer_
->render_pass_program_
[precision
][blend_mode
].program(),
364 renderer_
->program_shadow_
);
367 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
,
368 BlendMode blend_mode
) {
369 EXPECT_PROGRAM_VALID(
370 &renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]);
372 renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]
374 renderer_
->program_shadow_
);
377 void TestRenderPassMaskProgram(TexCoordPrecision precision
,
379 BlendMode blend_mode
) {
380 EXPECT_PROGRAM_VALID(
381 &renderer_
->render_pass_mask_program_
[precision
]
386 renderer_
->render_pass_mask_program_
[precision
]
390 renderer_
->program_shadow_
);
393 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
,
395 BlendMode blend_mode
) {
396 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_
397 [precision
][sampler
][blend_mode
][NO_MASK
]);
398 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_
399 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
400 renderer_
->program_shadow_
);
403 void TestRenderPassProgramAA(TexCoordPrecision precision
,
404 BlendMode blend_mode
) {
405 EXPECT_PROGRAM_VALID(
406 &renderer_
->render_pass_program_aa_
[precision
][blend_mode
]);
408 renderer_
->render_pass_program_aa_
[precision
][blend_mode
].program(),
409 renderer_
->program_shadow_
);
412 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
,
413 BlendMode blend_mode
) {
414 EXPECT_PROGRAM_VALID(
416 ->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]);
418 renderer_
->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]
420 renderer_
->program_shadow_
);
423 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
,
425 BlendMode blend_mode
) {
426 EXPECT_PROGRAM_VALID(
428 ->render_pass_mask_program_aa_
429 [precision
][sampler
][blend_mode
][NO_MASK
]);
431 renderer_
->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]
433 renderer_
->program_shadow_
);
436 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
,
438 BlendMode blend_mode
) {
439 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_aa_
440 [precision
][sampler
][blend_mode
][NO_MASK
]);
441 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
442 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
443 renderer_
->program_shadow_
);
446 void TestSolidColorProgramAA() {
447 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
448 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
449 renderer_
->program_shadow_
);
452 RendererSettings settings_
;
453 FakeOutputSurfaceClient output_surface_client_
;
454 scoped_ptr
<FakeOutputSurface
> output_surface_
;
455 FakeRendererClient renderer_client_
;
456 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
457 scoped_ptr
<ResourceProvider
> resource_provider_
;
458 scoped_ptr
<FakeRendererGL
> renderer_
;
463 // Test GLRenderer DiscardBackbuffer functionality:
464 // Suggest discarding framebuffer when one exists and the renderer is not
466 // Expected: it is discarded and damage tracker is reset.
468 GLRendererWithDefaultHarnessTest
,
469 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
470 renderer_
->SetVisible(false);
471 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
472 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
475 // Test GLRenderer DiscardBackbuffer functionality:
476 // Suggest discarding framebuffer when one exists and the renderer is visible.
477 // Expected: the allocation is ignored.
478 TEST_F(GLRendererWithDefaultHarnessTest
,
479 SuggestBackbufferNoDoNothingWhenVisible
) {
480 renderer_
->SetVisible(true);
481 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
482 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
485 // Test GLRenderer DiscardBackbuffer functionality:
486 // Suggest discarding framebuffer when one does not exist.
487 // Expected: it does nothing.
488 TEST_F(GLRendererWithDefaultHarnessTest
,
489 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
490 renderer_
->SetVisible(false);
491 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
492 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
494 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
495 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
498 // Test GLRenderer DiscardBackbuffer functionality:
499 // Begin drawing a frame while a framebuffer is discarded.
500 // Expected: will recreate framebuffer.
501 TEST_F(GLRendererWithDefaultHarnessTest
,
502 DiscardedBackbufferIsRecreatedForScopeDuration
) {
503 gfx::Rect
viewport_rect(1, 1);
504 renderer_
->SetVisible(false);
505 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
506 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
508 AddRenderPass(&render_passes_in_draw_order_
,
513 renderer_
->SetVisible(true);
514 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
519 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
522 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
525 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
526 gfx::Rect
viewport_rect(1, 1);
527 EXPECT_FALSE(renderer_
->stencil_enabled());
529 output_surface_
->set_has_external_stencil_test(true);
531 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
535 root_pass
->has_transparent_background
= false;
537 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
542 EXPECT_TRUE(renderer_
->stencil_enabled());
545 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
547 ForbidSynchronousCallContext() {}
549 void getAttachedShaders(GLuint program
,
552 GLuint
* shaders
) override
{
555 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
559 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
560 void getBufferParameteriv(GLenum target
,
562 GLint
* value
) override
{
565 GLenum
getError() override
{
569 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
570 void getFramebufferAttachmentParameteriv(GLenum target
,
573 GLint
* value
) override
{
576 void getIntegerv(GLenum pname
, GLint
* value
) override
{
577 if (pname
== GL_MAX_TEXTURE_SIZE
) {
578 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
585 // We allow querying the shader compilation and program link status in debug
586 // mode, but not release.
587 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
595 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
603 void getRenderbufferParameteriv(GLenum target
,
605 GLint
* value
) override
{
609 void getShaderPrecisionFormat(GLenum shadertype
,
610 GLenum precisiontype
,
612 GLint
* precision
) override
{
615 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
618 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
621 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
624 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
627 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
631 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
634 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
637 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
642 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
643 FakeOutputSurfaceClient output_surface_client
;
644 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
645 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
646 CHECK(output_surface
->BindToClient(&output_surface_client
));
648 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
649 new TestSharedBitmapManager());
650 scoped_ptr
<ResourceProvider
> resource_provider(
651 ResourceProvider::Create(output_surface
.get(),
652 shared_bitmap_manager
.get(),
659 RendererSettings settings
;
660 FakeRendererClient renderer_client
;
661 FakeRendererGL
renderer(&renderer_client
,
663 output_surface
.get(),
664 resource_provider
.get());
667 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
669 LoseContextOnFirstGetContext() {}
671 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
672 context_lost_
= true;
676 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
677 context_lost_
= true;
682 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
683 FakeOutputSurfaceClient output_surface_client
;
684 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
685 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
686 CHECK(output_surface
->BindToClient(&output_surface_client
));
688 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
689 new TestSharedBitmapManager());
690 scoped_ptr
<ResourceProvider
> resource_provider(
691 ResourceProvider::Create(output_surface
.get(),
692 shared_bitmap_manager
.get(),
699 RendererSettings settings
;
700 FakeRendererClient renderer_client
;
701 FakeRendererGL
renderer(&renderer_client
,
703 output_surface
.get(),
704 resource_provider
.get());
707 class ClearCountingContext
: public TestWebGraphicsContext3D
{
709 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
711 MOCK_METHOD3(discardFramebufferEXT
,
713 GLsizei numAttachments
,
714 const GLenum
* attachments
));
715 MOCK_METHOD1(clear
, void(GLbitfield mask
));
718 TEST_F(GLRendererTest
, OpaqueBackground
) {
719 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
720 ClearCountingContext
* context
= context_owned
.get();
722 FakeOutputSurfaceClient output_surface_client
;
723 scoped_ptr
<OutputSurface
> output_surface(
724 FakeOutputSurface::Create3d(context_owned
.Pass()));
725 CHECK(output_surface
->BindToClient(&output_surface_client
));
727 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
728 new TestSharedBitmapManager());
729 scoped_ptr
<ResourceProvider
> resource_provider(
730 ResourceProvider::Create(output_surface
.get(),
731 shared_bitmap_manager
.get(),
738 RendererSettings settings
;
739 FakeRendererClient renderer_client
;
740 FakeRendererGL
renderer(&renderer_client
,
742 output_surface
.get(),
743 resource_provider
.get());
745 gfx::Rect
viewport_rect(1, 1);
746 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
750 root_pass
->has_transparent_background
= false;
752 // On DEBUG builds, render passes with opaque background clear to blue to
753 // easily see regions that were not drawn on the screen.
754 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
755 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
758 EXPECT_CALL(*context
, clear(_
)).Times(0);
760 EXPECT_CALL(*context
, clear(_
)).Times(1);
762 renderer
.DrawFrame(&render_passes_in_draw_order_
,
767 Mock::VerifyAndClearExpectations(context
);
770 TEST_F(GLRendererTest
, TransparentBackground
) {
771 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
772 ClearCountingContext
* context
= context_owned
.get();
774 FakeOutputSurfaceClient output_surface_client
;
775 scoped_ptr
<OutputSurface
> output_surface(
776 FakeOutputSurface::Create3d(context_owned
.Pass()));
777 CHECK(output_surface
->BindToClient(&output_surface_client
));
779 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
780 new TestSharedBitmapManager());
781 scoped_ptr
<ResourceProvider
> resource_provider(
782 ResourceProvider::Create(output_surface
.get(),
783 shared_bitmap_manager
.get(),
790 RendererSettings settings
;
791 FakeRendererClient renderer_client
;
792 FakeRendererGL
renderer(&renderer_client
,
794 output_surface
.get(),
795 resource_provider
.get());
797 gfx::Rect
viewport_rect(1, 1);
798 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
802 root_pass
->has_transparent_background
= true;
804 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
805 EXPECT_CALL(*context
, clear(_
)).Times(1);
806 renderer
.DrawFrame(&render_passes_in_draw_order_
,
812 Mock::VerifyAndClearExpectations(context
);
815 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
816 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
817 ClearCountingContext
* context
= context_owned
.get();
819 FakeOutputSurfaceClient output_surface_client
;
820 scoped_ptr
<OutputSurface
> output_surface(
821 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
822 CHECK(output_surface
->BindToClient(&output_surface_client
));
824 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
825 new TestSharedBitmapManager());
826 scoped_ptr
<ResourceProvider
> resource_provider(
827 ResourceProvider::Create(output_surface
.get(),
828 shared_bitmap_manager
.get(),
835 RendererSettings settings
;
836 FakeRendererClient renderer_client
;
837 FakeRendererGL
renderer(&renderer_client
,
839 output_surface
.get(),
840 resource_provider
.get());
842 gfx::Rect
viewport_rect(1, 1);
843 AddRenderPass(&render_passes_in_draw_order_
,
848 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
849 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
851 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
852 renderer
.DrawFrame(&render_passes_in_draw_order_
,
857 Mock::VerifyAndClearExpectations(context
);
860 class VisibilityChangeIsLastCallTrackingContext
861 : public TestWebGraphicsContext3D
{
863 VisibilityChangeIsLastCallTrackingContext()
864 : last_call_was_set_visibility_(false) {}
866 // TestWebGraphicsContext3D methods.
867 void flush() override
{ last_call_was_set_visibility_
= false; }
868 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
869 void deleteFramebuffer(GLuint
) override
{
870 last_call_was_set_visibility_
= false;
872 void deleteQueryEXT(GLuint
) override
{
873 last_call_was_set_visibility_
= false;
875 void deleteRenderbuffer(GLuint
) override
{
876 last_call_was_set_visibility_
= false;
879 // Methods added for test.
880 void set_last_call_was_visibility(bool visible
) {
881 DCHECK(last_call_was_set_visibility_
== false);
882 last_call_was_set_visibility_
= true;
884 bool last_call_was_set_visibility() const {
885 return last_call_was_set_visibility_
;
889 bool last_call_was_set_visibility_
;
892 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
893 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
894 new VisibilityChangeIsLastCallTrackingContext
);
895 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
897 scoped_refptr
<TestContextProvider
> provider
=
898 TestContextProvider::Create(context_owned
.Pass());
900 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
901 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
902 base::Unretained(context
)));
904 FakeOutputSurfaceClient output_surface_client
;
905 scoped_ptr
<OutputSurface
> output_surface(
906 FakeOutputSurface::Create3d(provider
));
907 CHECK(output_surface
->BindToClient(&output_surface_client
));
909 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
910 new TestSharedBitmapManager());
911 scoped_ptr
<ResourceProvider
> resource_provider(
912 ResourceProvider::Create(output_surface
.get(),
913 shared_bitmap_manager
.get(),
920 RendererSettings settings
;
921 FakeRendererClient renderer_client
;
922 FakeRendererGL
renderer(&renderer_client
,
924 output_surface
.get(),
925 resource_provider
.get());
927 gfx::Rect
viewport_rect(1, 1);
928 AddRenderPass(&render_passes_in_draw_order_
,
933 // Ensure that the call to SetSurfaceVisible is the last call issue to the
934 // GPU process, after glFlush is called, and after the RendererClient's
935 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
936 // RenderClient and the Context by giving them both a pointer to a variable on
938 renderer
.SetVisible(true);
939 renderer
.DrawFrame(&render_passes_in_draw_order_
,
944 renderer
.SetVisible(false);
945 EXPECT_TRUE(context
->last_call_was_set_visibility());
948 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
950 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
951 test_capabilities_
.gpu
.egl_image_external
= true;
954 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
955 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
956 MOCK_METHOD4(drawElements
,
957 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
959 virtual void activeTexture(GLenum texture
) {
960 EXPECT_NE(texture
, active_texture_
);
961 active_texture_
= texture
;
964 GLenum
active_texture() const { return active_texture_
; }
967 GLenum active_texture_
;
970 TEST_F(GLRendererTest
, ActiveTextureState
) {
971 scoped_ptr
<TextureStateTrackingContext
> context_owned(
972 new TextureStateTrackingContext
);
973 TextureStateTrackingContext
* context
= context_owned
.get();
975 FakeOutputSurfaceClient output_surface_client
;
976 scoped_ptr
<OutputSurface
> output_surface(
977 FakeOutputSurface::Create3d(context_owned
.Pass()));
978 CHECK(output_surface
->BindToClient(&output_surface_client
));
980 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
981 new TestSharedBitmapManager());
982 scoped_ptr
<ResourceProvider
> resource_provider(
983 ResourceProvider::Create(output_surface
.get(),
984 shared_bitmap_manager
.get(),
991 RendererSettings settings
;
992 FakeRendererClient renderer_client
;
993 FakeRendererGL
renderer(&renderer_client
,
995 output_surface
.get(),
996 resource_provider
.get());
998 // During initialization we are allowed to set any texture parameters.
999 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
1001 RenderPassId
id(1, 1);
1002 TestRenderPass
* root_pass
= AddRenderPass(
1003 &render_passes_in_draw_order_
, id
, gfx::Rect(100, 100), gfx::Transform());
1004 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
1005 RenderPassId(2, 1));
1007 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1009 // Set up expected texture filter state transitions that match the quads
1010 // created in AppendOneOfEveryQuadType().
1011 Mock::VerifyAndClearExpectations(context
);
1013 InSequence sequence
;
1015 // The sync points for all quads are waited on first. This sync point is
1016 // for a texture quad drawn later in the frame.
1017 EXPECT_CALL(*context
,
1018 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
1021 // yuv_quad is drawn with the default linear filter.
1022 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1024 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1028 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
1031 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
1032 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1034 // transformed_tile_quad uses GL_LINEAR.
1035 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1037 // scaled_tile_quad also uses GL_LINEAR.
1038 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1040 // The remaining quads also use GL_LINEAR because nearest neighbor
1041 // filtering is currently only used with tile quads.
1042 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(7);
1045 gfx::Rect
viewport_rect(100, 100);
1046 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1051 Mock::VerifyAndClearExpectations(context
);
1054 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
1056 MOCK_METHOD1(clear
, void(GLbitfield mask
));
1057 MOCK_METHOD4(drawElements
,
1058 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1061 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
1062 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
1063 new NoClearRootRenderPassMockContext
);
1064 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
1066 FakeOutputSurfaceClient output_surface_client
;
1067 scoped_ptr
<OutputSurface
> output_surface(
1068 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
1069 CHECK(output_surface
->BindToClient(&output_surface_client
));
1071 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1072 new TestSharedBitmapManager());
1073 scoped_ptr
<ResourceProvider
> resource_provider(
1074 ResourceProvider::Create(output_surface
.get(),
1075 shared_bitmap_manager
.get(),
1082 RendererSettings settings
;
1083 settings
.should_clear_root_render_pass
= false;
1085 FakeRendererClient renderer_client
;
1086 FakeRendererGL
renderer(&renderer_client
,
1088 output_surface
.get(),
1089 resource_provider
.get());
1091 gfx::Rect
viewport_rect(10, 10);
1093 RenderPassId
root_pass_id(1, 0);
1094 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1098 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1100 RenderPassId
child_pass_id(2, 0);
1101 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1105 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
1107 AddRenderPassQuad(root_pass
, child_pass
);
1110 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
1112 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1115 // First render pass is not the root one, clearing should happen.
1116 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1118 Expectation first_render_pass
=
1119 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1121 // The second render pass is the root one, clearing should be prevented.
1122 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1125 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1128 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1129 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1135 // In multiple render passes all but the root pass should clear the
1137 Mock::VerifyAndClearExpectations(&mock_context
);
1140 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1142 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1144 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1146 void enable(GLenum cap
) override
{
1147 if (cap
== GL_SCISSOR_TEST
)
1148 scissor_enabled_
= true;
1151 void disable(GLenum cap
) override
{
1152 if (cap
== GL_SCISSOR_TEST
)
1153 scissor_enabled_
= false;
1157 bool scissor_enabled_
;
1160 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1161 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1162 new ScissorTestOnClearCheckingContext
);
1164 FakeOutputSurfaceClient output_surface_client
;
1165 scoped_ptr
<OutputSurface
> output_surface(
1166 FakeOutputSurface::Create3d(context_owned
.Pass()));
1167 CHECK(output_surface
->BindToClient(&output_surface_client
));
1169 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1170 new TestSharedBitmapManager());
1171 scoped_ptr
<ResourceProvider
> resource_provider(
1172 ResourceProvider::Create(output_surface
.get(),
1173 shared_bitmap_manager
.get(),
1180 RendererSettings settings
;
1181 FakeRendererClient renderer_client
;
1182 FakeRendererGL
renderer(&renderer_client
,
1184 output_surface
.get(),
1185 resource_provider
.get());
1186 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1188 gfx::Rect
viewport_rect(1, 1);
1190 gfx::Rect
grand_child_rect(25, 25);
1191 RenderPassId
grand_child_pass_id(3, 0);
1192 TestRenderPass
* grand_child_pass
=
1193 AddRenderPass(&render_passes_in_draw_order_
,
1194 grand_child_pass_id
,
1197 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1199 gfx::Rect
child_rect(50, 50);
1200 RenderPassId
child_pass_id(2, 0);
1201 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1205 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1207 RenderPassId
root_pass_id(1, 0);
1208 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1212 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1214 AddRenderPassQuad(root_pass
, child_pass
);
1215 AddRenderPassQuad(child_pass
, grand_child_pass
);
1217 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1218 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1225 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1227 DiscardCheckingContext() : discarded_(0) {
1228 set_have_post_sub_buffer(true);
1229 set_have_discard_framebuffer(true);
1232 void discardFramebufferEXT(GLenum target
,
1233 GLsizei numAttachments
,
1234 const GLenum
* attachments
) override
{
1238 int discarded() const { return discarded_
; }
1239 void reset() { discarded_
= 0; }
1245 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1247 explicit NonReshapableOutputSurface(
1248 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1249 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1251 surface_size_
= gfx::Size(500, 500);
1253 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1254 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1257 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1258 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1259 DiscardCheckingContext
* context
= context_owned
.get();
1261 FakeOutputSurfaceClient output_surface_client
;
1262 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1263 new NonReshapableOutputSurface(context_owned
.Pass()));
1264 CHECK(output_surface
->BindToClient(&output_surface_client
));
1265 output_surface
->set_fixed_size(gfx::Size(100, 100));
1267 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1268 new TestSharedBitmapManager());
1269 scoped_ptr
<ResourceProvider
> resource_provider(
1270 ResourceProvider::Create(output_surface
.get(),
1271 shared_bitmap_manager
.get(),
1278 RendererSettings settings
;
1279 settings
.partial_swap_enabled
= true;
1280 FakeRendererClient renderer_client
;
1281 FakeRendererGL
renderer(&renderer_client
,
1283 output_surface
.get(),
1284 resource_provider
.get());
1285 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1287 gfx::Rect
viewport_rect(100, 100);
1288 gfx::Rect
clip_rect(100, 100);
1291 // Partial frame, should not discard.
1292 RenderPassId
root_pass_id(1, 0);
1293 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1297 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1298 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1300 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1301 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1306 EXPECT_EQ(0, context
->discarded());
1310 // Full frame, should discard.
1311 RenderPassId
root_pass_id(1, 0);
1312 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1316 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1317 root_pass
->damage_rect
= root_pass
->output_rect
;
1319 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1320 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1325 EXPECT_EQ(1, context
->discarded());
1329 // Full frame, external scissor is set, should not discard.
1330 output_surface
->set_has_external_stencil_test(true);
1331 RenderPassId
root_pass_id(1, 0);
1332 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1336 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1337 root_pass
->damage_rect
= root_pass
->output_rect
;
1338 root_pass
->has_transparent_background
= false;
1340 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1341 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1346 EXPECT_EQ(0, context
->discarded());
1348 output_surface
->set_has_external_stencil_test(false);
1351 // Full frame, clipped, should not discard.
1352 clip_rect
= gfx::Rect(10, 10, 10, 10);
1353 RenderPassId
root_pass_id(1, 0);
1354 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1358 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1359 root_pass
->damage_rect
= root_pass
->output_rect
;
1361 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1362 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1367 EXPECT_EQ(0, context
->discarded());
1371 // Full frame, doesn't cover the surface, should not discard.
1372 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1373 RenderPassId
root_pass_id(1, 0);
1374 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1378 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1379 root_pass
->damage_rect
= root_pass
->output_rect
;
1381 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1382 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1387 EXPECT_EQ(0, context
->discarded());
1391 // Full frame, doesn't cover the surface (no offset), should not discard.
1392 clip_rect
= gfx::Rect(100, 100);
1393 viewport_rect
= gfx::Rect(50, 50);
1394 RenderPassId
root_pass_id(1, 0);
1395 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1399 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1400 root_pass
->damage_rect
= root_pass
->output_rect
;
1402 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1403 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1408 EXPECT_EQ(0, context
->discarded());
1413 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1415 MOCK_METHOD4(viewport
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1416 MOCK_METHOD4(scissor
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1419 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1420 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1421 // and maintains a fixed size. This test verifies that glViewport and
1422 // glScissor's Y coordinate is flipped correctly in this environment, and that
1423 // the glViewport can be at a nonzero origin within the surface.
1424 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1425 new FlippedScissorAndViewportContext
);
1427 // We expect exactly one call to viewport on this context and exactly two
1428 // to scissor (one to scissor the clear, one to scissor the quad draw).
1429 EXPECT_CALL(*context_owned
, viewport(10, 390, 100, 100));
1430 EXPECT_CALL(*context_owned
, scissor(10, 390, 100, 100));
1431 EXPECT_CALL(*context_owned
, scissor(30, 450, 20, 20));
1433 FakeOutputSurfaceClient output_surface_client
;
1434 scoped_ptr
<OutputSurface
> output_surface(
1435 new NonReshapableOutputSurface(context_owned
.Pass()));
1436 CHECK(output_surface
->BindToClient(&output_surface_client
));
1438 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1439 new TestSharedBitmapManager());
1440 scoped_ptr
<ResourceProvider
> resource_provider(
1441 ResourceProvider::Create(output_surface
.get(),
1442 shared_bitmap_manager
.get(),
1449 RendererSettings settings
;
1450 FakeRendererClient renderer_client
;
1451 FakeRendererGL
renderer(&renderer_client
,
1453 output_surface
.get(),
1454 resource_provider
.get());
1455 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1457 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1458 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1459 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1461 RenderPassId
root_pass_id(1, 0);
1462 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1466 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1468 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1469 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1471 device_viewport_rect
,
1472 device_viewport_rect
,
1476 TEST_F(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1477 // When using render-to-FBO to display the surface, all rendering is done
1478 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1479 // the correct framebuffer during rendering, if changed.
1480 // Note: there is one path that will set it to 0, but that is after the render
1482 FakeOutputSurfaceClient output_surface_client
;
1483 scoped_ptr
<FakeOutputSurface
> output_surface(
1484 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1485 CHECK(output_surface
->BindToClient(&output_surface_client
));
1487 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1488 new TestSharedBitmapManager());
1489 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1490 output_surface
.get(), shared_bitmap_manager
.get(), NULL
, NULL
, 0, false,
1493 RendererSettings settings
;
1494 FakeRendererClient renderer_client
;
1495 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1496 resource_provider
.get());
1497 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1499 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1500 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1501 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1503 RenderPassId
root_pass_id(1, 0);
1504 TestRenderPass
* root_pass
=
1505 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1507 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1510 gpu::gles2::GLES2Interface
* gl
=
1511 output_surface
->context_provider()->ContextGL();
1512 gl
->GenFramebuffers(1, &fbo
);
1513 output_surface
->set_framebuffer(fbo
);
1515 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1516 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1517 device_viewport_rect
, false);
1520 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1521 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1524 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1525 gfx::Rect
viewport_rect(1, 1);
1527 gfx::Rect
child_rect(50, 50);
1528 RenderPassId
child_pass_id(2, 0);
1529 TestRenderPass
* child_pass
;
1531 RenderPassId
root_pass_id(1, 0);
1532 TestRenderPass
* root_pass
;
1534 ResourceProvider::ResourceId mask
= resource_provider_
->CreateResource(
1535 gfx::Size(20, 12), GL_CLAMP_TO_EDGE
,
1536 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1537 resource_provider_
->best_texture_format());
1538 resource_provider_
->AllocateForTesting(mask
);
1540 SkScalar matrix
[20];
1541 float amount
= 0.5f
;
1542 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1543 matrix
[1] = 0.715f
- 0.715f
* amount
;
1544 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1545 matrix
[3] = matrix
[4] = 0;
1546 matrix
[5] = 0.213f
- 0.213f
* amount
;
1547 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1548 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1549 matrix
[8] = matrix
[9] = 0;
1550 matrix
[10] = 0.213f
- 0.213f
* amount
;
1551 matrix
[11] = 0.715f
- 0.715f
* amount
;
1552 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1553 matrix
[13] = matrix
[14] = 0;
1554 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1556 skia::RefPtr
<SkColorFilter
> color_filter(
1557 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1558 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1559 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1560 FilterOperations filters
;
1561 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1563 gfx::Transform transform_causing_aa
;
1564 transform_causing_aa
.Rotate(20.0);
1566 for (int i
= 0; i
<= LAST_BLEND_MODE
; ++i
) {
1567 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1568 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1569 settings_
.force_blending_with_shaders
= (blend_mode
!= BLEND_MODE_NONE
);
1570 // RenderPassProgram
1571 render_passes_in_draw_order_
.clear();
1572 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1577 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1582 AddRenderPassQuad(root_pass
,
1589 renderer_
->DecideRenderPassAllocationsForFrame(
1590 render_passes_in_draw_order_
);
1591 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1596 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1598 // RenderPassColorMatrixProgram
1599 render_passes_in_draw_order_
.clear();
1601 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1604 transform_causing_aa
);
1606 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1612 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1614 renderer_
->DecideRenderPassAllocationsForFrame(
1615 render_passes_in_draw_order_
);
1616 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1621 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1623 // RenderPassMaskProgram
1624 render_passes_in_draw_order_
.clear();
1626 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1631 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1636 AddRenderPassQuad(root_pass
,
1643 renderer_
->DecideRenderPassAllocationsForFrame(
1644 render_passes_in_draw_order_
);
1645 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1650 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1653 // RenderPassMaskColorMatrixProgram
1654 render_passes_in_draw_order_
.clear();
1656 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1661 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1667 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1669 renderer_
->DecideRenderPassAllocationsForFrame(
1670 render_passes_in_draw_order_
);
1671 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1676 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
,
1677 SAMPLER_TYPE_2D
, blend_mode
);
1679 // RenderPassProgramAA
1680 render_passes_in_draw_order_
.clear();
1682 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1685 transform_causing_aa
);
1687 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1692 AddRenderPassQuad(root_pass
,
1696 transform_causing_aa
,
1699 renderer_
->DecideRenderPassAllocationsForFrame(
1700 render_passes_in_draw_order_
);
1701 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1706 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1708 // RenderPassColorMatrixProgramAA
1709 render_passes_in_draw_order_
.clear();
1711 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1714 transform_causing_aa
);
1716 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1722 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1724 renderer_
->DecideRenderPassAllocationsForFrame(
1725 render_passes_in_draw_order_
);
1726 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1731 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1733 // RenderPassMaskProgramAA
1734 render_passes_in_draw_order_
.clear();
1736 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1739 transform_causing_aa
);
1741 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1746 AddRenderPassQuad(root_pass
,
1750 transform_causing_aa
,
1753 renderer_
->DecideRenderPassAllocationsForFrame(
1754 render_passes_in_draw_order_
);
1755 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1760 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1763 // RenderPassMaskColorMatrixProgramAA
1764 render_passes_in_draw_order_
.clear();
1766 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1769 transform_causing_aa
);
1771 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1774 transform_causing_aa
);
1777 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1779 renderer_
->DecideRenderPassAllocationsForFrame(
1780 render_passes_in_draw_order_
);
1781 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1786 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
,
1787 SAMPLER_TYPE_2D
, blend_mode
);
1791 // At this time, the AA code path cannot be taken if the surface's rect would
1792 // project incorrectly by the given transform, because of w<0 clipping.
1793 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1794 gfx::Rect
child_rect(50, 50);
1795 RenderPassId
child_pass_id(2, 0);
1796 TestRenderPass
* child_pass
;
1798 gfx::Rect
viewport_rect(1, 1);
1799 RenderPassId
root_pass_id(1, 0);
1800 TestRenderPass
* root_pass
;
1802 gfx::Transform transform_preventing_aa
;
1803 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1804 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1805 transform_preventing_aa
.Scale(30.0, 1.0);
1807 // Verify that the test transform and test rect actually do cause the clipped
1808 // flag to trigger. Otherwise we are not testing the intended scenario.
1809 bool clipped
= false;
1810 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1811 ASSERT_TRUE(clipped
);
1813 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1816 transform_preventing_aa
);
1818 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1823 AddRenderPassQuad(root_pass
,
1827 transform_preventing_aa
,
1828 SkXfermode::kSrcOver_Mode
);
1830 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1831 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1837 // If use_aa incorrectly ignores clipping, it will use the
1838 // RenderPassProgramAA shader instead of the RenderPassProgram.
1839 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, BLEND_MODE_NONE
);
1842 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1843 gfx::Rect
viewport_rect(1, 1);
1844 RenderPassId
root_pass_id(1, 0);
1845 TestRenderPass
* root_pass
;
1847 gfx::Transform pixel_aligned_transform_causing_aa
;
1848 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1849 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1851 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1855 AddTransformedQuad(root_pass
,
1858 pixel_aligned_transform_causing_aa
);
1860 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1861 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1867 TestSolidColorProgramAA();
1870 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1872 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1874 // Specifically override methods even if they are unused (used in conjunction
1875 // with StrictMock). We need to make sure that GLRenderer does not issue
1876 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1877 // through the OutputSurface abstraction.
1878 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1879 MOCK_METHOD3(reshapeWithScaleFactor
,
1880 void(int width
, int height
, float scale_factor
));
1881 MOCK_METHOD4(drawElements
,
1882 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1885 class MockOutputSurface
: public OutputSurface
{
1889 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1890 new StrictMock
<OutputSurfaceMockContext
>))) {
1891 surface_size_
= gfx::Size(100, 100);
1893 virtual ~MockOutputSurface() {}
1895 MOCK_METHOD0(EnsureBackbuffer
, void());
1896 MOCK_METHOD0(DiscardBackbuffer
, void());
1897 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1898 MOCK_METHOD0(BindFramebuffer
, void());
1899 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1902 class MockOutputSurfaceTest
: public GLRendererTest
{
1904 virtual void SetUp() {
1905 FakeOutputSurfaceClient output_surface_client_
;
1906 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1908 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1909 resource_provider_
= ResourceProvider::Create(&output_surface_
,
1910 shared_bitmap_manager_
.get(),
1917 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1920 resource_provider_
.get()));
1923 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1925 void DrawFrame(float device_scale_factor
,
1926 const gfx::Rect
& device_viewport_rect
) {
1927 RenderPassId
render_pass_id(1, 0);
1928 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1930 device_viewport_rect
,
1932 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1934 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1936 EXPECT_CALL(output_surface_
,
1937 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1940 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1942 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1944 renderer_
->DecideRenderPassAllocationsForFrame(
1945 render_passes_in_draw_order_
);
1946 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1947 device_scale_factor
,
1948 device_viewport_rect
,
1949 device_viewport_rect
,
1953 OutputSurfaceMockContext
* Context() {
1954 return static_cast<OutputSurfaceMockContext
*>(
1955 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1959 RendererSettings settings_
;
1960 FakeOutputSurfaceClient output_surface_client_
;
1961 StrictMock
<MockOutputSurface
> output_surface_
;
1962 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1963 scoped_ptr
<ResourceProvider
> resource_provider_
;
1964 FakeRendererClient renderer_client_
;
1965 scoped_ptr
<FakeRendererGL
> renderer_
;
1968 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1969 gfx::Rect
device_viewport_rect(1, 1);
1970 DrawFrame(1.f
, device_viewport_rect
);
1972 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1973 renderer_
->SwapBuffers(CompositorFrameMetadata());
1976 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1977 gfx::Rect
device_viewport_rect(1, 1);
1979 DrawFrame(1.f
, device_viewport_rect
);
1980 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1981 renderer_
->SwapBuffers(CompositorFrameMetadata());
1983 device_viewport_rect
= gfx::Rect(2, 2);
1985 DrawFrame(2.f
, device_viewport_rect
);
1986 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1987 renderer_
->SwapBuffers(CompositorFrameMetadata());
1989 DrawFrame(2.f
, device_viewport_rect
);
1990 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1991 renderer_
->SwapBuffers(CompositorFrameMetadata());
1993 device_viewport_rect
= gfx::Rect(1, 1);
1995 DrawFrame(1.f
, device_viewport_rect
);
1996 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1997 renderer_
->SwapBuffers(CompositorFrameMetadata());
2000 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
2002 static void SyncPointCallback(int* callback_count
) {
2003 ++(*callback_count
);
2004 base::MessageLoop::current()->QuitWhenIdle();
2007 static void OtherCallback(int* callback_count
) {
2008 ++(*callback_count
);
2009 base::MessageLoop::current()->QuitWhenIdle();
2013 #if !defined(OS_ANDROID)
2014 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
2015 int sync_point_callback_count
= 0;
2016 int other_callback_count
= 0;
2017 gpu::gles2::GLES2Interface
* gl
=
2018 output_surface_
->context_provider()->ContextGL();
2019 gpu::ContextSupport
* context_support
=
2020 output_surface_
->context_provider()->ContextSupport();
2022 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
2024 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
2025 GL_INNOCENT_CONTEXT_RESET_ARB
);
2027 context_support
->SignalSyncPoint(
2028 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
2029 EXPECT_EQ(0, sync_point_callback_count
);
2030 EXPECT_EQ(0, other_callback_count
);
2032 // Make the sync point happen.
2034 // Post a task after the sync point.
2035 base::MessageLoop::current()->PostTask(
2036 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
2038 base::MessageLoop::current()->Run();
2040 // The sync point shouldn't have happened since the context was lost.
2041 EXPECT_EQ(0, sync_point_callback_count
);
2042 EXPECT_EQ(1, other_callback_count
);
2045 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
2046 int sync_point_callback_count
= 0;
2047 int other_callback_count
= 0;
2049 gpu::gles2::GLES2Interface
* gl
=
2050 output_surface_
->context_provider()->ContextGL();
2051 gpu::ContextSupport
* context_support
=
2052 output_surface_
->context_provider()->ContextSupport();
2054 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
2056 context_support
->SignalSyncPoint(
2057 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
2058 EXPECT_EQ(0, sync_point_callback_count
);
2059 EXPECT_EQ(0, other_callback_count
);
2061 // Make the sync point happen.
2063 // Post a task after the sync point.
2064 base::MessageLoop::current()->PostTask(
2065 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
2067 base::MessageLoop::current()->Run();
2069 // The sync point should have happened.
2070 EXPECT_EQ(1, sync_point_callback_count
);
2071 EXPECT_EQ(1, other_callback_count
);
2073 #endif // OS_ANDROID