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 "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "cc/base/math_util.h"
13 #include "cc/output/compositor_frame_metadata.h"
14 #include "cc/output/copy_output_request.h"
15 #include "cc/output/copy_output_result.h"
16 #include "cc/output/overlay_strategy_single_on_top.h"
17 #include "cc/output/texture_mailbox_deleter.h"
18 #include "cc/quads/texture_draw_quad.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/test/fake_impl_proxy.h"
21 #include "cc/test/fake_layer_tree_host_impl.h"
22 #include "cc/test/fake_output_surface.h"
23 #include "cc/test/fake_output_surface_client.h"
24 #include "cc/test/fake_renderer_client.h"
25 #include "cc/test/fake_resource_provider.h"
26 #include "cc/test/pixel_test.h"
27 #include "cc/test/render_pass_test_common.h"
28 #include "cc/test/render_pass_test_utils.h"
29 #include "cc/test/test_shared_bitmap_manager.h"
30 #include "cc/test/test_web_graphics_context_3d.h"
31 #include "gpu/GLES2/gl2extchromium.h"
32 #include "gpu/command_buffer/client/context_support.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/skia/include/core/SkImageFilter.h"
36 #include "third_party/skia/include/core/SkMatrix.h"
37 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
38 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
39 #include "ui/gfx/transform.h"
42 using testing::AnyNumber
;
44 using testing::AtLeast
;
45 using testing::ElementsAre
;
46 using testing::Expectation
;
47 using testing::InSequence
;
49 using testing::Return
;
50 using testing::StrictMock
;
54 class GLRendererTest
: public testing::Test
{
56 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
58 RenderPassList render_passes_in_draw_order_
;
61 #define EXPECT_PROGRAM_VALID(program_binding) \
63 EXPECT_TRUE((program_binding)->program()); \
64 EXPECT_TRUE((program_binding)->initialized()); \
67 static inline SkXfermode::Mode
BlendModeToSkXfermode(BlendMode blend_mode
) {
70 case BLEND_MODE_NORMAL
:
71 return SkXfermode::kSrcOver_Mode
;
72 case BLEND_MODE_SCREEN
:
73 return SkXfermode::kScreen_Mode
;
74 case BLEND_MODE_OVERLAY
:
75 return SkXfermode::kOverlay_Mode
;
76 case BLEND_MODE_DARKEN
:
77 return SkXfermode::kDarken_Mode
;
78 case BLEND_MODE_LIGHTEN
:
79 return SkXfermode::kLighten_Mode
;
80 case BLEND_MODE_COLOR_DODGE
:
81 return SkXfermode::kColorDodge_Mode
;
82 case BLEND_MODE_COLOR_BURN
:
83 return SkXfermode::kColorBurn_Mode
;
84 case BLEND_MODE_HARD_LIGHT
:
85 return SkXfermode::kHardLight_Mode
;
86 case BLEND_MODE_SOFT_LIGHT
:
87 return SkXfermode::kSoftLight_Mode
;
88 case BLEND_MODE_DIFFERENCE
:
89 return SkXfermode::kDifference_Mode
;
90 case BLEND_MODE_EXCLUSION
:
91 return SkXfermode::kExclusion_Mode
;
92 case BLEND_MODE_MULTIPLY
:
93 return SkXfermode::kMultiply_Mode
;
95 return SkXfermode::kHue_Mode
;
96 case BLEND_MODE_SATURATION
:
97 return SkXfermode::kSaturation_Mode
;
98 case BLEND_MODE_COLOR
:
99 return SkXfermode::kColor_Mode
;
100 case BLEND_MODE_LUMINOSITY
:
101 return SkXfermode::kLuminosity_Mode
;
103 return SkXfermode::kSrcOver_Mode
;
106 // Explicitly named to be a friend in GLRenderer for shader access.
107 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
109 void SetUp() override
{
110 GLRendererPixelTest::SetUp();
111 ASSERT_FALSE(renderer()->IsContextLost());
114 void TearDown() override
{
115 GLRendererPixelTest::TearDown();
116 ASSERT_FALSE(renderer()->IsContextLost());
119 void TestBasicShaders() {
120 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
122 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
123 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
126 void TestShadersWithPrecision(TexCoordPrecision precision
) {
127 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
128 if (renderer()->Capabilities().using_egl_image
)
129 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
131 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
134 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision
,
135 BlendMode blend_mode
) {
136 EXPECT_PROGRAM_VALID(
137 renderer()->GetRenderPassProgram(precision
, blend_mode
));
138 EXPECT_PROGRAM_VALID(
139 renderer()->GetRenderPassProgramAA(precision
, blend_mode
));
142 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision
,
143 SamplerType sampler
) {
144 if (!renderer()->Capabilities().using_egl_image
&&
145 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
146 // This will likely be hit in tests due to usage of osmesa.
150 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
, sampler
));
151 EXPECT_PROGRAM_VALID(
152 renderer()->GetNonPremultipliedTextureProgram(precision
, sampler
));
153 EXPECT_PROGRAM_VALID(
154 renderer()->GetTextureBackgroundProgram(precision
, sampler
));
155 EXPECT_PROGRAM_VALID(
156 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
,
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
160 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
161 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
162 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
163 EXPECT_PROGRAM_VALID(
164 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
165 EXPECT_PROGRAM_VALID(
166 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
167 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
, sampler
));
168 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
, sampler
));
171 void TestShadersWithMasks(TexCoordPrecision precision
,
173 BlendMode blend_mode
,
174 bool mask_for_background
) {
175 if (!renderer()->Capabilities().using_egl_image
&&
176 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
177 // This will likely be hit in tests due to usage of osmesa.
181 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
182 precision
, sampler
, blend_mode
, mask_for_background
));
183 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
184 precision
, sampler
, blend_mode
, mask_for_background
));
185 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
186 precision
, sampler
, blend_mode
, mask_for_background
));
187 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
188 precision
, sampler
, blend_mode
, mask_for_background
));
194 #if !defined(OS_ANDROID) && !defined(OS_WIN)
195 static const TexCoordPrecision kPrecisionList
[] = {TEX_COORD_PRECISION_MEDIUM
,
196 TEX_COORD_PRECISION_HIGH
};
198 static const BlendMode kBlendModeList
[LAST_BLEND_MODE
+ 1] = {
205 BLEND_MODE_COLOR_DODGE
,
206 BLEND_MODE_COLOR_BURN
,
207 BLEND_MODE_HARD_LIGHT
,
208 BLEND_MODE_SOFT_LIGHT
,
209 BLEND_MODE_DIFFERENCE
,
210 BLEND_MODE_EXCLUSION
,
213 BLEND_MODE_SATURATION
,
215 BLEND_MODE_LUMINOSITY
,
218 static const SamplerType kSamplerList
[] = {
220 SAMPLER_TYPE_2D_RECT
,
221 SAMPLER_TYPE_EXTERNAL_OES
,
224 TEST_F(GLRendererShaderPixelTest
, BasicShadersCompile
) {
228 class PrecisionShaderPixelTest
229 : public GLRendererShaderPixelTest
,
230 public ::testing::WithParamInterface
<TexCoordPrecision
> {};
232 TEST_P(PrecisionShaderPixelTest
, ShadersCompile
) {
233 TestShadersWithPrecision(GetParam());
236 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile
,
237 PrecisionShaderPixelTest
,
238 ::testing::ValuesIn(kPrecisionList
));
240 class PrecisionBlendShaderPixelTest
241 : public GLRendererShaderPixelTest
,
242 public ::testing::WithParamInterface
<
243 std::tr1::tuple
<TexCoordPrecision
, BlendMode
>> {};
245 TEST_P(PrecisionBlendShaderPixelTest
, ShadersCompile
) {
246 TestShadersWithPrecisionAndBlend(std::tr1::get
<0>(GetParam()),
247 std::tr1::get
<1>(GetParam()));
250 INSTANTIATE_TEST_CASE_P(
251 PrecisionBlendShadersCompile
,
252 PrecisionBlendShaderPixelTest
,
253 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
254 ::testing::ValuesIn(kBlendModeList
)));
256 class PrecisionSamplerShaderPixelTest
257 : public GLRendererShaderPixelTest
,
258 public ::testing::WithParamInterface
<
259 std::tr1::tuple
<TexCoordPrecision
, SamplerType
>> {};
261 TEST_P(PrecisionSamplerShaderPixelTest
, ShadersCompile
) {
262 TestShadersWithPrecisionAndSampler(std::tr1::get
<0>(GetParam()),
263 std::tr1::get
<1>(GetParam()));
266 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile
,
267 PrecisionSamplerShaderPixelTest
,
268 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
269 ::testing::ValuesIn(kSamplerList
)));
271 class MaskShaderPixelTest
272 : public GLRendererShaderPixelTest
,
273 public ::testing::WithParamInterface
<
274 std::tr1::tuple
<TexCoordPrecision
, SamplerType
, BlendMode
, bool>> {};
276 TEST_P(MaskShaderPixelTest
, ShadersCompile
) {
277 TestShadersWithMasks(
278 std::tr1::get
<0>(GetParam()), std::tr1::get
<1>(GetParam()),
279 std::tr1::get
<2>(GetParam()), std::tr1::get
<3>(GetParam()));
282 INSTANTIATE_TEST_CASE_P(MaskShadersCompile
,
284 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
285 ::testing::ValuesIn(kSamplerList
),
286 ::testing::ValuesIn(kBlendModeList
),
291 class FakeRendererGL
: public GLRenderer
{
293 FakeRendererGL(RendererClient
* client
,
294 const RendererSettings
* settings
,
295 OutputSurface
* output_surface
,
296 ResourceProvider
* resource_provider
)
304 FakeRendererGL(RendererClient
* client
,
305 const RendererSettings
* settings
,
306 OutputSurface
* output_surface
,
307 ResourceProvider
* resource_provider
,
308 TextureMailboxDeleter
* texture_mailbox_deleter
)
313 texture_mailbox_deleter
,
316 void SetOverlayProcessor(OverlayProcessor
* processor
) {
317 overlay_processor_
.reset(processor
);
320 // GLRenderer methods.
322 // Changing visibility to public.
323 using GLRenderer::IsBackbufferDiscarded
;
324 using GLRenderer::DoDrawQuad
;
325 using GLRenderer::BeginDrawingFrame
;
326 using GLRenderer::FinishDrawingQuadList
;
327 using GLRenderer::stencil_enabled
;
330 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
332 GLRendererWithDefaultHarnessTest() {
334 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
335 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
337 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
338 resource_provider_
= FakeResourceProvider::Create(
339 output_surface_
.get(), shared_bitmap_manager_
.get());
340 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
342 output_surface_
.get(),
343 resource_provider_
.get()));
346 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
348 RendererSettings settings_
;
349 FakeOutputSurfaceClient output_surface_client_
;
350 scoped_ptr
<FakeOutputSurface
> output_surface_
;
351 FakeRendererClient renderer_client_
;
352 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
353 scoped_ptr
<ResourceProvider
> resource_provider_
;
354 scoped_ptr
<FakeRendererGL
> renderer_
;
357 // Closing the namespace here so that GLRendererShaderTest can take advantage
358 // of the friend relationship with GLRenderer and all of the mock classes
359 // declared above it.
362 class GLRendererShaderTest
: public GLRendererTest
{
364 GLRendererShaderTest() {
365 output_surface_
= FakeOutputSurface::Create3d().Pass();
366 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
368 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
369 resource_provider_
= FakeResourceProvider::Create(
370 output_surface_
.get(), shared_bitmap_manager_
.get());
371 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
373 output_surface_
.get(),
374 resource_provider_
.get()));
377 void TestRenderPassProgram(TexCoordPrecision precision
,
378 BlendMode blend_mode
) {
379 EXPECT_PROGRAM_VALID(
380 &renderer_
->render_pass_program_
[precision
][blend_mode
]);
381 EXPECT_EQ(renderer_
->render_pass_program_
[precision
][blend_mode
].program(),
382 renderer_
->program_shadow_
);
385 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
,
386 BlendMode blend_mode
) {
387 EXPECT_PROGRAM_VALID(
388 &renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]);
390 renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]
392 renderer_
->program_shadow_
);
395 void TestRenderPassMaskProgram(TexCoordPrecision precision
,
397 BlendMode blend_mode
) {
398 EXPECT_PROGRAM_VALID(
399 &renderer_
->render_pass_mask_program_
[precision
]
404 renderer_
->render_pass_mask_program_
[precision
]
408 renderer_
->program_shadow_
);
411 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
,
413 BlendMode blend_mode
) {
414 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_
415 [precision
][sampler
][blend_mode
][NO_MASK
]);
416 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_
417 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
418 renderer_
->program_shadow_
);
421 void TestRenderPassProgramAA(TexCoordPrecision precision
,
422 BlendMode blend_mode
) {
423 EXPECT_PROGRAM_VALID(
424 &renderer_
->render_pass_program_aa_
[precision
][blend_mode
]);
426 renderer_
->render_pass_program_aa_
[precision
][blend_mode
].program(),
427 renderer_
->program_shadow_
);
430 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
,
431 BlendMode blend_mode
) {
432 EXPECT_PROGRAM_VALID(
434 ->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]);
436 renderer_
->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]
438 renderer_
->program_shadow_
);
441 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
,
443 BlendMode blend_mode
) {
444 EXPECT_PROGRAM_VALID(
446 ->render_pass_mask_program_aa_
447 [precision
][sampler
][blend_mode
][NO_MASK
]);
449 renderer_
->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]
451 renderer_
->program_shadow_
);
454 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
,
456 BlendMode blend_mode
) {
457 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_aa_
458 [precision
][sampler
][blend_mode
][NO_MASK
]);
459 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
460 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
461 renderer_
->program_shadow_
);
464 void TestSolidColorProgramAA() {
465 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
466 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
467 renderer_
->program_shadow_
);
470 RendererSettings settings_
;
471 FakeOutputSurfaceClient output_surface_client_
;
472 scoped_ptr
<FakeOutputSurface
> output_surface_
;
473 FakeRendererClient renderer_client_
;
474 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
475 scoped_ptr
<ResourceProvider
> resource_provider_
;
476 scoped_ptr
<FakeRendererGL
> renderer_
;
481 // Test GLRenderer DiscardBackbuffer functionality:
482 // Suggest discarding framebuffer when one exists and the renderer is not
484 // Expected: it is discarded and damage tracker is reset.
486 GLRendererWithDefaultHarnessTest
,
487 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
488 renderer_
->SetVisible(false);
489 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
490 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
493 // Test GLRenderer DiscardBackbuffer functionality:
494 // Suggest discarding framebuffer when one exists and the renderer is visible.
495 // Expected: the allocation is ignored.
496 TEST_F(GLRendererWithDefaultHarnessTest
,
497 SuggestBackbufferNoDoNothingWhenVisible
) {
498 renderer_
->SetVisible(true);
499 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
500 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
503 // Test GLRenderer DiscardBackbuffer functionality:
504 // Suggest discarding framebuffer when one does not exist.
505 // Expected: it does nothing.
506 TEST_F(GLRendererWithDefaultHarnessTest
,
507 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
508 renderer_
->SetVisible(false);
509 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
510 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
512 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
513 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
516 // Test GLRenderer DiscardBackbuffer functionality:
517 // Begin drawing a frame while a framebuffer is discarded.
518 // Expected: will recreate framebuffer.
519 TEST_F(GLRendererWithDefaultHarnessTest
,
520 DiscardedBackbufferIsRecreatedForScopeDuration
) {
521 gfx::Rect
viewport_rect(1, 1);
522 renderer_
->SetVisible(false);
523 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
524 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
526 AddRenderPass(&render_passes_in_draw_order_
,
531 renderer_
->SetVisible(true);
532 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
537 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
540 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
543 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
544 gfx::Rect
viewport_rect(1, 1);
545 EXPECT_FALSE(renderer_
->stencil_enabled());
547 output_surface_
->set_has_external_stencil_test(true);
549 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
553 root_pass
->has_transparent_background
= false;
555 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
560 EXPECT_TRUE(renderer_
->stencil_enabled());
563 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
565 ForbidSynchronousCallContext() {}
567 void getAttachedShaders(GLuint program
,
570 GLuint
* shaders
) override
{
573 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
577 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
578 void getBufferParameteriv(GLenum target
,
580 GLint
* value
) override
{
583 GLenum
getError() override
{
587 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
588 void getFramebufferAttachmentParameteriv(GLenum target
,
591 GLint
* value
) override
{
594 void getIntegerv(GLenum pname
, GLint
* value
) override
{
595 if (pname
== GL_MAX_TEXTURE_SIZE
) {
596 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
603 // We allow querying the shader compilation and program link status in debug
604 // mode, but not release.
605 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
613 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
621 void getRenderbufferParameteriv(GLenum target
,
623 GLint
* value
) override
{
627 void getShaderPrecisionFormat(GLenum shadertype
,
628 GLenum precisiontype
,
630 GLint
* precision
) override
{
633 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
636 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
639 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
642 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
645 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
649 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
652 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
655 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
660 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
661 FakeOutputSurfaceClient output_surface_client
;
662 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
663 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
664 CHECK(output_surface
->BindToClient(&output_surface_client
));
666 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
667 new TestSharedBitmapManager());
668 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
669 output_surface
.get(), shared_bitmap_manager
.get());
671 RendererSettings settings
;
672 FakeRendererClient renderer_client
;
673 FakeRendererGL
renderer(&renderer_client
,
675 output_surface
.get(),
676 resource_provider
.get());
679 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
681 LoseContextOnFirstGetContext() {}
683 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
684 context_lost_
= true;
688 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
689 context_lost_
= true;
694 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
695 FakeOutputSurfaceClient output_surface_client
;
696 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
697 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
698 CHECK(output_surface
->BindToClient(&output_surface_client
));
700 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
701 new TestSharedBitmapManager());
702 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
703 output_surface
.get(), shared_bitmap_manager
.get());
705 RendererSettings settings
;
706 FakeRendererClient renderer_client
;
707 FakeRendererGL
renderer(&renderer_client
,
709 output_surface
.get(),
710 resource_provider
.get());
713 class ClearCountingContext
: public TestWebGraphicsContext3D
{
715 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
717 MOCK_METHOD3(discardFramebufferEXT
,
719 GLsizei numAttachments
,
720 const GLenum
* attachments
));
721 MOCK_METHOD1(clear
, void(GLbitfield mask
));
724 TEST_F(GLRendererTest
, OpaqueBackground
) {
725 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
726 ClearCountingContext
* context
= context_owned
.get();
728 FakeOutputSurfaceClient output_surface_client
;
729 scoped_ptr
<OutputSurface
> output_surface(
730 FakeOutputSurface::Create3d(context_owned
.Pass()));
731 CHECK(output_surface
->BindToClient(&output_surface_client
));
733 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
734 new TestSharedBitmapManager());
735 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
736 output_surface
.get(), 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
= FakeResourceProvider::Create(
782 output_surface
.get(), shared_bitmap_manager
.get());
784 RendererSettings settings
;
785 FakeRendererClient renderer_client
;
786 FakeRendererGL
renderer(&renderer_client
,
788 output_surface
.get(),
789 resource_provider
.get());
791 gfx::Rect
viewport_rect(1, 1);
792 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
796 root_pass
->has_transparent_background
= true;
798 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
799 EXPECT_CALL(*context
, clear(_
)).Times(1);
800 renderer
.DrawFrame(&render_passes_in_draw_order_
,
806 Mock::VerifyAndClearExpectations(context
);
809 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
810 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
811 ClearCountingContext
* context
= context_owned
.get();
813 FakeOutputSurfaceClient output_surface_client
;
814 scoped_ptr
<OutputSurface
> output_surface(
815 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
816 CHECK(output_surface
->BindToClient(&output_surface_client
));
818 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
819 new TestSharedBitmapManager());
820 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
821 output_surface
.get(), shared_bitmap_manager
.get());
823 RendererSettings settings
;
824 FakeRendererClient renderer_client
;
825 FakeRendererGL
renderer(&renderer_client
,
827 output_surface
.get(),
828 resource_provider
.get());
830 gfx::Rect
viewport_rect(1, 1);
831 AddRenderPass(&render_passes_in_draw_order_
,
836 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
837 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
839 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
840 renderer
.DrawFrame(&render_passes_in_draw_order_
,
845 Mock::VerifyAndClearExpectations(context
);
848 class VisibilityChangeIsLastCallTrackingContext
849 : public TestWebGraphicsContext3D
{
851 VisibilityChangeIsLastCallTrackingContext()
852 : last_call_was_set_visibility_(false) {}
854 // TestWebGraphicsContext3D methods.
855 void flush() override
{ last_call_was_set_visibility_
= false; }
856 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
857 void deleteFramebuffer(GLuint
) override
{
858 last_call_was_set_visibility_
= false;
860 void deleteQueryEXT(GLuint
) override
{
861 last_call_was_set_visibility_
= false;
863 void deleteRenderbuffer(GLuint
) override
{
864 last_call_was_set_visibility_
= false;
867 // Methods added for test.
868 void set_last_call_was_visibility(bool visible
) {
869 DCHECK(last_call_was_set_visibility_
== false);
870 last_call_was_set_visibility_
= true;
872 bool last_call_was_set_visibility() const {
873 return last_call_was_set_visibility_
;
877 bool last_call_was_set_visibility_
;
880 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
881 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
882 new VisibilityChangeIsLastCallTrackingContext
);
883 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
885 scoped_refptr
<TestContextProvider
> provider
=
886 TestContextProvider::Create(context_owned
.Pass());
888 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
889 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
890 base::Unretained(context
)));
892 FakeOutputSurfaceClient output_surface_client
;
893 scoped_ptr
<OutputSurface
> output_surface(
894 FakeOutputSurface::Create3d(provider
));
895 CHECK(output_surface
->BindToClient(&output_surface_client
));
897 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
898 new TestSharedBitmapManager());
899 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
900 output_surface
.get(), shared_bitmap_manager
.get());
902 RendererSettings settings
;
903 FakeRendererClient renderer_client
;
904 FakeRendererGL
renderer(&renderer_client
,
906 output_surface
.get(),
907 resource_provider
.get());
909 gfx::Rect
viewport_rect(1, 1);
910 AddRenderPass(&render_passes_in_draw_order_
,
915 // Ensure that the call to SetSurfaceVisible is the last call issue to the
916 // GPU process, after glFlush is called, and after the RendererClient's
917 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
918 // RenderClient and the Context by giving them both a pointer to a variable on
920 renderer
.SetVisible(true);
921 renderer
.DrawFrame(&render_passes_in_draw_order_
,
926 renderer
.SetVisible(false);
927 EXPECT_TRUE(context
->last_call_was_set_visibility());
930 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
932 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
933 test_capabilities_
.gpu
.egl_image_external
= true;
936 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
937 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
938 MOCK_METHOD4(drawElements
,
939 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
941 virtual void activeTexture(GLenum texture
) {
942 EXPECT_NE(texture
, active_texture_
);
943 active_texture_
= texture
;
946 GLenum
active_texture() const { return active_texture_
; }
949 GLenum active_texture_
;
952 TEST_F(GLRendererTest
, ActiveTextureState
) {
953 scoped_ptr
<TextureStateTrackingContext
> context_owned(
954 new TextureStateTrackingContext
);
955 TextureStateTrackingContext
* context
= context_owned
.get();
957 FakeOutputSurfaceClient output_surface_client
;
958 scoped_ptr
<OutputSurface
> output_surface(
959 FakeOutputSurface::Create3d(context_owned
.Pass()));
960 CHECK(output_surface
->BindToClient(&output_surface_client
));
962 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
963 new TestSharedBitmapManager());
964 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
965 output_surface
.get(), shared_bitmap_manager
.get());
967 RendererSettings settings
;
968 FakeRendererClient renderer_client
;
969 FakeRendererGL
renderer(&renderer_client
,
971 output_surface
.get(),
972 resource_provider
.get());
974 // During initialization we are allowed to set any texture parameters.
975 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
977 TestRenderPass
* root_pass
=
978 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 1),
979 gfx::Rect(100, 100), gfx::Transform());
980 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
983 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
985 // Set up expected texture filter state transitions that match the quads
986 // created in AppendOneOfEveryQuadType().
987 Mock::VerifyAndClearExpectations(context
);
991 // The sync points for all quads are waited on first. This sync point is
992 // for a texture quad drawn later in the frame.
993 EXPECT_CALL(*context
,
994 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
997 // yuv_quad is drawn with the default linear filter.
998 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1000 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1004 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
1007 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
1008 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1010 // transformed_tile_quad uses GL_LINEAR.
1011 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1013 // scaled_tile_quad also uses GL_LINEAR.
1014 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1016 // The remaining quads also use GL_LINEAR because nearest neighbor
1017 // filtering is currently only used with tile quads.
1018 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(7);
1021 gfx::Rect
viewport_rect(100, 100);
1022 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1027 Mock::VerifyAndClearExpectations(context
);
1030 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
1032 MOCK_METHOD1(clear
, void(GLbitfield mask
));
1033 MOCK_METHOD4(drawElements
,
1034 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1037 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
1038 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
1039 new NoClearRootRenderPassMockContext
);
1040 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
1042 FakeOutputSurfaceClient output_surface_client
;
1043 scoped_ptr
<OutputSurface
> output_surface(
1044 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
1045 CHECK(output_surface
->BindToClient(&output_surface_client
));
1047 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1048 new TestSharedBitmapManager());
1049 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1050 output_surface
.get(), shared_bitmap_manager
.get());
1052 RendererSettings settings
;
1053 settings
.should_clear_root_render_pass
= false;
1055 FakeRendererClient renderer_client
;
1056 FakeRendererGL
renderer(&renderer_client
,
1058 output_surface
.get(),
1059 resource_provider
.get());
1061 gfx::Rect
viewport_rect(10, 10);
1063 RenderPassId
child_pass_id(2, 0);
1064 TestRenderPass
* child_pass
=
1065 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, viewport_rect
,
1067 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
1069 RenderPassId
root_pass_id(1, 0);
1070 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1074 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1077 AddRenderPassQuad(root_pass
, child_pass
);
1080 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
1082 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1085 // First render pass is not the root one, clearing should happen.
1086 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1088 Expectation first_render_pass
=
1089 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1091 // The second render pass is the root one, clearing should be prevented.
1092 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1095 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1098 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1099 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1105 // In multiple render passes all but the root pass should clear the
1107 Mock::VerifyAndClearExpectations(&mock_context
);
1110 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1112 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1114 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1116 void enable(GLenum cap
) override
{
1117 if (cap
== GL_SCISSOR_TEST
)
1118 scissor_enabled_
= true;
1121 void disable(GLenum cap
) override
{
1122 if (cap
== GL_SCISSOR_TEST
)
1123 scissor_enabled_
= false;
1127 bool scissor_enabled_
;
1130 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1131 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1132 new ScissorTestOnClearCheckingContext
);
1134 FakeOutputSurfaceClient output_surface_client
;
1135 scoped_ptr
<OutputSurface
> output_surface(
1136 FakeOutputSurface::Create3d(context_owned
.Pass()));
1137 CHECK(output_surface
->BindToClient(&output_surface_client
));
1139 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1140 new TestSharedBitmapManager());
1141 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1142 output_surface
.get(), shared_bitmap_manager
.get());
1144 RendererSettings settings
;
1145 FakeRendererClient renderer_client
;
1146 FakeRendererGL
renderer(&renderer_client
,
1148 output_surface
.get(),
1149 resource_provider
.get());
1150 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1152 gfx::Rect
viewport_rect(1, 1);
1154 gfx::Rect
grand_child_rect(25, 25);
1155 RenderPassId
grand_child_pass_id(3, 0);
1156 TestRenderPass
* grand_child_pass
=
1157 AddRenderPass(&render_passes_in_draw_order_
,
1158 grand_child_pass_id
,
1161 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1163 gfx::Rect
child_rect(50, 50);
1164 RenderPassId
child_pass_id(2, 0);
1165 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1169 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1171 RenderPassId
root_pass_id(1, 0);
1172 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1176 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1178 AddRenderPassQuad(root_pass
, child_pass
);
1179 AddRenderPassQuad(child_pass
, grand_child_pass
);
1181 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1182 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1189 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1191 DiscardCheckingContext() : discarded_(0) {
1192 set_have_post_sub_buffer(true);
1193 set_have_discard_framebuffer(true);
1196 void discardFramebufferEXT(GLenum target
,
1197 GLsizei numAttachments
,
1198 const GLenum
* attachments
) override
{
1202 int discarded() const { return discarded_
; }
1203 void reset() { discarded_
= 0; }
1209 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1211 explicit NonReshapableOutputSurface(
1212 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1213 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1215 surface_size_
= gfx::Size(500, 500);
1217 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1218 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1221 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1222 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1223 DiscardCheckingContext
* context
= context_owned
.get();
1225 FakeOutputSurfaceClient output_surface_client
;
1226 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1227 new NonReshapableOutputSurface(context_owned
.Pass()));
1228 CHECK(output_surface
->BindToClient(&output_surface_client
));
1229 output_surface
->set_fixed_size(gfx::Size(100, 100));
1231 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1232 new TestSharedBitmapManager());
1233 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1234 output_surface
.get(), shared_bitmap_manager
.get());
1236 RendererSettings settings
;
1237 settings
.partial_swap_enabled
= true;
1238 FakeRendererClient renderer_client
;
1239 FakeRendererGL
renderer(&renderer_client
,
1241 output_surface
.get(),
1242 resource_provider
.get());
1243 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1245 gfx::Rect
viewport_rect(100, 100);
1246 gfx::Rect
clip_rect(100, 100);
1249 // Partial frame, should not discard.
1250 RenderPassId
root_pass_id(1, 0);
1251 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1255 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1256 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1258 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1259 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1264 EXPECT_EQ(0, context
->discarded());
1268 // Full frame, should discard.
1269 RenderPassId
root_pass_id(1, 0);
1270 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1274 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1275 root_pass
->damage_rect
= root_pass
->output_rect
;
1277 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1278 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1283 EXPECT_EQ(1, context
->discarded());
1287 // Full frame, external scissor is set, should not discard.
1288 output_surface
->set_has_external_stencil_test(true);
1289 RenderPassId
root_pass_id(1, 0);
1290 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1294 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1295 root_pass
->damage_rect
= root_pass
->output_rect
;
1296 root_pass
->has_transparent_background
= false;
1298 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1299 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1304 EXPECT_EQ(0, context
->discarded());
1306 output_surface
->set_has_external_stencil_test(false);
1309 // Full frame, clipped, should not discard.
1310 clip_rect
= gfx::Rect(10, 10, 10, 10);
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(0, context
->discarded());
1329 // Full frame, doesn't cover the surface, should not discard.
1330 viewport_rect
= gfx::Rect(10, 10, 10, 10);
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
;
1339 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1340 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1345 EXPECT_EQ(0, context
->discarded());
1349 // Full frame, doesn't cover the surface (no offset), should not discard.
1350 clip_rect
= gfx::Rect(100, 100);
1351 viewport_rect
= gfx::Rect(50, 50);
1352 RenderPassId
root_pass_id(1, 0);
1353 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1357 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1358 root_pass
->damage_rect
= root_pass
->output_rect
;
1360 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1361 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1366 EXPECT_EQ(0, context
->discarded());
1371 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1373 MOCK_METHOD4(viewport
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1374 MOCK_METHOD4(scissor
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1377 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1378 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1379 // and maintains a fixed size. This test verifies that glViewport and
1380 // glScissor's Y coordinate is flipped correctly in this environment, and that
1381 // the glViewport can be at a nonzero origin within the surface.
1382 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1383 new FlippedScissorAndViewportContext
);
1385 // We expect exactly one call to viewport on this context and exactly two
1386 // to scissor (one to scissor the clear, one to scissor the quad draw).
1387 EXPECT_CALL(*context_owned
, viewport(10, 390, 100, 100));
1388 EXPECT_CALL(*context_owned
, scissor(10, 390, 100, 100));
1389 EXPECT_CALL(*context_owned
, scissor(30, 450, 20, 20));
1391 FakeOutputSurfaceClient output_surface_client
;
1392 scoped_ptr
<OutputSurface
> output_surface(
1393 new NonReshapableOutputSurface(context_owned
.Pass()));
1394 CHECK(output_surface
->BindToClient(&output_surface_client
));
1396 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1397 new TestSharedBitmapManager());
1398 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1399 output_surface
.get(), shared_bitmap_manager
.get());
1401 RendererSettings settings
;
1402 FakeRendererClient renderer_client
;
1403 FakeRendererGL
renderer(&renderer_client
,
1405 output_surface
.get(),
1406 resource_provider
.get());
1407 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1409 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1410 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1411 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1413 RenderPassId
root_pass_id(1, 0);
1414 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1418 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1420 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1421 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1423 device_viewport_rect
,
1424 device_viewport_rect
,
1428 TEST_F(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1429 // When using render-to-FBO to display the surface, all rendering is done
1430 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1431 // the correct framebuffer during rendering, if changed.
1432 // Note: there is one path that will set it to 0, but that is after the render
1434 FakeOutputSurfaceClient output_surface_client
;
1435 scoped_ptr
<FakeOutputSurface
> output_surface(
1436 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1437 CHECK(output_surface
->BindToClient(&output_surface_client
));
1439 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1440 new TestSharedBitmapManager());
1441 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1442 output_surface
.get(), shared_bitmap_manager
.get());
1444 RendererSettings settings
;
1445 FakeRendererClient renderer_client
;
1446 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1447 resource_provider
.get());
1448 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1450 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1451 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1452 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1454 RenderPassId
root_pass_id(1, 0);
1455 TestRenderPass
* root_pass
=
1456 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1458 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1461 gpu::gles2::GLES2Interface
* gl
=
1462 output_surface
->context_provider()->ContextGL();
1463 gl
->GenFramebuffers(1, &fbo
);
1464 output_surface
->set_framebuffer(fbo
);
1466 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1467 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1468 device_viewport_rect
, false);
1471 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1472 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1475 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1476 gfx::Rect
viewport_rect(1, 1);
1478 gfx::Rect
child_rect(50, 50);
1479 RenderPassId
child_pass_id(2, 0);
1480 TestRenderPass
* child_pass
;
1482 RenderPassId
root_pass_id(1, 0);
1483 TestRenderPass
* root_pass
;
1485 ResourceId mask
= resource_provider_
->CreateResource(
1486 gfx::Size(20, 12), GL_CLAMP_TO_EDGE
,
1487 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1488 resource_provider_
->best_texture_format());
1489 resource_provider_
->AllocateForTesting(mask
);
1491 SkScalar matrix
[20];
1492 float amount
= 0.5f
;
1493 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1494 matrix
[1] = 0.715f
- 0.715f
* amount
;
1495 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1496 matrix
[3] = matrix
[4] = 0;
1497 matrix
[5] = 0.213f
- 0.213f
* amount
;
1498 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1499 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1500 matrix
[8] = matrix
[9] = 0;
1501 matrix
[10] = 0.213f
- 0.213f
* amount
;
1502 matrix
[11] = 0.715f
- 0.715f
* amount
;
1503 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1504 matrix
[13] = matrix
[14] = 0;
1505 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1507 skia::RefPtr
<SkColorFilter
> color_filter(
1508 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1509 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1510 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1511 FilterOperations filters
;
1512 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1514 gfx::Transform transform_causing_aa
;
1515 transform_causing_aa
.Rotate(20.0);
1517 for (int i
= 0; i
<= LAST_BLEND_MODE
; ++i
) {
1518 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1519 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1520 settings_
.force_blending_with_shaders
= (blend_mode
!= BLEND_MODE_NONE
);
1521 // RenderPassProgram
1522 render_passes_in_draw_order_
.clear();
1523 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1528 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1533 AddRenderPassQuad(root_pass
,
1540 renderer_
->DecideRenderPassAllocationsForFrame(
1541 render_passes_in_draw_order_
);
1542 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1547 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1549 // RenderPassColorMatrixProgram
1550 render_passes_in_draw_order_
.clear();
1552 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1555 transform_causing_aa
);
1557 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1563 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1565 renderer_
->DecideRenderPassAllocationsForFrame(
1566 render_passes_in_draw_order_
);
1567 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1572 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1574 // RenderPassMaskProgram
1575 render_passes_in_draw_order_
.clear();
1577 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1582 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1587 AddRenderPassQuad(root_pass
,
1594 renderer_
->DecideRenderPassAllocationsForFrame(
1595 render_passes_in_draw_order_
);
1596 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1601 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1604 // RenderPassMaskColorMatrixProgram
1605 render_passes_in_draw_order_
.clear();
1607 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1612 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1618 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1620 renderer_
->DecideRenderPassAllocationsForFrame(
1621 render_passes_in_draw_order_
);
1622 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1627 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
,
1628 SAMPLER_TYPE_2D
, blend_mode
);
1630 // RenderPassProgramAA
1631 render_passes_in_draw_order_
.clear();
1633 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1636 transform_causing_aa
);
1638 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1643 AddRenderPassQuad(root_pass
,
1647 transform_causing_aa
,
1650 renderer_
->DecideRenderPassAllocationsForFrame(
1651 render_passes_in_draw_order_
);
1652 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1657 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1659 // RenderPassColorMatrixProgramAA
1660 render_passes_in_draw_order_
.clear();
1662 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1665 transform_causing_aa
);
1667 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1673 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1675 renderer_
->DecideRenderPassAllocationsForFrame(
1676 render_passes_in_draw_order_
);
1677 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1682 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1684 // RenderPassMaskProgramAA
1685 render_passes_in_draw_order_
.clear();
1687 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1690 transform_causing_aa
);
1692 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1697 AddRenderPassQuad(root_pass
,
1701 transform_causing_aa
,
1704 renderer_
->DecideRenderPassAllocationsForFrame(
1705 render_passes_in_draw_order_
);
1706 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1711 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1714 // RenderPassMaskColorMatrixProgramAA
1715 render_passes_in_draw_order_
.clear();
1717 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1720 transform_causing_aa
);
1722 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1725 transform_causing_aa
);
1728 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1730 renderer_
->DecideRenderPassAllocationsForFrame(
1731 render_passes_in_draw_order_
);
1732 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1737 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
,
1738 SAMPLER_TYPE_2D
, blend_mode
);
1742 // At this time, the AA code path cannot be taken if the surface's rect would
1743 // project incorrectly by the given transform, because of w<0 clipping.
1744 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1745 gfx::Rect
child_rect(50, 50);
1746 RenderPassId
child_pass_id(2, 0);
1747 TestRenderPass
* child_pass
;
1749 gfx::Rect
viewport_rect(1, 1);
1750 RenderPassId
root_pass_id(1, 0);
1751 TestRenderPass
* root_pass
;
1753 gfx::Transform transform_preventing_aa
;
1754 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1755 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1756 transform_preventing_aa
.Scale(30.0, 1.0);
1758 // Verify that the test transform and test rect actually do cause the clipped
1759 // flag to trigger. Otherwise we are not testing the intended scenario.
1760 bool clipped
= false;
1761 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1762 ASSERT_TRUE(clipped
);
1764 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1767 transform_preventing_aa
);
1769 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1774 AddRenderPassQuad(root_pass
,
1778 transform_preventing_aa
,
1779 SkXfermode::kSrcOver_Mode
);
1781 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1782 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1788 // If use_aa incorrectly ignores clipping, it will use the
1789 // RenderPassProgramAA shader instead of the RenderPassProgram.
1790 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, BLEND_MODE_NONE
);
1793 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1794 gfx::Rect
viewport_rect(1, 1);
1795 RenderPassId
root_pass_id(1, 0);
1796 TestRenderPass
* root_pass
;
1798 gfx::Transform pixel_aligned_transform_causing_aa
;
1799 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1800 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1802 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1806 AddTransformedQuad(root_pass
,
1809 pixel_aligned_transform_causing_aa
);
1811 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1812 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1818 TestSolidColorProgramAA();
1821 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1823 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1825 // Specifically override methods even if they are unused (used in conjunction
1826 // with StrictMock). We need to make sure that GLRenderer does not issue
1827 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1828 // through the OutputSurface abstraction.
1829 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1830 MOCK_METHOD3(reshapeWithScaleFactor
,
1831 void(int width
, int height
, float scale_factor
));
1832 MOCK_METHOD4(drawElements
,
1833 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1836 class MockOutputSurface
: public OutputSurface
{
1840 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1841 new StrictMock
<OutputSurfaceMockContext
>))) {
1842 surface_size_
= gfx::Size(100, 100);
1844 virtual ~MockOutputSurface() {}
1846 MOCK_METHOD0(EnsureBackbuffer
, void());
1847 MOCK_METHOD0(DiscardBackbuffer
, void());
1848 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1849 MOCK_METHOD0(BindFramebuffer
, void());
1850 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1853 class MockOutputSurfaceTest
: public GLRendererTest
{
1855 virtual void SetUp() {
1856 FakeOutputSurfaceClient output_surface_client_
;
1857 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1859 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1860 resource_provider_
= FakeResourceProvider::Create(
1861 &output_surface_
, shared_bitmap_manager_
.get());
1863 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1866 resource_provider_
.get()));
1869 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1871 void DrawFrame(float device_scale_factor
,
1872 const gfx::Rect
& device_viewport_rect
) {
1873 RenderPassId
render_pass_id(1, 0);
1874 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1876 device_viewport_rect
,
1878 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1880 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1882 EXPECT_CALL(output_surface_
,
1883 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1886 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1888 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1890 renderer_
->DecideRenderPassAllocationsForFrame(
1891 render_passes_in_draw_order_
);
1892 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1893 device_scale_factor
,
1894 device_viewport_rect
,
1895 device_viewport_rect
,
1899 OutputSurfaceMockContext
* Context() {
1900 return static_cast<OutputSurfaceMockContext
*>(
1901 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1905 RendererSettings settings_
;
1906 FakeOutputSurfaceClient output_surface_client_
;
1907 StrictMock
<MockOutputSurface
> output_surface_
;
1908 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1909 scoped_ptr
<ResourceProvider
> resource_provider_
;
1910 FakeRendererClient renderer_client_
;
1911 scoped_ptr
<FakeRendererGL
> renderer_
;
1914 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1915 gfx::Rect
device_viewport_rect(1, 1);
1916 DrawFrame(1.f
, device_viewport_rect
);
1918 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1919 renderer_
->SwapBuffers(CompositorFrameMetadata());
1922 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1923 gfx::Rect
device_viewport_rect(1, 1);
1925 DrawFrame(1.f
, device_viewport_rect
);
1926 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1927 renderer_
->SwapBuffers(CompositorFrameMetadata());
1929 device_viewport_rect
= gfx::Rect(2, 2);
1931 DrawFrame(2.f
, device_viewport_rect
);
1932 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1933 renderer_
->SwapBuffers(CompositorFrameMetadata());
1935 DrawFrame(2.f
, device_viewport_rect
);
1936 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1937 renderer_
->SwapBuffers(CompositorFrameMetadata());
1939 device_viewport_rect
= gfx::Rect(1, 1);
1941 DrawFrame(1.f
, device_viewport_rect
);
1942 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1943 renderer_
->SwapBuffers(CompositorFrameMetadata());
1946 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1948 static void SyncPointCallback(int* callback_count
) {
1949 ++(*callback_count
);
1950 base::MessageLoop::current()->QuitWhenIdle();
1953 static void OtherCallback(int* callback_count
) {
1954 ++(*callback_count
);
1955 base::MessageLoop::current()->QuitWhenIdle();
1959 #if !defined(OS_ANDROID)
1960 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1961 int sync_point_callback_count
= 0;
1962 int other_callback_count
= 0;
1963 gpu::gles2::GLES2Interface
* gl
=
1964 output_surface_
->context_provider()->ContextGL();
1965 gpu::ContextSupport
* context_support
=
1966 output_surface_
->context_provider()->ContextSupport();
1968 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1970 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1971 GL_INNOCENT_CONTEXT_RESET_ARB
);
1973 context_support
->SignalSyncPoint(
1974 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1975 EXPECT_EQ(0, sync_point_callback_count
);
1976 EXPECT_EQ(0, other_callback_count
);
1978 // Make the sync point happen.
1980 // Post a task after the sync point.
1981 base::ThreadTaskRunnerHandle::Get()->PostTask(
1982 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1984 base::MessageLoop::current()->Run();
1986 // The sync point shouldn't have happened since the context was lost.
1987 EXPECT_EQ(0, sync_point_callback_count
);
1988 EXPECT_EQ(1, other_callback_count
);
1991 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1992 int sync_point_callback_count
= 0;
1993 int other_callback_count
= 0;
1995 gpu::gles2::GLES2Interface
* gl
=
1996 output_surface_
->context_provider()->ContextGL();
1997 gpu::ContextSupport
* context_support
=
1998 output_surface_
->context_provider()->ContextSupport();
2000 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
2002 context_support
->SignalSyncPoint(
2003 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
2004 EXPECT_EQ(0, sync_point_callback_count
);
2005 EXPECT_EQ(0, other_callback_count
);
2007 // Make the sync point happen.
2009 // Post a task after the sync point.
2010 base::ThreadTaskRunnerHandle::Get()->PostTask(
2011 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
2013 base::MessageLoop::current()->Run();
2015 // The sync point should have happened.
2016 EXPECT_EQ(1, sync_point_callback_count
);
2017 EXPECT_EQ(1, other_callback_count
);
2019 #endif // OS_ANDROID
2021 class TestOverlayProcessor
: public OverlayProcessor
{
2023 class Strategy
: public OverlayProcessor::Strategy
{
2026 ~Strategy() override
{}
2027 MOCK_METHOD2(Attempt
,
2028 bool(RenderPassList
* render_passes_in_draw_order
,
2029 OverlayCandidateList
* candidates
));
2032 TestOverlayProcessor(OutputSurface
* surface
,
2033 ResourceProvider
* resource_provider
)
2034 : OverlayProcessor(surface
, resource_provider
) {}
2035 ~TestOverlayProcessor() override
{}
2036 void Initialize() override
{
2037 strategy_
= new Strategy();
2038 strategies_
.push_back(scoped_ptr
<OverlayProcessor::Strategy
>(strategy_
));
2041 Strategy
* strategy_
;
2044 void MailboxReleased(unsigned sync_point
,
2046 BlockingTaskRunner
* main_thread_task_runner
) {
2049 void IgnoreCopyResult(scoped_ptr
<CopyOutputResult
> result
) {
2052 TEST_F(GLRendererTest
, DontOverlayWithCopyRequests
) {
2053 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
2054 FakeOutputSurfaceClient output_surface_client
;
2055 scoped_ptr
<OutputSurface
> output_surface(
2056 FakeOutputSurface::Create3d(context_owned
.Pass()));
2057 CHECK(output_surface
->BindToClient(&output_surface_client
));
2059 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2060 new TestSharedBitmapManager());
2061 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2062 output_surface
.get(), shared_bitmap_manager
.get());
2063 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2064 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2066 RendererSettings settings
;
2067 FakeRendererClient renderer_client
;
2068 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2069 resource_provider
.get(), mailbox_deleter
.get());
2071 TestOverlayProcessor
* processor
=
2072 new TestOverlayProcessor(output_surface
.get(), resource_provider
.get());
2073 processor
->Initialize();
2074 renderer
.SetOverlayProcessor(processor
);
2076 gfx::Rect
viewport_rect(1, 1);
2077 TestRenderPass
* root_pass
=
2078 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2079 viewport_rect
, gfx::Transform());
2080 root_pass
->has_transparent_background
= false;
2081 root_pass
->copy_requests
.push_back(
2082 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult
)));
2084 unsigned sync_point
= 0;
2085 TextureMailbox mailbox
=
2086 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2087 mailbox
.set_allow_overlay(true);
2088 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2089 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2090 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2091 mailbox
, release_callback
.Pass());
2092 bool premultiplied_alpha
= false;
2093 bool flipped
= false;
2094 bool nearest_neighbor
= false;
2095 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2097 TextureDrawQuad
* overlay_quad
=
2098 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2099 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2100 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2101 premultiplied_alpha
, gfx::PointF(0, 0),
2102 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2103 flipped
, nearest_neighbor
);
2105 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2106 // Attempt will be called for each strategy in OverlayProcessor. We have
2107 // added a fake strategy, so checking for Attempt calls checks if there was
2108 // any attempt to overlay, which there shouldn't be. We can't use the quad
2109 // list because the render pass is cleaned up by DrawFrame.
2110 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(0);
2111 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2112 viewport_rect
, false);
2113 Mock::VerifyAndClearExpectations(processor
->strategy_
);
2115 // Without a copy request Attempt() should be called once.
2116 root_pass
= AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2117 viewport_rect
, gfx::Transform());
2118 root_pass
->has_transparent_background
= false;
2120 overlay_quad
= root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2121 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2122 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2123 premultiplied_alpha
, gfx::PointF(0, 0),
2124 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2125 flipped
, nearest_neighbor
);
2127 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(1);
2128 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2129 viewport_rect
, false);
2132 class SingleOverlayOnTopProcessor
: public OverlayProcessor
{
2134 class SingleOverlayValidator
: public OverlayCandidateValidator
{
2136 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
2137 ASSERT_EQ(2U, surfaces
->size());
2138 OverlayCandidate
& candidate
= surfaces
->back();
2139 candidate
.overlay_handled
= true;
2143 SingleOverlayOnTopProcessor(OutputSurface
* surface
,
2144 ResourceProvider
* resource_provider
)
2145 : OverlayProcessor(surface
, resource_provider
) {}
2147 void Initialize() override
{
2148 strategies_
.push_back(scoped_ptr
<Strategy
>(
2149 new OverlayStrategySingleOnTop(&validator_
, resource_provider_
)));
2152 SingleOverlayValidator validator_
;
2155 class WaitSyncPointCountingContext
: public TestWebGraphicsContext3D
{
2157 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
2160 class MockOverlayScheduler
{
2162 MOCK_METHOD5(Schedule
,
2163 void(int plane_z_order
,
2164 gfx::OverlayTransform plane_transform
,
2165 unsigned overlay_texture_id
,
2166 const gfx::Rect
& display_bounds
,
2167 const gfx::RectF
& uv_rect
));
2170 TEST_F(GLRendererTest
, OverlaySyncPointsAreProcessed
) {
2171 scoped_ptr
<WaitSyncPointCountingContext
> context_owned(
2172 new WaitSyncPointCountingContext
);
2173 WaitSyncPointCountingContext
* context
= context_owned
.get();
2175 MockOverlayScheduler overlay_scheduler
;
2176 scoped_refptr
<TestContextProvider
> context_provider
=
2177 TestContextProvider::Create(context_owned
.Pass());
2178 context_provider
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2179 &MockOverlayScheduler::Schedule
, base::Unretained(&overlay_scheduler
)));
2181 FakeOutputSurfaceClient output_surface_client
;
2182 scoped_ptr
<OutputSurface
> output_surface(
2183 FakeOutputSurface::Create3d(context_provider
));
2184 CHECK(output_surface
->BindToClient(&output_surface_client
));
2186 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2187 new TestSharedBitmapManager());
2188 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2189 output_surface
.get(), shared_bitmap_manager
.get());
2190 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2191 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2193 RendererSettings settings
;
2194 FakeRendererClient renderer_client
;
2195 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2196 resource_provider
.get(), mailbox_deleter
.get());
2198 SingleOverlayOnTopProcessor
* processor
= new SingleOverlayOnTopProcessor(
2199 output_surface
.get(), resource_provider
.get());
2200 processor
->Initialize();
2201 renderer
.SetOverlayProcessor(processor
);
2203 gfx::Rect
viewport_rect(1, 1);
2204 TestRenderPass
* root_pass
=
2205 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2206 viewport_rect
, gfx::Transform());
2207 root_pass
->has_transparent_background
= false;
2209 unsigned sync_point
= TestRenderPass::kSyncPointForMailboxTextureQuad
;
2210 TextureMailbox mailbox
=
2211 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2212 mailbox
.set_allow_overlay(true);
2213 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2214 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2215 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2216 mailbox
, release_callback
.Pass());
2217 bool premultiplied_alpha
= false;
2218 bool flipped
= false;
2219 bool nearest_neighbor
= false;
2220 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2221 gfx::PointF
uv_top_left(0, 0);
2222 gfx::PointF
uv_bottom_right(1, 1);
2224 TextureDrawQuad
* overlay_quad
=
2225 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2226 SharedQuadState
* shared_state
= root_pass
->CreateAndAppendSharedQuadState();
2227 shared_state
->SetAll(gfx::Transform(), viewport_rect
.size(), viewport_rect
,
2228 viewport_rect
, false, 1, SkXfermode::kSrcOver_Mode
, 0);
2229 overlay_quad
->SetNew(shared_state
, viewport_rect
, viewport_rect
,
2230 viewport_rect
, resource_id
, premultiplied_alpha
,
2231 uv_top_left
, uv_bottom_right
, SK_ColorTRANSPARENT
,
2232 vertex_opacity
, flipped
, nearest_neighbor
);
2234 // Verify that overlay_quad actually gets turned into an overlay, and even
2235 // though it's not drawn, that its sync point is waited on.
2236 EXPECT_CALL(*context
,
2237 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
2239 EXPECT_CALL(overlay_scheduler
,
2240 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE
, _
, viewport_rect
,
2241 BoundingRect(uv_top_left
, uv_bottom_right
))).Times(1);
2243 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2244 viewport_rect
, false);