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_utils.h"
28 #include "cc/test/test_shared_bitmap_manager.h"
29 #include "cc/test/test_web_graphics_context_3d.h"
30 #include "gpu/GLES2/gl2extchromium.h"
31 #include "gpu/command_buffer/client/context_support.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "third_party/skia/include/core/SkImageFilter.h"
35 #include "third_party/skia/include/core/SkMatrix.h"
36 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
37 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
38 #include "ui/gfx/transform.h"
41 using testing::AnyNumber
;
43 using testing::AtLeast
;
44 using testing::ElementsAre
;
45 using testing::Expectation
;
46 using testing::InSequence
;
48 using testing::Return
;
49 using testing::StrictMock
;
53 class GLRendererTest
: public testing::Test
{
55 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
57 RenderPassList render_passes_in_draw_order_
;
60 #define EXPECT_PROGRAM_VALID(program_binding) \
62 EXPECT_TRUE((program_binding)->program()); \
63 EXPECT_TRUE((program_binding)->initialized()); \
66 static inline SkXfermode::Mode
BlendModeToSkXfermode(BlendMode blend_mode
) {
69 case BLEND_MODE_NORMAL
:
70 return SkXfermode::kSrcOver_Mode
;
71 case BLEND_MODE_SCREEN
:
72 return SkXfermode::kScreen_Mode
;
73 case BLEND_MODE_OVERLAY
:
74 return SkXfermode::kOverlay_Mode
;
75 case BLEND_MODE_DARKEN
:
76 return SkXfermode::kDarken_Mode
;
77 case BLEND_MODE_LIGHTEN
:
78 return SkXfermode::kLighten_Mode
;
79 case BLEND_MODE_COLOR_DODGE
:
80 return SkXfermode::kColorDodge_Mode
;
81 case BLEND_MODE_COLOR_BURN
:
82 return SkXfermode::kColorBurn_Mode
;
83 case BLEND_MODE_HARD_LIGHT
:
84 return SkXfermode::kHardLight_Mode
;
85 case BLEND_MODE_SOFT_LIGHT
:
86 return SkXfermode::kSoftLight_Mode
;
87 case BLEND_MODE_DIFFERENCE
:
88 return SkXfermode::kDifference_Mode
;
89 case BLEND_MODE_EXCLUSION
:
90 return SkXfermode::kExclusion_Mode
;
91 case BLEND_MODE_MULTIPLY
:
92 return SkXfermode::kMultiply_Mode
;
94 return SkXfermode::kHue_Mode
;
95 case BLEND_MODE_SATURATION
:
96 return SkXfermode::kSaturation_Mode
;
97 case BLEND_MODE_COLOR
:
98 return SkXfermode::kColor_Mode
;
99 case BLEND_MODE_LUMINOSITY
:
100 return SkXfermode::kLuminosity_Mode
;
102 return SkXfermode::kSrcOver_Mode
;
105 // Explicitly named to be a friend in GLRenderer for shader access.
106 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
108 void SetUp() override
{
109 GLRendererPixelTest::SetUp();
110 ASSERT_FALSE(renderer()->IsContextLost());
113 void TearDown() override
{
114 GLRendererPixelTest::TearDown();
115 ASSERT_FALSE(renderer()->IsContextLost());
118 void TestBasicShaders() {
119 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
120 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
124 void TestShadersWithPrecision(TexCoordPrecision precision
) {
125 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
126 if (renderer()->Capabilities().using_egl_image
)
127 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
129 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
132 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision
,
133 BlendMode blend_mode
) {
134 EXPECT_PROGRAM_VALID(
135 renderer()->GetRenderPassProgram(precision
, blend_mode
));
136 EXPECT_PROGRAM_VALID(
137 renderer()->GetRenderPassProgramAA(precision
, blend_mode
));
140 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision
,
141 SamplerType sampler
) {
142 if (!renderer()->Capabilities().using_egl_image
&&
143 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
144 // This will likely be hit in tests due to usage of osmesa.
148 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
, sampler
));
149 EXPECT_PROGRAM_VALID(
150 renderer()->GetNonPremultipliedTextureProgram(precision
, sampler
));
151 EXPECT_PROGRAM_VALID(
152 renderer()->GetTextureBackgroundProgram(precision
, sampler
));
153 EXPECT_PROGRAM_VALID(
154 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
,
157 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
158 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
160 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
161 EXPECT_PROGRAM_VALID(
162 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
163 EXPECT_PROGRAM_VALID(
164 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
165 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
, sampler
));
166 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
, sampler
));
169 void TestShadersWithMasks(TexCoordPrecision precision
,
171 BlendMode blend_mode
,
172 bool mask_for_background
) {
173 if (!renderer()->Capabilities().using_egl_image
&&
174 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
175 // This will likely be hit in tests due to usage of osmesa.
179 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
180 precision
, sampler
, blend_mode
, mask_for_background
));
181 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
182 precision
, sampler
, blend_mode
, mask_for_background
));
183 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
184 precision
, sampler
, blend_mode
, mask_for_background
));
185 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
186 precision
, sampler
, blend_mode
, mask_for_background
));
192 #if !defined(OS_ANDROID) && !defined(OS_WIN)
193 static const TexCoordPrecision kPrecisionList
[] = {TEX_COORD_PRECISION_MEDIUM
,
194 TEX_COORD_PRECISION_HIGH
};
196 static const BlendMode kBlendModeList
[LAST_BLEND_MODE
+ 1] = {
203 BLEND_MODE_COLOR_DODGE
,
204 BLEND_MODE_COLOR_BURN
,
205 BLEND_MODE_HARD_LIGHT
,
206 BLEND_MODE_SOFT_LIGHT
,
207 BLEND_MODE_DIFFERENCE
,
208 BLEND_MODE_EXCLUSION
,
211 BLEND_MODE_SATURATION
,
213 BLEND_MODE_LUMINOSITY
,
216 static const SamplerType kSamplerList
[] = {
218 SAMPLER_TYPE_2D_RECT
,
219 SAMPLER_TYPE_EXTERNAL_OES
,
222 TEST_F(GLRendererShaderPixelTest
, BasicShadersCompile
) {
226 class PrecisionShaderPixelTest
227 : public GLRendererShaderPixelTest
,
228 public ::testing::WithParamInterface
<TexCoordPrecision
> {};
230 TEST_P(PrecisionShaderPixelTest
, ShadersCompile
) {
231 TestShadersWithPrecision(GetParam());
234 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile
,
235 PrecisionShaderPixelTest
,
236 ::testing::ValuesIn(kPrecisionList
));
238 class PrecisionBlendShaderPixelTest
239 : public GLRendererShaderPixelTest
,
240 public ::testing::WithParamInterface
<
241 std::tr1::tuple
<TexCoordPrecision
, BlendMode
>> {};
243 TEST_P(PrecisionBlendShaderPixelTest
, ShadersCompile
) {
244 TestShadersWithPrecisionAndBlend(std::tr1::get
<0>(GetParam()),
245 std::tr1::get
<1>(GetParam()));
248 INSTANTIATE_TEST_CASE_P(
249 PrecisionBlendShadersCompile
,
250 PrecisionBlendShaderPixelTest
,
251 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
252 ::testing::ValuesIn(kBlendModeList
)));
254 class PrecisionSamplerShaderPixelTest
255 : public GLRendererShaderPixelTest
,
256 public ::testing::WithParamInterface
<
257 std::tr1::tuple
<TexCoordPrecision
, SamplerType
>> {};
259 TEST_P(PrecisionSamplerShaderPixelTest
, ShadersCompile
) {
260 TestShadersWithPrecisionAndSampler(std::tr1::get
<0>(GetParam()),
261 std::tr1::get
<1>(GetParam()));
264 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile
,
265 PrecisionSamplerShaderPixelTest
,
266 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
267 ::testing::ValuesIn(kSamplerList
)));
269 class MaskShaderPixelTest
270 : public GLRendererShaderPixelTest
,
271 public ::testing::WithParamInterface
<
272 std::tr1::tuple
<TexCoordPrecision
, SamplerType
, BlendMode
, bool>> {};
274 TEST_P(MaskShaderPixelTest
, ShadersCompile
) {
275 TestShadersWithMasks(
276 std::tr1::get
<0>(GetParam()), std::tr1::get
<1>(GetParam()),
277 std::tr1::get
<2>(GetParam()), std::tr1::get
<3>(GetParam()));
280 INSTANTIATE_TEST_CASE_P(MaskShadersCompile
,
282 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
283 ::testing::ValuesIn(kSamplerList
),
284 ::testing::ValuesIn(kBlendModeList
),
289 class FakeRendererGL
: public GLRenderer
{
291 FakeRendererGL(RendererClient
* client
,
292 const RendererSettings
* settings
,
293 OutputSurface
* output_surface
,
294 ResourceProvider
* resource_provider
)
302 FakeRendererGL(RendererClient
* client
,
303 const RendererSettings
* settings
,
304 OutputSurface
* output_surface
,
305 ResourceProvider
* resource_provider
,
306 TextureMailboxDeleter
* texture_mailbox_deleter
)
311 texture_mailbox_deleter
,
314 void SetOverlayProcessor(OverlayProcessor
* processor
) {
315 overlay_processor_
.reset(processor
);
318 // GLRenderer methods.
320 // Changing visibility to public.
321 using GLRenderer::IsBackbufferDiscarded
;
322 using GLRenderer::DoDrawQuad
;
323 using GLRenderer::BeginDrawingFrame
;
324 using GLRenderer::FinishDrawingQuadList
;
325 using GLRenderer::stencil_enabled
;
328 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
330 GLRendererWithDefaultHarnessTest() {
332 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
333 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
335 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
336 resource_provider_
= FakeResourceProvider::Create(
337 output_surface_
.get(), shared_bitmap_manager_
.get());
338 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
340 output_surface_
.get(),
341 resource_provider_
.get()));
344 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
346 RendererSettings settings_
;
347 FakeOutputSurfaceClient output_surface_client_
;
348 scoped_ptr
<FakeOutputSurface
> output_surface_
;
349 FakeRendererClient renderer_client_
;
350 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
351 scoped_ptr
<ResourceProvider
> resource_provider_
;
352 scoped_ptr
<FakeRendererGL
> renderer_
;
355 // Closing the namespace here so that GLRendererShaderTest can take advantage
356 // of the friend relationship with GLRenderer and all of the mock classes
357 // declared above it.
360 class GLRendererShaderTest
: public GLRendererTest
{
362 GLRendererShaderTest() {
363 output_surface_
= FakeOutputSurface::Create3d().Pass();
364 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
366 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
367 resource_provider_
= FakeResourceProvider::Create(
368 output_surface_
.get(), shared_bitmap_manager_
.get());
369 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
371 output_surface_
.get(),
372 resource_provider_
.get()));
375 void TestRenderPassProgram(TexCoordPrecision precision
,
376 BlendMode blend_mode
) {
377 EXPECT_PROGRAM_VALID(
378 &renderer_
->render_pass_program_
[precision
][blend_mode
]);
379 EXPECT_EQ(renderer_
->render_pass_program_
[precision
][blend_mode
].program(),
380 renderer_
->program_shadow_
);
383 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
,
384 BlendMode blend_mode
) {
385 EXPECT_PROGRAM_VALID(
386 &renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]);
388 renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]
390 renderer_
->program_shadow_
);
393 void TestRenderPassMaskProgram(TexCoordPrecision precision
,
395 BlendMode blend_mode
) {
396 EXPECT_PROGRAM_VALID(
397 &renderer_
->render_pass_mask_program_
[precision
]
402 renderer_
->render_pass_mask_program_
[precision
]
406 renderer_
->program_shadow_
);
409 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
,
411 BlendMode blend_mode
) {
412 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_
413 [precision
][sampler
][blend_mode
][NO_MASK
]);
414 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_
415 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
416 renderer_
->program_shadow_
);
419 void TestRenderPassProgramAA(TexCoordPrecision precision
,
420 BlendMode blend_mode
) {
421 EXPECT_PROGRAM_VALID(
422 &renderer_
->render_pass_program_aa_
[precision
][blend_mode
]);
424 renderer_
->render_pass_program_aa_
[precision
][blend_mode
].program(),
425 renderer_
->program_shadow_
);
428 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
,
429 BlendMode blend_mode
) {
430 EXPECT_PROGRAM_VALID(
432 ->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]);
434 renderer_
->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]
436 renderer_
->program_shadow_
);
439 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
,
441 BlendMode blend_mode
) {
442 EXPECT_PROGRAM_VALID(
444 ->render_pass_mask_program_aa_
445 [precision
][sampler
][blend_mode
][NO_MASK
]);
447 renderer_
->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]
449 renderer_
->program_shadow_
);
452 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
,
454 BlendMode blend_mode
) {
455 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_aa_
456 [precision
][sampler
][blend_mode
][NO_MASK
]);
457 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
458 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
459 renderer_
->program_shadow_
);
462 void TestSolidColorProgramAA() {
463 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
464 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
465 renderer_
->program_shadow_
);
468 RendererSettings settings_
;
469 FakeOutputSurfaceClient output_surface_client_
;
470 scoped_ptr
<FakeOutputSurface
> output_surface_
;
471 FakeRendererClient renderer_client_
;
472 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
473 scoped_ptr
<ResourceProvider
> resource_provider_
;
474 scoped_ptr
<FakeRendererGL
> renderer_
;
479 // Test GLRenderer DiscardBackbuffer functionality:
480 // Suggest discarding framebuffer when one exists and the renderer is not
482 // Expected: it is discarded and damage tracker is reset.
484 GLRendererWithDefaultHarnessTest
,
485 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
486 renderer_
->SetVisible(false);
487 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
488 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
491 // Test GLRenderer DiscardBackbuffer functionality:
492 // Suggest discarding framebuffer when one exists and the renderer is visible.
493 // Expected: the allocation is ignored.
494 TEST_F(GLRendererWithDefaultHarnessTest
,
495 SuggestBackbufferNoDoNothingWhenVisible
) {
496 renderer_
->SetVisible(true);
497 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
498 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
501 // Test GLRenderer DiscardBackbuffer functionality:
502 // Suggest discarding framebuffer when one does not exist.
503 // Expected: it does nothing.
504 TEST_F(GLRendererWithDefaultHarnessTest
,
505 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
506 renderer_
->SetVisible(false);
507 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
508 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
510 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
511 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
514 // Test GLRenderer DiscardBackbuffer functionality:
515 // Begin drawing a frame while a framebuffer is discarded.
516 // Expected: will recreate framebuffer.
517 TEST_F(GLRendererWithDefaultHarnessTest
,
518 DiscardedBackbufferIsRecreatedForScopeDuration
) {
519 gfx::Rect
viewport_rect(1, 1);
520 renderer_
->SetVisible(false);
521 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
522 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
524 AddRenderPass(&render_passes_in_draw_order_
,
529 renderer_
->SetVisible(true);
530 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
535 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
538 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
541 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
542 gfx::Rect
viewport_rect(1, 1);
543 EXPECT_FALSE(renderer_
->stencil_enabled());
545 output_surface_
->set_has_external_stencil_test(true);
547 RenderPass
* root_pass
=
548 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
549 viewport_rect
, gfx::Transform());
550 root_pass
->has_transparent_background
= false;
552 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
557 EXPECT_TRUE(renderer_
->stencil_enabled());
560 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
562 ForbidSynchronousCallContext() {}
564 void getAttachedShaders(GLuint program
,
567 GLuint
* shaders
) override
{
570 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
574 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
575 void getBufferParameteriv(GLenum target
,
577 GLint
* value
) override
{
580 GLenum
getError() override
{
584 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
585 void getFramebufferAttachmentParameteriv(GLenum target
,
588 GLint
* value
) override
{
591 void getIntegerv(GLenum pname
, GLint
* value
) override
{
592 if (pname
== GL_MAX_TEXTURE_SIZE
) {
593 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
600 // We allow querying the shader compilation and program link status in debug
601 // mode, but not release.
602 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
610 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
618 void getRenderbufferParameteriv(GLenum target
,
620 GLint
* value
) override
{
624 void getShaderPrecisionFormat(GLenum shadertype
,
625 GLenum precisiontype
,
627 GLint
* precision
) override
{
630 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
633 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
636 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
639 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
642 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
646 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
649 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
652 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
657 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
658 FakeOutputSurfaceClient output_surface_client
;
659 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
660 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
661 CHECK(output_surface
->BindToClient(&output_surface_client
));
663 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
664 new TestSharedBitmapManager());
665 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
666 output_surface
.get(), shared_bitmap_manager
.get());
668 RendererSettings settings
;
669 FakeRendererClient renderer_client
;
670 FakeRendererGL
renderer(&renderer_client
,
672 output_surface
.get(),
673 resource_provider
.get());
676 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
678 LoseContextOnFirstGetContext() {}
680 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
681 context_lost_
= true;
685 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
686 context_lost_
= true;
691 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
692 FakeOutputSurfaceClient output_surface_client
;
693 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
694 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
695 CHECK(output_surface
->BindToClient(&output_surface_client
));
697 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
698 new TestSharedBitmapManager());
699 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
700 output_surface
.get(), shared_bitmap_manager
.get());
702 RendererSettings settings
;
703 FakeRendererClient renderer_client
;
704 FakeRendererGL
renderer(&renderer_client
,
706 output_surface
.get(),
707 resource_provider
.get());
710 class ClearCountingContext
: public TestWebGraphicsContext3D
{
712 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
714 MOCK_METHOD3(discardFramebufferEXT
,
716 GLsizei numAttachments
,
717 const GLenum
* attachments
));
718 MOCK_METHOD1(clear
, void(GLbitfield mask
));
721 TEST_F(GLRendererTest
, OpaqueBackground
) {
722 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
723 ClearCountingContext
* context
= context_owned
.get();
725 FakeOutputSurfaceClient output_surface_client
;
726 scoped_ptr
<OutputSurface
> output_surface(
727 FakeOutputSurface::Create3d(context_owned
.Pass()));
728 CHECK(output_surface
->BindToClient(&output_surface_client
));
730 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
731 new TestSharedBitmapManager());
732 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
733 output_surface
.get(), shared_bitmap_manager
.get());
735 RendererSettings settings
;
736 FakeRendererClient renderer_client
;
737 FakeRendererGL
renderer(&renderer_client
,
739 output_surface
.get(),
740 resource_provider
.get());
742 gfx::Rect
viewport_rect(1, 1);
743 RenderPass
* root_pass
=
744 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
745 viewport_rect
, gfx::Transform());
746 root_pass
->has_transparent_background
= false;
748 // On DEBUG builds, render passes with opaque background clear to blue to
749 // easily see regions that were not drawn on the screen.
750 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
751 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
754 EXPECT_CALL(*context
, clear(_
)).Times(0);
756 EXPECT_CALL(*context
, clear(_
)).Times(1);
758 renderer
.DrawFrame(&render_passes_in_draw_order_
,
763 Mock::VerifyAndClearExpectations(context
);
766 TEST_F(GLRendererTest
, TransparentBackground
) {
767 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
768 ClearCountingContext
* context
= context_owned
.get();
770 FakeOutputSurfaceClient output_surface_client
;
771 scoped_ptr
<OutputSurface
> output_surface(
772 FakeOutputSurface::Create3d(context_owned
.Pass()));
773 CHECK(output_surface
->BindToClient(&output_surface_client
));
775 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
776 new TestSharedBitmapManager());
777 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
778 output_surface
.get(), shared_bitmap_manager
.get());
780 RendererSettings settings
;
781 FakeRendererClient renderer_client
;
782 FakeRendererGL
renderer(&renderer_client
,
784 output_surface
.get(),
785 resource_provider
.get());
787 gfx::Rect
viewport_rect(1, 1);
788 RenderPass
* root_pass
=
789 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
790 viewport_rect
, gfx::Transform());
791 root_pass
->has_transparent_background
= true;
793 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
794 EXPECT_CALL(*context
, clear(_
)).Times(1);
795 renderer
.DrawFrame(&render_passes_in_draw_order_
,
801 Mock::VerifyAndClearExpectations(context
);
804 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
805 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
806 ClearCountingContext
* context
= context_owned
.get();
808 FakeOutputSurfaceClient output_surface_client
;
809 scoped_ptr
<OutputSurface
> output_surface(
810 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
811 CHECK(output_surface
->BindToClient(&output_surface_client
));
813 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
814 new TestSharedBitmapManager());
815 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
816 output_surface
.get(), shared_bitmap_manager
.get());
818 RendererSettings settings
;
819 FakeRendererClient renderer_client
;
820 FakeRendererGL
renderer(&renderer_client
,
822 output_surface
.get(),
823 resource_provider
.get());
825 gfx::Rect
viewport_rect(1, 1);
826 AddRenderPass(&render_passes_in_draw_order_
,
831 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
832 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
834 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
835 renderer
.DrawFrame(&render_passes_in_draw_order_
,
840 Mock::VerifyAndClearExpectations(context
);
843 class VisibilityChangeIsLastCallTrackingContext
844 : public TestWebGraphicsContext3D
{
846 VisibilityChangeIsLastCallTrackingContext()
847 : last_call_was_set_visibility_(false) {}
849 // TestWebGraphicsContext3D methods.
850 void flush() override
{ last_call_was_set_visibility_
= false; }
851 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
852 void deleteFramebuffer(GLuint
) override
{
853 last_call_was_set_visibility_
= false;
855 void deleteQueryEXT(GLuint
) override
{
856 last_call_was_set_visibility_
= false;
858 void deleteRenderbuffer(GLuint
) override
{
859 last_call_was_set_visibility_
= false;
862 // Methods added for test.
863 void set_last_call_was_visibility(bool visible
) {
864 DCHECK(last_call_was_set_visibility_
== false);
865 last_call_was_set_visibility_
= true;
867 bool last_call_was_set_visibility() const {
868 return last_call_was_set_visibility_
;
872 bool last_call_was_set_visibility_
;
875 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
876 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
877 new VisibilityChangeIsLastCallTrackingContext
);
878 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
880 scoped_refptr
<TestContextProvider
> provider
=
881 TestContextProvider::Create(context_owned
.Pass());
883 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
884 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
885 base::Unretained(context
)));
887 FakeOutputSurfaceClient output_surface_client
;
888 scoped_ptr
<OutputSurface
> output_surface(
889 FakeOutputSurface::Create3d(provider
));
890 CHECK(output_surface
->BindToClient(&output_surface_client
));
892 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
893 new TestSharedBitmapManager());
894 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
895 output_surface
.get(), shared_bitmap_manager
.get());
897 RendererSettings settings
;
898 FakeRendererClient renderer_client
;
899 FakeRendererGL
renderer(&renderer_client
,
901 output_surface
.get(),
902 resource_provider
.get());
904 gfx::Rect
viewport_rect(1, 1);
905 AddRenderPass(&render_passes_in_draw_order_
,
910 // Ensure that the call to SetSurfaceVisible is the last call issue to the
911 // GPU process, after glFlush is called, and after the RendererClient's
912 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
913 // RenderClient and the Context by giving them both a pointer to a variable on
915 renderer
.SetVisible(true);
916 renderer
.DrawFrame(&render_passes_in_draw_order_
,
921 renderer
.SetVisible(false);
922 EXPECT_TRUE(context
->last_call_was_set_visibility());
925 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
927 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
928 test_capabilities_
.gpu
.egl_image_external
= true;
931 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
932 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
933 MOCK_METHOD4(drawElements
,
934 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
936 virtual void activeTexture(GLenum texture
) {
937 EXPECT_NE(texture
, active_texture_
);
938 active_texture_
= texture
;
941 GLenum
active_texture() const { return active_texture_
; }
944 GLenum active_texture_
;
947 TEST_F(GLRendererTest
, ActiveTextureState
) {
948 scoped_ptr
<TextureStateTrackingContext
> context_owned(
949 new TextureStateTrackingContext
);
950 TextureStateTrackingContext
* context
= context_owned
.get();
952 FakeOutputSurfaceClient output_surface_client
;
953 scoped_ptr
<OutputSurface
> output_surface(
954 FakeOutputSurface::Create3d(context_owned
.Pass()));
955 CHECK(output_surface
->BindToClient(&output_surface_client
));
957 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
958 new TestSharedBitmapManager());
959 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
960 output_surface
.get(), shared_bitmap_manager
.get());
962 RendererSettings settings
;
963 FakeRendererClient renderer_client
;
964 FakeRendererGL
renderer(&renderer_client
,
966 output_surface
.get(),
967 resource_provider
.get());
969 // During initialization we are allowed to set any texture parameters.
970 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
972 RenderPass
* root_pass
=
973 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 1),
974 gfx::Rect(100, 100), gfx::Transform());
975 uint32_t mailbox_sync_point
;
976 AddOneOfEveryQuadType(root_pass
, resource_provider
.get(), RenderPassId(0, 0),
977 &mailbox_sync_point
);
979 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
981 // Set up expected texture filter state transitions that match the quads
982 // created in AppendOneOfEveryQuadType().
983 Mock::VerifyAndClearExpectations(context
);
987 // The sync points for all quads are waited on first. This sync point is
988 // for a texture quad drawn later in the frame.
989 EXPECT_CALL(*context
, waitSyncPoint(mailbox_sync_point
)).Times(1);
991 // yuv_quad is drawn with the default linear filter.
992 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
994 // tile_quad is drawn with GL_NEAREST because it is not transformed or
998 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
1001 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
1002 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1004 // transformed_tile_quad uses GL_LINEAR.
1005 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1007 // scaled_tile_quad also uses GL_LINEAR.
1008 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1010 // The remaining quads also use GL_LINEAR because nearest neighbor
1011 // filtering is currently only used with tile quads.
1012 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(6);
1015 gfx::Rect
viewport_rect(100, 100);
1016 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1021 Mock::VerifyAndClearExpectations(context
);
1024 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
1026 MOCK_METHOD1(clear
, void(GLbitfield mask
));
1027 MOCK_METHOD4(drawElements
,
1028 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1031 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
1032 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
1033 new NoClearRootRenderPassMockContext
);
1034 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
1036 FakeOutputSurfaceClient output_surface_client
;
1037 scoped_ptr
<OutputSurface
> output_surface(
1038 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
1039 CHECK(output_surface
->BindToClient(&output_surface_client
));
1041 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1042 new TestSharedBitmapManager());
1043 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1044 output_surface
.get(), shared_bitmap_manager
.get());
1046 RendererSettings settings
;
1047 settings
.should_clear_root_render_pass
= false;
1049 FakeRendererClient renderer_client
;
1050 FakeRendererGL
renderer(&renderer_client
,
1052 output_surface
.get(),
1053 resource_provider
.get());
1055 gfx::Rect
viewport_rect(10, 10);
1057 RenderPassId
child_pass_id(2, 0);
1058 RenderPass
* child_pass
=
1059 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, viewport_rect
,
1061 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
1063 RenderPassId
root_pass_id(1, 0);
1064 RenderPass
* root_pass
=
1065 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1067 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1070 AddRenderPassQuad(root_pass
, child_pass
);
1073 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
1075 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1078 // First render pass is not the root one, clearing should happen.
1079 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1081 Expectation first_render_pass
=
1082 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1084 // The second render pass is the root one, clearing should be prevented.
1085 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1088 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1091 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1092 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1098 // In multiple render passes all but the root pass should clear the
1100 Mock::VerifyAndClearExpectations(&mock_context
);
1103 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1105 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1107 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1109 void enable(GLenum cap
) override
{
1110 if (cap
== GL_SCISSOR_TEST
)
1111 scissor_enabled_
= true;
1114 void disable(GLenum cap
) override
{
1115 if (cap
== GL_SCISSOR_TEST
)
1116 scissor_enabled_
= false;
1120 bool scissor_enabled_
;
1123 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1124 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1125 new ScissorTestOnClearCheckingContext
);
1127 FakeOutputSurfaceClient output_surface_client
;
1128 scoped_ptr
<OutputSurface
> output_surface(
1129 FakeOutputSurface::Create3d(context_owned
.Pass()));
1130 CHECK(output_surface
->BindToClient(&output_surface_client
));
1132 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1133 new TestSharedBitmapManager());
1134 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1135 output_surface
.get(), shared_bitmap_manager
.get());
1137 RendererSettings settings
;
1138 FakeRendererClient renderer_client
;
1139 FakeRendererGL
renderer(&renderer_client
,
1141 output_surface
.get(),
1142 resource_provider
.get());
1143 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1145 gfx::Rect
viewport_rect(1, 1);
1147 gfx::Rect
grand_child_rect(25, 25);
1148 RenderPassId
grand_child_pass_id(3, 0);
1149 RenderPass
* grand_child_pass
=
1150 AddRenderPass(&render_passes_in_draw_order_
, grand_child_pass_id
,
1151 grand_child_rect
, gfx::Transform());
1152 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1154 gfx::Rect
child_rect(50, 50);
1155 RenderPassId
child_pass_id(2, 0);
1156 RenderPass
* child_pass
=
1157 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, child_rect
,
1159 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1161 RenderPassId
root_pass_id(1, 0);
1162 RenderPass
* root_pass
=
1163 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1165 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1167 AddRenderPassQuad(root_pass
, child_pass
);
1168 AddRenderPassQuad(child_pass
, grand_child_pass
);
1170 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1171 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1178 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1180 DiscardCheckingContext() : discarded_(0) {
1181 set_have_post_sub_buffer(true);
1182 set_have_discard_framebuffer(true);
1185 void discardFramebufferEXT(GLenum target
,
1186 GLsizei numAttachments
,
1187 const GLenum
* attachments
) override
{
1191 int discarded() const { return discarded_
; }
1192 void reset() { discarded_
= 0; }
1198 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1200 explicit NonReshapableOutputSurface(
1201 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1202 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1204 surface_size_
= gfx::Size(500, 500);
1206 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1207 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1210 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1211 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1212 DiscardCheckingContext
* context
= context_owned
.get();
1214 FakeOutputSurfaceClient output_surface_client
;
1215 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1216 new NonReshapableOutputSurface(context_owned
.Pass()));
1217 CHECK(output_surface
->BindToClient(&output_surface_client
));
1218 output_surface
->set_fixed_size(gfx::Size(100, 100));
1220 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1221 new TestSharedBitmapManager());
1222 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1223 output_surface
.get(), shared_bitmap_manager
.get());
1225 RendererSettings settings
;
1226 settings
.partial_swap_enabled
= true;
1227 FakeRendererClient renderer_client
;
1228 FakeRendererGL
renderer(&renderer_client
,
1230 output_surface
.get(),
1231 resource_provider
.get());
1232 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1234 gfx::Rect
viewport_rect(100, 100);
1235 gfx::Rect
clip_rect(100, 100);
1238 // Partial frame, should not discard.
1239 RenderPassId
root_pass_id(1, 0);
1240 RenderPass
* root_pass
=
1241 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1242 viewport_rect
, gfx::Transform());
1243 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1244 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1246 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1247 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1252 EXPECT_EQ(0, context
->discarded());
1256 // Full frame, should discard.
1257 RenderPassId
root_pass_id(1, 0);
1258 RenderPass
* root_pass
=
1259 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1260 viewport_rect
, gfx::Transform());
1261 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1262 root_pass
->damage_rect
= root_pass
->output_rect
;
1264 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1265 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1270 EXPECT_EQ(1, context
->discarded());
1274 // Full frame, external scissor is set, should not discard.
1275 output_surface
->set_has_external_stencil_test(true);
1276 RenderPassId
root_pass_id(1, 0);
1277 RenderPass
* root_pass
=
1278 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1279 viewport_rect
, gfx::Transform());
1280 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1281 root_pass
->damage_rect
= root_pass
->output_rect
;
1282 root_pass
->has_transparent_background
= false;
1284 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1285 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1290 EXPECT_EQ(0, context
->discarded());
1292 output_surface
->set_has_external_stencil_test(false);
1295 // Full frame, clipped, should not discard.
1296 clip_rect
= gfx::Rect(10, 10, 10, 10);
1297 RenderPassId
root_pass_id(1, 0);
1298 RenderPass
* root_pass
=
1299 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1300 viewport_rect
, gfx::Transform());
1301 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1302 root_pass
->damage_rect
= root_pass
->output_rect
;
1304 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1305 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1310 EXPECT_EQ(0, context
->discarded());
1314 // Full frame, doesn't cover the surface, should not discard.
1315 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1316 RenderPassId
root_pass_id(1, 0);
1317 RenderPass
* root_pass
=
1318 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1319 viewport_rect
, gfx::Transform());
1320 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1321 root_pass
->damage_rect
= root_pass
->output_rect
;
1323 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1324 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1329 EXPECT_EQ(0, context
->discarded());
1333 // Full frame, doesn't cover the surface (no offset), should not discard.
1334 clip_rect
= gfx::Rect(100, 100);
1335 viewport_rect
= gfx::Rect(50, 50);
1336 RenderPassId
root_pass_id(1, 0);
1337 RenderPass
* root_pass
=
1338 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1339 viewport_rect
, gfx::Transform());
1340 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1341 root_pass
->damage_rect
= root_pass
->output_rect
;
1343 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1344 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1349 EXPECT_EQ(0, context
->discarded());
1354 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1356 MOCK_METHOD4(viewport
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1357 MOCK_METHOD4(scissor
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1360 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1361 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1362 // and maintains a fixed size. This test verifies that glViewport and
1363 // glScissor's Y coordinate is flipped correctly in this environment, and that
1364 // the glViewport can be at a nonzero origin within the surface.
1365 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1366 new FlippedScissorAndViewportContext
);
1368 // We expect exactly one call to viewport on this context and exactly two
1369 // to scissor (one to scissor the clear, one to scissor the quad draw).
1370 EXPECT_CALL(*context_owned
, viewport(10, 390, 100, 100));
1371 EXPECT_CALL(*context_owned
, scissor(10, 390, 100, 100));
1372 EXPECT_CALL(*context_owned
, scissor(30, 450, 20, 20));
1374 FakeOutputSurfaceClient output_surface_client
;
1375 scoped_ptr
<OutputSurface
> output_surface(
1376 new NonReshapableOutputSurface(context_owned
.Pass()));
1377 CHECK(output_surface
->BindToClient(&output_surface_client
));
1379 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1380 new TestSharedBitmapManager());
1381 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1382 output_surface
.get(), shared_bitmap_manager
.get());
1384 RendererSettings settings
;
1385 FakeRendererClient renderer_client
;
1386 FakeRendererGL
renderer(&renderer_client
,
1388 output_surface
.get(),
1389 resource_provider
.get());
1390 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1392 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1393 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1394 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1396 RenderPassId
root_pass_id(1, 0);
1397 RenderPass
* root_pass
=
1398 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1400 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1402 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1403 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1405 device_viewport_rect
,
1406 device_viewport_rect
,
1410 TEST_F(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1411 // When using render-to-FBO to display the surface, all rendering is done
1412 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1413 // the correct framebuffer during rendering, if changed.
1414 // Note: there is one path that will set it to 0, but that is after the render
1416 FakeOutputSurfaceClient output_surface_client
;
1417 scoped_ptr
<FakeOutputSurface
> output_surface(
1418 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1419 CHECK(output_surface
->BindToClient(&output_surface_client
));
1421 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1422 new TestSharedBitmapManager());
1423 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1424 output_surface
.get(), shared_bitmap_manager
.get());
1426 RendererSettings settings
;
1427 FakeRendererClient renderer_client
;
1428 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1429 resource_provider
.get());
1430 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1432 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1433 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1434 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1436 RenderPassId
root_pass_id(1, 0);
1437 RenderPass
* root_pass
=
1438 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1440 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1443 gpu::gles2::GLES2Interface
* gl
=
1444 output_surface
->context_provider()->ContextGL();
1445 gl
->GenFramebuffers(1, &fbo
);
1446 output_surface
->set_framebuffer(fbo
);
1448 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1449 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1450 device_viewport_rect
, false);
1453 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1454 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1457 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1458 gfx::Rect
viewport_rect(1, 1);
1460 gfx::Rect
child_rect(50, 50);
1461 RenderPassId
child_pass_id(2, 0);
1462 RenderPass
* child_pass
;
1464 RenderPassId
root_pass_id(1, 0);
1465 RenderPass
* root_pass
;
1467 ResourceId mask
= resource_provider_
->CreateResource(
1468 gfx::Size(20, 12), GL_CLAMP_TO_EDGE
,
1469 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1470 resource_provider_
->best_texture_format());
1471 resource_provider_
->AllocateForTesting(mask
);
1473 SkScalar matrix
[20];
1474 float amount
= 0.5f
;
1475 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1476 matrix
[1] = 0.715f
- 0.715f
* amount
;
1477 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1478 matrix
[3] = matrix
[4] = 0;
1479 matrix
[5] = 0.213f
- 0.213f
* amount
;
1480 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1481 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1482 matrix
[8] = matrix
[9] = 0;
1483 matrix
[10] = 0.213f
- 0.213f
* amount
;
1484 matrix
[11] = 0.715f
- 0.715f
* amount
;
1485 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1486 matrix
[13] = matrix
[14] = 0;
1487 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1489 skia::RefPtr
<SkColorFilter
> color_filter(
1490 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1491 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1492 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1493 FilterOperations filters
;
1494 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1496 gfx::Transform transform_causing_aa
;
1497 transform_causing_aa
.Rotate(20.0);
1499 for (int i
= 0; i
<= LAST_BLEND_MODE
; ++i
) {
1500 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1501 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1502 settings_
.force_blending_with_shaders
= (blend_mode
!= BLEND_MODE_NONE
);
1503 // RenderPassProgram
1504 render_passes_in_draw_order_
.clear();
1505 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1510 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1515 AddRenderPassQuad(root_pass
,
1522 renderer_
->DecideRenderPassAllocationsForFrame(
1523 render_passes_in_draw_order_
);
1524 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1529 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1531 // RenderPassColorMatrixProgram
1532 render_passes_in_draw_order_
.clear();
1534 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1537 transform_causing_aa
);
1539 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1545 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1547 renderer_
->DecideRenderPassAllocationsForFrame(
1548 render_passes_in_draw_order_
);
1549 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1554 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1556 // RenderPassMaskProgram
1557 render_passes_in_draw_order_
.clear();
1559 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1564 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1569 AddRenderPassQuad(root_pass
,
1576 renderer_
->DecideRenderPassAllocationsForFrame(
1577 render_passes_in_draw_order_
);
1578 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1583 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1586 // RenderPassMaskColorMatrixProgram
1587 render_passes_in_draw_order_
.clear();
1589 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1594 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1600 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1602 renderer_
->DecideRenderPassAllocationsForFrame(
1603 render_passes_in_draw_order_
);
1604 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1609 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
,
1610 SAMPLER_TYPE_2D
, blend_mode
);
1612 // RenderPassProgramAA
1613 render_passes_in_draw_order_
.clear();
1615 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1618 transform_causing_aa
);
1620 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1625 AddRenderPassQuad(root_pass
,
1629 transform_causing_aa
,
1632 renderer_
->DecideRenderPassAllocationsForFrame(
1633 render_passes_in_draw_order_
);
1634 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1639 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1641 // RenderPassColorMatrixProgramAA
1642 render_passes_in_draw_order_
.clear();
1644 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1647 transform_causing_aa
);
1649 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1655 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1657 renderer_
->DecideRenderPassAllocationsForFrame(
1658 render_passes_in_draw_order_
);
1659 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1664 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1666 // RenderPassMaskProgramAA
1667 render_passes_in_draw_order_
.clear();
1669 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1672 transform_causing_aa
);
1674 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1679 AddRenderPassQuad(root_pass
,
1683 transform_causing_aa
,
1686 renderer_
->DecideRenderPassAllocationsForFrame(
1687 render_passes_in_draw_order_
);
1688 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1693 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1696 // RenderPassMaskColorMatrixProgramAA
1697 render_passes_in_draw_order_
.clear();
1699 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1702 transform_causing_aa
);
1704 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1707 transform_causing_aa
);
1710 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1712 renderer_
->DecideRenderPassAllocationsForFrame(
1713 render_passes_in_draw_order_
);
1714 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1719 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
,
1720 SAMPLER_TYPE_2D
, blend_mode
);
1724 // At this time, the AA code path cannot be taken if the surface's rect would
1725 // project incorrectly by the given transform, because of w<0 clipping.
1726 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1727 gfx::Rect
child_rect(50, 50);
1728 RenderPassId
child_pass_id(2, 0);
1729 RenderPass
* child_pass
;
1731 gfx::Rect
viewport_rect(1, 1);
1732 RenderPassId
root_pass_id(1, 0);
1733 RenderPass
* root_pass
;
1735 gfx::Transform transform_preventing_aa
;
1736 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1737 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1738 transform_preventing_aa
.Scale(30.0, 1.0);
1740 // Verify that the test transform and test rect actually do cause the clipped
1741 // flag to trigger. Otherwise we are not testing the intended scenario.
1742 bool clipped
= false;
1743 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1744 ASSERT_TRUE(clipped
);
1746 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1749 transform_preventing_aa
);
1751 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1756 AddRenderPassQuad(root_pass
,
1760 transform_preventing_aa
,
1761 SkXfermode::kSrcOver_Mode
);
1763 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1764 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1770 // If use_aa incorrectly ignores clipping, it will use the
1771 // RenderPassProgramAA shader instead of the RenderPassProgram.
1772 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, BLEND_MODE_NONE
);
1775 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1776 gfx::Rect
viewport_rect(1, 1);
1777 RenderPassId
root_pass_id(1, 0);
1778 RenderPass
* root_pass
;
1780 gfx::Transform pixel_aligned_transform_causing_aa
;
1781 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1782 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1784 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1788 AddTransformedQuad(root_pass
,
1791 pixel_aligned_transform_causing_aa
);
1793 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1794 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1800 TestSolidColorProgramAA();
1803 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1805 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1807 // Specifically override methods even if they are unused (used in conjunction
1808 // with StrictMock). We need to make sure that GLRenderer does not issue
1809 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1810 // through the OutputSurface abstraction.
1811 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1812 MOCK_METHOD3(reshapeWithScaleFactor
,
1813 void(int width
, int height
, float scale_factor
));
1814 MOCK_METHOD4(drawElements
,
1815 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1818 class MockOutputSurface
: public OutputSurface
{
1822 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1823 new StrictMock
<OutputSurfaceMockContext
>))) {
1824 surface_size_
= gfx::Size(100, 100);
1826 virtual ~MockOutputSurface() {}
1828 MOCK_METHOD0(EnsureBackbuffer
, void());
1829 MOCK_METHOD0(DiscardBackbuffer
, void());
1830 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1831 MOCK_METHOD0(BindFramebuffer
, void());
1832 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1835 class MockOutputSurfaceTest
: public GLRendererTest
{
1837 virtual void SetUp() {
1838 FakeOutputSurfaceClient output_surface_client_
;
1839 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1841 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1842 resource_provider_
= FakeResourceProvider::Create(
1843 &output_surface_
, shared_bitmap_manager_
.get());
1845 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1848 resource_provider_
.get()));
1851 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1853 void DrawFrame(float device_scale_factor
,
1854 const gfx::Rect
& device_viewport_rect
) {
1855 RenderPassId
render_pass_id(1, 0);
1856 RenderPass
* render_pass
=
1857 AddRenderPass(&render_passes_in_draw_order_
, render_pass_id
,
1858 device_viewport_rect
, gfx::Transform());
1859 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1861 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1863 EXPECT_CALL(output_surface_
,
1864 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1867 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1869 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1871 renderer_
->DecideRenderPassAllocationsForFrame(
1872 render_passes_in_draw_order_
);
1873 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1874 device_scale_factor
,
1875 device_viewport_rect
,
1876 device_viewport_rect
,
1880 OutputSurfaceMockContext
* Context() {
1881 return static_cast<OutputSurfaceMockContext
*>(
1882 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1886 RendererSettings settings_
;
1887 FakeOutputSurfaceClient output_surface_client_
;
1888 StrictMock
<MockOutputSurface
> output_surface_
;
1889 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1890 scoped_ptr
<ResourceProvider
> resource_provider_
;
1891 FakeRendererClient renderer_client_
;
1892 scoped_ptr
<FakeRendererGL
> renderer_
;
1895 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1896 gfx::Rect
device_viewport_rect(1, 1);
1897 DrawFrame(1.f
, device_viewport_rect
);
1899 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1900 renderer_
->SwapBuffers(CompositorFrameMetadata());
1903 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1904 gfx::Rect
device_viewport_rect(1, 1);
1906 DrawFrame(1.f
, device_viewport_rect
);
1907 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1908 renderer_
->SwapBuffers(CompositorFrameMetadata());
1910 device_viewport_rect
= gfx::Rect(2, 2);
1912 DrawFrame(2.f
, device_viewport_rect
);
1913 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1914 renderer_
->SwapBuffers(CompositorFrameMetadata());
1916 DrawFrame(2.f
, device_viewport_rect
);
1917 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1918 renderer_
->SwapBuffers(CompositorFrameMetadata());
1920 device_viewport_rect
= gfx::Rect(1, 1);
1922 DrawFrame(1.f
, device_viewport_rect
);
1923 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1924 renderer_
->SwapBuffers(CompositorFrameMetadata());
1927 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1929 static void SyncPointCallback(int* callback_count
) {
1930 ++(*callback_count
);
1931 base::MessageLoop::current()->QuitWhenIdle();
1934 static void OtherCallback(int* callback_count
) {
1935 ++(*callback_count
);
1936 base::MessageLoop::current()->QuitWhenIdle();
1940 #if !defined(OS_ANDROID)
1941 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1942 int sync_point_callback_count
= 0;
1943 int other_callback_count
= 0;
1944 gpu::gles2::GLES2Interface
* gl
=
1945 output_surface_
->context_provider()->ContextGL();
1946 gpu::ContextSupport
* context_support
=
1947 output_surface_
->context_provider()->ContextSupport();
1949 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1951 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1952 GL_INNOCENT_CONTEXT_RESET_ARB
);
1954 context_support
->SignalSyncPoint(
1955 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1956 EXPECT_EQ(0, sync_point_callback_count
);
1957 EXPECT_EQ(0, other_callback_count
);
1959 // Make the sync point happen.
1961 // Post a task after the sync point.
1962 base::ThreadTaskRunnerHandle::Get()->PostTask(
1963 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1965 base::MessageLoop::current()->Run();
1967 // The sync point shouldn't have happened since the context was lost.
1968 EXPECT_EQ(0, sync_point_callback_count
);
1969 EXPECT_EQ(1, other_callback_count
);
1972 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1973 int sync_point_callback_count
= 0;
1974 int other_callback_count
= 0;
1976 gpu::gles2::GLES2Interface
* gl
=
1977 output_surface_
->context_provider()->ContextGL();
1978 gpu::ContextSupport
* context_support
=
1979 output_surface_
->context_provider()->ContextSupport();
1981 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1983 context_support
->SignalSyncPoint(
1984 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1985 EXPECT_EQ(0, sync_point_callback_count
);
1986 EXPECT_EQ(0, other_callback_count
);
1988 // Make the sync point happen.
1990 // Post a task after the sync point.
1991 base::ThreadTaskRunnerHandle::Get()->PostTask(
1992 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1994 base::MessageLoop::current()->Run();
1996 // The sync point should have happened.
1997 EXPECT_EQ(1, sync_point_callback_count
);
1998 EXPECT_EQ(1, other_callback_count
);
2000 #endif // OS_ANDROID
2002 class TestOverlayProcessor
: public OverlayProcessor
{
2004 class Strategy
: public OverlayProcessor::Strategy
{
2007 ~Strategy() override
{}
2008 MOCK_METHOD2(Attempt
,
2009 bool(RenderPassList
* render_passes_in_draw_order
,
2010 OverlayCandidateList
* candidates
));
2013 explicit TestOverlayProcessor(OutputSurface
* surface
)
2014 : OverlayProcessor(surface
) {}
2015 ~TestOverlayProcessor() override
{}
2016 void Initialize() override
{
2017 strategy_
= new Strategy();
2018 strategies_
.push_back(scoped_ptr
<OverlayProcessor::Strategy
>(strategy_
));
2021 Strategy
* strategy_
;
2024 void MailboxReleased(unsigned sync_point
,
2026 BlockingTaskRunner
* main_thread_task_runner
) {
2029 void IgnoreCopyResult(scoped_ptr
<CopyOutputResult
> result
) {
2032 TEST_F(GLRendererTest
, DontOverlayWithCopyRequests
) {
2033 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
2034 FakeOutputSurfaceClient output_surface_client
;
2035 scoped_ptr
<OutputSurface
> output_surface(
2036 FakeOutputSurface::Create3d(context_owned
.Pass()));
2037 CHECK(output_surface
->BindToClient(&output_surface_client
));
2039 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2040 new TestSharedBitmapManager());
2041 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2042 output_surface
.get(), shared_bitmap_manager
.get());
2043 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2044 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2046 RendererSettings settings
;
2047 FakeRendererClient renderer_client
;
2048 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2049 resource_provider
.get(), mailbox_deleter
.get());
2051 TestOverlayProcessor
* processor
=
2052 new TestOverlayProcessor(output_surface
.get());
2053 processor
->Initialize();
2054 renderer
.SetOverlayProcessor(processor
);
2056 gfx::Rect
viewport_rect(1, 1);
2057 RenderPass
* root_pass
=
2058 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2059 viewport_rect
, gfx::Transform());
2060 root_pass
->has_transparent_background
= false;
2061 root_pass
->copy_requests
.push_back(
2062 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult
)));
2064 unsigned sync_point
= 0;
2065 TextureMailbox mailbox
=
2066 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2067 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2068 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2069 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2070 mailbox
, release_callback
.Pass());
2071 bool premultiplied_alpha
= false;
2072 bool flipped
= false;
2073 bool nearest_neighbor
= false;
2074 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2076 TextureDrawQuad
* overlay_quad
=
2077 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2078 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2079 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2080 premultiplied_alpha
, gfx::PointF(0, 0),
2081 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2082 flipped
, nearest_neighbor
);
2083 overlay_quad
->set_allow_overlay(true);
2085 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2086 // Attempt will be called for each strategy in OverlayProcessor. We have
2087 // added a fake strategy, so checking for Attempt calls checks if there was
2088 // any attempt to overlay, which there shouldn't be. We can't use the quad
2089 // list because the render pass is cleaned up by DrawFrame.
2090 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(0);
2091 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2092 viewport_rect
, false);
2093 Mock::VerifyAndClearExpectations(processor
->strategy_
);
2095 // Without a copy request Attempt() should be called once.
2096 root_pass
= AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2097 viewport_rect
, gfx::Transform());
2098 root_pass
->has_transparent_background
= false;
2100 overlay_quad
= root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2101 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2102 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2103 premultiplied_alpha
, gfx::PointF(0, 0),
2104 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2105 flipped
, nearest_neighbor
);
2107 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(1);
2108 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2109 viewport_rect
, false);
2112 class SingleOverlayOnTopProcessor
: public OverlayProcessor
{
2114 class SingleOverlayValidator
: public OverlayCandidateValidator
{
2116 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
2117 ASSERT_EQ(2U, surfaces
->size());
2118 OverlayCandidate
& candidate
= surfaces
->back();
2119 candidate
.overlay_handled
= true;
2123 explicit SingleOverlayOnTopProcessor(OutputSurface
* surface
)
2124 : OverlayProcessor(surface
) {}
2126 void Initialize() override
{
2127 strategies_
.push_back(
2128 scoped_ptr
<Strategy
>(new OverlayStrategySingleOnTop(&validator_
)));
2131 SingleOverlayValidator validator_
;
2134 class WaitSyncPointCountingContext
: public TestWebGraphicsContext3D
{
2136 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
2139 class MockOverlayScheduler
{
2141 MOCK_METHOD5(Schedule
,
2142 void(int plane_z_order
,
2143 gfx::OverlayTransform plane_transform
,
2144 unsigned overlay_texture_id
,
2145 const gfx::Rect
& display_bounds
,
2146 const gfx::RectF
& uv_rect
));
2149 TEST_F(GLRendererTest
, OverlaySyncPointsAreProcessed
) {
2150 scoped_ptr
<WaitSyncPointCountingContext
> context_owned(
2151 new WaitSyncPointCountingContext
);
2152 WaitSyncPointCountingContext
* context
= context_owned
.get();
2154 MockOverlayScheduler overlay_scheduler
;
2155 scoped_refptr
<TestContextProvider
> context_provider
=
2156 TestContextProvider::Create(context_owned
.Pass());
2157 context_provider
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2158 &MockOverlayScheduler::Schedule
, base::Unretained(&overlay_scheduler
)));
2160 FakeOutputSurfaceClient output_surface_client
;
2161 scoped_ptr
<OutputSurface
> output_surface(
2162 FakeOutputSurface::Create3d(context_provider
));
2163 CHECK(output_surface
->BindToClient(&output_surface_client
));
2165 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2166 new TestSharedBitmapManager());
2167 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2168 output_surface
.get(), shared_bitmap_manager
.get());
2169 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2170 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2172 RendererSettings settings
;
2173 FakeRendererClient renderer_client
;
2174 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2175 resource_provider
.get(), mailbox_deleter
.get());
2177 SingleOverlayOnTopProcessor
* processor
=
2178 new SingleOverlayOnTopProcessor(output_surface
.get());
2179 processor
->Initialize();
2180 renderer
.SetOverlayProcessor(processor
);
2182 gfx::Rect
viewport_rect(1, 1);
2183 RenderPass
* root_pass
=
2184 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2185 viewport_rect
, gfx::Transform());
2186 root_pass
->has_transparent_background
= false;
2188 unsigned sync_point
= 29;
2189 TextureMailbox mailbox
=
2190 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2191 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2192 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2193 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2194 mailbox
, release_callback
.Pass());
2195 bool premultiplied_alpha
= false;
2196 bool flipped
= false;
2197 bool nearest_neighbor
= false;
2198 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2199 gfx::PointF
uv_top_left(0, 0);
2200 gfx::PointF
uv_bottom_right(1, 1);
2202 TextureDrawQuad
* overlay_quad
=
2203 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2204 SharedQuadState
* shared_state
= root_pass
->CreateAndAppendSharedQuadState();
2205 shared_state
->SetAll(gfx::Transform(), viewport_rect
.size(), viewport_rect
,
2206 viewport_rect
, false, 1, SkXfermode::kSrcOver_Mode
, 0);
2207 overlay_quad
->SetNew(shared_state
, viewport_rect
, viewport_rect
,
2208 viewport_rect
, resource_id
, premultiplied_alpha
,
2209 uv_top_left
, uv_bottom_right
, SK_ColorTRANSPARENT
,
2210 vertex_opacity
, flipped
, nearest_neighbor
);
2211 overlay_quad
->set_allow_overlay(true);
2213 // Verify that overlay_quad actually gets turned into an overlay, and even
2214 // though it's not drawn, that its sync point is waited on.
2215 EXPECT_CALL(*context
, waitSyncPoint(sync_point
)).Times(1);
2216 EXPECT_CALL(overlay_scheduler
,
2217 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE
, _
, viewport_rect
,
2218 BoundingRect(uv_top_left
, uv_bottom_right
))).Times(1);
2220 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2221 viewport_rect
, false);