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/overlay_strategy_underlay.h"
18 #include "cc/output/texture_mailbox_deleter.h"
19 #include "cc/quads/texture_draw_quad.h"
20 #include "cc/resources/resource_provider.h"
21 #include "cc/test/fake_impl_proxy.h"
22 #include "cc/test/fake_layer_tree_host_impl.h"
23 #include "cc/test/fake_output_surface.h"
24 #include "cc/test/fake_output_surface_client.h"
25 #include "cc/test/fake_renderer_client.h"
26 #include "cc/test/fake_resource_provider.h"
27 #include "cc/test/pixel_test.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()->GetDebugBorderProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
122 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
125 void TestShadersWithPrecision(TexCoordPrecision precision
) {
126 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
127 if (renderer()->Capabilities().using_egl_image
)
128 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
130 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
133 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision
,
134 BlendMode blend_mode
) {
135 EXPECT_PROGRAM_VALID(
136 renderer()->GetRenderPassProgram(precision
, blend_mode
));
137 EXPECT_PROGRAM_VALID(
138 renderer()->GetRenderPassProgramAA(precision
, blend_mode
));
141 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision
,
142 SamplerType sampler
) {
143 if (!renderer()->Capabilities().using_egl_image
&&
144 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
145 // This will likely be hit in tests due to usage of osmesa.
149 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
, sampler
));
150 EXPECT_PROGRAM_VALID(
151 renderer()->GetNonPremultipliedTextureProgram(precision
, sampler
));
152 EXPECT_PROGRAM_VALID(
153 renderer()->GetTextureBackgroundProgram(precision
, sampler
));
154 EXPECT_PROGRAM_VALID(
155 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
,
158 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
160 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
161 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
162 EXPECT_PROGRAM_VALID(
163 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
164 EXPECT_PROGRAM_VALID(
165 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
166 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
, sampler
));
167 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
, sampler
));
170 void TestShadersWithMasks(TexCoordPrecision precision
,
172 BlendMode blend_mode
,
173 bool mask_for_background
) {
174 if (!renderer()->Capabilities().using_egl_image
&&
175 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
176 // This will likely be hit in tests due to usage of osmesa.
180 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
181 precision
, sampler
, blend_mode
, mask_for_background
));
182 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
183 precision
, sampler
, blend_mode
, mask_for_background
));
184 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
185 precision
, sampler
, blend_mode
, mask_for_background
));
186 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
187 precision
, sampler
, blend_mode
, mask_for_background
));
193 #if !defined(OS_ANDROID) && !defined(OS_WIN)
194 static const TexCoordPrecision kPrecisionList
[] = {TEX_COORD_PRECISION_MEDIUM
,
195 TEX_COORD_PRECISION_HIGH
};
197 static const BlendMode kBlendModeList
[LAST_BLEND_MODE
+ 1] = {
204 BLEND_MODE_COLOR_DODGE
,
205 BLEND_MODE_COLOR_BURN
,
206 BLEND_MODE_HARD_LIGHT
,
207 BLEND_MODE_SOFT_LIGHT
,
208 BLEND_MODE_DIFFERENCE
,
209 BLEND_MODE_EXCLUSION
,
212 BLEND_MODE_SATURATION
,
214 BLEND_MODE_LUMINOSITY
,
217 static const SamplerType kSamplerList
[] = {
219 SAMPLER_TYPE_2D_RECT
,
220 SAMPLER_TYPE_EXTERNAL_OES
,
223 TEST_F(GLRendererShaderPixelTest
, BasicShadersCompile
) {
227 class PrecisionShaderPixelTest
228 : public GLRendererShaderPixelTest
,
229 public ::testing::WithParamInterface
<TexCoordPrecision
> {};
231 TEST_P(PrecisionShaderPixelTest
, ShadersCompile
) {
232 TestShadersWithPrecision(GetParam());
235 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile
,
236 PrecisionShaderPixelTest
,
237 ::testing::ValuesIn(kPrecisionList
));
239 class PrecisionBlendShaderPixelTest
240 : public GLRendererShaderPixelTest
,
241 public ::testing::WithParamInterface
<
242 std::tr1::tuple
<TexCoordPrecision
, BlendMode
>> {};
244 TEST_P(PrecisionBlendShaderPixelTest
, ShadersCompile
) {
245 TestShadersWithPrecisionAndBlend(std::tr1::get
<0>(GetParam()),
246 std::tr1::get
<1>(GetParam()));
249 INSTANTIATE_TEST_CASE_P(
250 PrecisionBlendShadersCompile
,
251 PrecisionBlendShaderPixelTest
,
252 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
253 ::testing::ValuesIn(kBlendModeList
)));
255 class PrecisionSamplerShaderPixelTest
256 : public GLRendererShaderPixelTest
,
257 public ::testing::WithParamInterface
<
258 std::tr1::tuple
<TexCoordPrecision
, SamplerType
>> {};
260 TEST_P(PrecisionSamplerShaderPixelTest
, ShadersCompile
) {
261 TestShadersWithPrecisionAndSampler(std::tr1::get
<0>(GetParam()),
262 std::tr1::get
<1>(GetParam()));
265 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile
,
266 PrecisionSamplerShaderPixelTest
,
267 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
268 ::testing::ValuesIn(kSamplerList
)));
270 class MaskShaderPixelTest
271 : public GLRendererShaderPixelTest
,
272 public ::testing::WithParamInterface
<
273 std::tr1::tuple
<TexCoordPrecision
, SamplerType
, BlendMode
, bool>> {};
275 TEST_P(MaskShaderPixelTest
, ShadersCompile
) {
276 TestShadersWithMasks(
277 std::tr1::get
<0>(GetParam()), std::tr1::get
<1>(GetParam()),
278 std::tr1::get
<2>(GetParam()), std::tr1::get
<3>(GetParam()));
281 INSTANTIATE_TEST_CASE_P(MaskShadersCompile
,
283 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
284 ::testing::ValuesIn(kSamplerList
),
285 ::testing::ValuesIn(kBlendModeList
),
290 class FakeRendererGL
: public GLRenderer
{
292 FakeRendererGL(RendererClient
* client
,
293 const RendererSettings
* settings
,
294 OutputSurface
* output_surface
,
295 ResourceProvider
* resource_provider
)
303 FakeRendererGL(RendererClient
* client
,
304 const RendererSettings
* settings
,
305 OutputSurface
* output_surface
,
306 ResourceProvider
* resource_provider
,
307 TextureMailboxDeleter
* texture_mailbox_deleter
)
312 texture_mailbox_deleter
,
315 void SetOverlayProcessor(OverlayProcessor
* processor
) {
316 overlay_processor_
.reset(processor
);
319 // GLRenderer methods.
321 // Changing visibility to public.
322 using GLRenderer::IsBackbufferDiscarded
;
323 using GLRenderer::DoDrawQuad
;
324 using GLRenderer::BeginDrawingFrame
;
325 using GLRenderer::FinishDrawingQuadList
;
326 using GLRenderer::stencil_enabled
;
329 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
331 GLRendererWithDefaultHarnessTest() {
333 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
334 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
336 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
337 resource_provider_
= FakeResourceProvider::Create(
338 output_surface_
.get(), shared_bitmap_manager_
.get());
339 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
341 output_surface_
.get(),
342 resource_provider_
.get()));
345 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
347 RendererSettings settings_
;
348 FakeOutputSurfaceClient output_surface_client_
;
349 scoped_ptr
<FakeOutputSurface
> output_surface_
;
350 FakeRendererClient renderer_client_
;
351 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
352 scoped_ptr
<ResourceProvider
> resource_provider_
;
353 scoped_ptr
<FakeRendererGL
> renderer_
;
356 // Closing the namespace here so that GLRendererShaderTest can take advantage
357 // of the friend relationship with GLRenderer and all of the mock classes
358 // declared above it.
361 class GLRendererShaderTest
: public GLRendererTest
{
363 GLRendererShaderTest() {
364 output_surface_
= FakeOutputSurface::Create3d().Pass();
365 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
367 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
368 resource_provider_
= FakeResourceProvider::Create(
369 output_surface_
.get(), shared_bitmap_manager_
.get());
370 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
372 output_surface_
.get(),
373 resource_provider_
.get()));
376 void TestRenderPassProgram(TexCoordPrecision precision
,
377 BlendMode blend_mode
) {
378 EXPECT_PROGRAM_VALID(
379 &renderer_
->render_pass_program_
[precision
][blend_mode
]);
380 EXPECT_EQ(renderer_
->render_pass_program_
[precision
][blend_mode
].program(),
381 renderer_
->program_shadow_
);
384 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
,
385 BlendMode blend_mode
) {
386 EXPECT_PROGRAM_VALID(
387 &renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]);
389 renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]
391 renderer_
->program_shadow_
);
394 void TestRenderPassMaskProgram(TexCoordPrecision precision
,
396 BlendMode blend_mode
) {
397 EXPECT_PROGRAM_VALID(
398 &renderer_
->render_pass_mask_program_
[precision
]
403 renderer_
->render_pass_mask_program_
[precision
]
407 renderer_
->program_shadow_
);
410 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
,
412 BlendMode blend_mode
) {
413 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_
414 [precision
][sampler
][blend_mode
][NO_MASK
]);
415 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_
416 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
417 renderer_
->program_shadow_
);
420 void TestRenderPassProgramAA(TexCoordPrecision precision
,
421 BlendMode blend_mode
) {
422 EXPECT_PROGRAM_VALID(
423 &renderer_
->render_pass_program_aa_
[precision
][blend_mode
]);
425 renderer_
->render_pass_program_aa_
[precision
][blend_mode
].program(),
426 renderer_
->program_shadow_
);
429 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
,
430 BlendMode blend_mode
) {
431 EXPECT_PROGRAM_VALID(
433 ->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]);
435 renderer_
->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]
437 renderer_
->program_shadow_
);
440 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
,
442 BlendMode blend_mode
) {
443 EXPECT_PROGRAM_VALID(
445 ->render_pass_mask_program_aa_
446 [precision
][sampler
][blend_mode
][NO_MASK
]);
448 renderer_
->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]
450 renderer_
->program_shadow_
);
453 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
,
455 BlendMode blend_mode
) {
456 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_aa_
457 [precision
][sampler
][blend_mode
][NO_MASK
]);
458 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
459 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
460 renderer_
->program_shadow_
);
463 void TestSolidColorProgramAA() {
464 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
465 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
466 renderer_
->program_shadow_
);
469 RendererSettings settings_
;
470 FakeOutputSurfaceClient output_surface_client_
;
471 scoped_ptr
<FakeOutputSurface
> output_surface_
;
472 FakeRendererClient renderer_client_
;
473 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
474 scoped_ptr
<ResourceProvider
> resource_provider_
;
475 scoped_ptr
<FakeRendererGL
> renderer_
;
480 // Test GLRenderer DiscardBackbuffer functionality:
481 // Suggest discarding framebuffer when one exists and the renderer is not
483 // Expected: it is discarded and damage tracker is reset.
485 GLRendererWithDefaultHarnessTest
,
486 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
487 renderer_
->SetVisible(false);
488 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
489 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
492 // Test GLRenderer DiscardBackbuffer functionality:
493 // Suggest discarding framebuffer when one exists and the renderer is visible.
494 // Expected: the allocation is ignored.
495 TEST_F(GLRendererWithDefaultHarnessTest
,
496 SuggestBackbufferNoDoNothingWhenVisible
) {
497 renderer_
->SetVisible(true);
498 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
499 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
502 // Test GLRenderer DiscardBackbuffer functionality:
503 // Suggest discarding framebuffer when one does not exist.
504 // Expected: it does nothing.
505 TEST_F(GLRendererWithDefaultHarnessTest
,
506 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
507 renderer_
->SetVisible(false);
508 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
509 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
511 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
512 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
515 // Test GLRenderer DiscardBackbuffer functionality:
516 // Begin drawing a frame while a framebuffer is discarded.
517 // Expected: will recreate framebuffer.
518 TEST_F(GLRendererWithDefaultHarnessTest
,
519 DiscardedBackbufferIsRecreatedForScopeDuration
) {
520 gfx::Rect
viewport_rect(1, 1);
521 renderer_
->SetVisible(false);
522 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
523 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
525 AddRenderPass(&render_passes_in_draw_order_
,
530 renderer_
->SetVisible(true);
531 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
536 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
539 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
542 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
543 gfx::Rect
viewport_rect(1, 1);
544 EXPECT_FALSE(renderer_
->stencil_enabled());
546 output_surface_
->set_has_external_stencil_test(true);
548 RenderPass
* root_pass
=
549 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
550 viewport_rect
, gfx::Transform());
551 root_pass
->has_transparent_background
= false;
553 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
558 EXPECT_TRUE(renderer_
->stencil_enabled());
561 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
563 ForbidSynchronousCallContext() {}
565 void getAttachedShaders(GLuint program
,
568 GLuint
* shaders
) override
{
571 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
575 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
576 void getBufferParameteriv(GLenum target
,
578 GLint
* value
) override
{
581 GLenum
getError() override
{
585 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
586 void getFramebufferAttachmentParameteriv(GLenum target
,
589 GLint
* value
) override
{
592 void getIntegerv(GLenum pname
, GLint
* value
) override
{
593 if (pname
== GL_MAX_TEXTURE_SIZE
) {
594 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
601 // We allow querying the shader compilation and program link status in debug
602 // mode, but not release.
603 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
611 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
619 void getRenderbufferParameteriv(GLenum target
,
621 GLint
* value
) override
{
625 void getShaderPrecisionFormat(GLenum shadertype
,
626 GLenum precisiontype
,
628 GLint
* precision
) override
{
631 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
634 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
637 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
640 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
643 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
647 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
650 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
653 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
658 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
659 FakeOutputSurfaceClient output_surface_client
;
660 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
661 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
662 CHECK(output_surface
->BindToClient(&output_surface_client
));
664 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
665 new TestSharedBitmapManager());
666 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
667 output_surface
.get(), shared_bitmap_manager
.get());
669 RendererSettings settings
;
670 FakeRendererClient renderer_client
;
671 FakeRendererGL
renderer(&renderer_client
,
673 output_surface
.get(),
674 resource_provider
.get());
677 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
679 LoseContextOnFirstGetContext() {}
681 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
682 context_lost_
= true;
686 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
687 context_lost_
= true;
692 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
693 FakeOutputSurfaceClient output_surface_client
;
694 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
695 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
696 CHECK(output_surface
->BindToClient(&output_surface_client
));
698 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
699 new TestSharedBitmapManager());
700 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
701 output_surface
.get(), shared_bitmap_manager
.get());
703 RendererSettings settings
;
704 FakeRendererClient renderer_client
;
705 FakeRendererGL
renderer(&renderer_client
,
707 output_surface
.get(),
708 resource_provider
.get());
711 class ClearCountingContext
: public TestWebGraphicsContext3D
{
713 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
715 MOCK_METHOD3(discardFramebufferEXT
,
717 GLsizei numAttachments
,
718 const GLenum
* attachments
));
719 MOCK_METHOD1(clear
, void(GLbitfield mask
));
722 TEST_F(GLRendererTest
, OpaqueBackground
) {
723 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
724 ClearCountingContext
* context
= context_owned
.get();
726 FakeOutputSurfaceClient output_surface_client
;
727 scoped_ptr
<OutputSurface
> output_surface(
728 FakeOutputSurface::Create3d(context_owned
.Pass()));
729 CHECK(output_surface
->BindToClient(&output_surface_client
));
731 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
732 new TestSharedBitmapManager());
733 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
734 output_surface
.get(), shared_bitmap_manager
.get());
736 RendererSettings settings
;
737 FakeRendererClient renderer_client
;
738 FakeRendererGL
renderer(&renderer_client
,
740 output_surface
.get(),
741 resource_provider
.get());
743 gfx::Rect
viewport_rect(1, 1);
744 RenderPass
* root_pass
=
745 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
746 viewport_rect
, gfx::Transform());
747 root_pass
->has_transparent_background
= false;
749 // On DEBUG builds, render passes with opaque background clear to blue to
750 // easily see regions that were not drawn on the screen.
751 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
752 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
755 EXPECT_CALL(*context
, clear(_
)).Times(0);
757 EXPECT_CALL(*context
, clear(_
)).Times(1);
759 renderer
.DrawFrame(&render_passes_in_draw_order_
,
764 Mock::VerifyAndClearExpectations(context
);
767 TEST_F(GLRendererTest
, TransparentBackground
) {
768 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
769 ClearCountingContext
* context
= context_owned
.get();
771 FakeOutputSurfaceClient output_surface_client
;
772 scoped_ptr
<OutputSurface
> output_surface(
773 FakeOutputSurface::Create3d(context_owned
.Pass()));
774 CHECK(output_surface
->BindToClient(&output_surface_client
));
776 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
777 new TestSharedBitmapManager());
778 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
779 output_surface
.get(), shared_bitmap_manager
.get());
781 RendererSettings settings
;
782 FakeRendererClient renderer_client
;
783 FakeRendererGL
renderer(&renderer_client
,
785 output_surface
.get(),
786 resource_provider
.get());
788 gfx::Rect
viewport_rect(1, 1);
789 RenderPass
* root_pass
=
790 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
791 viewport_rect
, gfx::Transform());
792 root_pass
->has_transparent_background
= true;
794 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
795 EXPECT_CALL(*context
, clear(_
)).Times(1);
796 renderer
.DrawFrame(&render_passes_in_draw_order_
,
802 Mock::VerifyAndClearExpectations(context
);
805 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
806 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
807 ClearCountingContext
* context
= context_owned
.get();
809 FakeOutputSurfaceClient output_surface_client
;
810 scoped_ptr
<OutputSurface
> output_surface(
811 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
812 CHECK(output_surface
->BindToClient(&output_surface_client
));
814 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
815 new TestSharedBitmapManager());
816 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
817 output_surface
.get(), shared_bitmap_manager
.get());
819 RendererSettings settings
;
820 FakeRendererClient renderer_client
;
821 FakeRendererGL
renderer(&renderer_client
,
823 output_surface
.get(),
824 resource_provider
.get());
826 gfx::Rect
viewport_rect(1, 1);
827 AddRenderPass(&render_passes_in_draw_order_
,
832 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
833 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
835 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
836 renderer
.DrawFrame(&render_passes_in_draw_order_
,
841 Mock::VerifyAndClearExpectations(context
);
844 class VisibilityChangeIsLastCallTrackingContext
845 : public TestWebGraphicsContext3D
{
847 VisibilityChangeIsLastCallTrackingContext()
848 : last_call_was_set_visibility_(false) {}
850 // TestWebGraphicsContext3D methods.
851 void flush() override
{ last_call_was_set_visibility_
= false; }
852 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
853 void deleteFramebuffer(GLuint
) override
{
854 last_call_was_set_visibility_
= false;
856 void deleteQueryEXT(GLuint
) override
{
857 last_call_was_set_visibility_
= false;
859 void deleteRenderbuffer(GLuint
) override
{
860 last_call_was_set_visibility_
= false;
863 // Methods added for test.
864 void set_last_call_was_visibility(bool visible
) {
865 DCHECK(last_call_was_set_visibility_
== false);
866 last_call_was_set_visibility_
= true;
868 bool last_call_was_set_visibility() const {
869 return last_call_was_set_visibility_
;
873 bool last_call_was_set_visibility_
;
876 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
877 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
878 new VisibilityChangeIsLastCallTrackingContext
);
879 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
881 scoped_refptr
<TestContextProvider
> provider
=
882 TestContextProvider::Create(context_owned
.Pass());
884 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
885 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
886 base::Unretained(context
)));
888 FakeOutputSurfaceClient output_surface_client
;
889 scoped_ptr
<OutputSurface
> output_surface(
890 FakeOutputSurface::Create3d(provider
));
891 CHECK(output_surface
->BindToClient(&output_surface_client
));
893 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
894 new TestSharedBitmapManager());
895 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
896 output_surface
.get(), shared_bitmap_manager
.get());
898 RendererSettings settings
;
899 FakeRendererClient renderer_client
;
900 FakeRendererGL
renderer(&renderer_client
,
902 output_surface
.get(),
903 resource_provider
.get());
905 gfx::Rect
viewport_rect(1, 1);
906 AddRenderPass(&render_passes_in_draw_order_
,
911 // Ensure that the call to SetSurfaceVisible is the last call issue to the
912 // GPU process, after glFlush is called, and after the RendererClient's
913 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
914 // RenderClient and the Context by giving them both a pointer to a variable on
916 renderer
.SetVisible(true);
917 renderer
.DrawFrame(&render_passes_in_draw_order_
,
922 renderer
.SetVisible(false);
923 EXPECT_TRUE(context
->last_call_was_set_visibility());
926 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
928 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
929 test_capabilities_
.gpu
.egl_image_external
= true;
932 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
933 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
934 MOCK_METHOD4(drawElements
,
935 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
937 virtual void activeTexture(GLenum texture
) {
938 EXPECT_NE(texture
, active_texture_
);
939 active_texture_
= texture
;
942 GLenum
active_texture() const { return active_texture_
; }
945 GLenum active_texture_
;
948 TEST_F(GLRendererTest
, ActiveTextureState
) {
949 scoped_ptr
<TextureStateTrackingContext
> context_owned(
950 new TextureStateTrackingContext
);
951 TextureStateTrackingContext
* context
= context_owned
.get();
953 FakeOutputSurfaceClient output_surface_client
;
954 scoped_ptr
<OutputSurface
> output_surface(
955 FakeOutputSurface::Create3d(context_owned
.Pass()));
956 CHECK(output_surface
->BindToClient(&output_surface_client
));
958 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
959 new TestSharedBitmapManager());
960 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
961 output_surface
.get(), shared_bitmap_manager
.get());
963 RendererSettings settings
;
964 FakeRendererClient renderer_client
;
965 FakeRendererGL
renderer(&renderer_client
,
967 output_surface
.get(),
968 resource_provider
.get());
970 // During initialization we are allowed to set any texture parameters.
971 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
973 RenderPass
* root_pass
=
974 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 1),
975 gfx::Rect(100, 100), gfx::Transform());
976 uint32_t mailbox_sync_point
;
977 AddOneOfEveryQuadType(root_pass
, resource_provider
.get(), RenderPassId(0, 0),
978 &mailbox_sync_point
);
980 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
982 // Set up expected texture filter state transitions that match the quads
983 // created in AppendOneOfEveryQuadType().
984 Mock::VerifyAndClearExpectations(context
);
988 // The sync points for all quads are waited on first. This sync point is
989 // for a texture quad drawn later in the frame.
990 EXPECT_CALL(*context
, waitSyncPoint(mailbox_sync_point
)).Times(1);
992 // yuv_quad is drawn with the default linear filter.
993 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
995 // tile_quad is drawn with GL_NEAREST because it is not transformed or
999 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
1002 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
1003 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1005 // transformed_tile_quad uses GL_LINEAR.
1006 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1008 // scaled_tile_quad also uses GL_LINEAR.
1009 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1011 // The remaining quads also use GL_LINEAR because nearest neighbor
1012 // filtering is currently only used with tile quads.
1013 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(6);
1016 gfx::Rect
viewport_rect(100, 100);
1017 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1022 Mock::VerifyAndClearExpectations(context
);
1025 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
1027 MOCK_METHOD1(clear
, void(GLbitfield mask
));
1028 MOCK_METHOD4(drawElements
,
1029 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1032 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
1033 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
1034 new NoClearRootRenderPassMockContext
);
1035 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
1037 FakeOutputSurfaceClient output_surface_client
;
1038 scoped_ptr
<OutputSurface
> output_surface(
1039 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
1040 CHECK(output_surface
->BindToClient(&output_surface_client
));
1042 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1043 new TestSharedBitmapManager());
1044 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1045 output_surface
.get(), shared_bitmap_manager
.get());
1047 RendererSettings settings
;
1048 settings
.should_clear_root_render_pass
= false;
1050 FakeRendererClient renderer_client
;
1051 FakeRendererGL
renderer(&renderer_client
,
1053 output_surface
.get(),
1054 resource_provider
.get());
1056 gfx::Rect
viewport_rect(10, 10);
1058 RenderPassId
child_pass_id(2, 0);
1059 RenderPass
* child_pass
=
1060 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, viewport_rect
,
1062 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
1064 RenderPassId
root_pass_id(1, 0);
1065 RenderPass
* root_pass
=
1066 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1068 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1071 AddRenderPassQuad(root_pass
, child_pass
);
1074 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
1076 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1079 // First render pass is not the root one, clearing should happen.
1080 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1082 Expectation first_render_pass
=
1083 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1085 // The second render pass is the root one, clearing should be prevented.
1086 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1089 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1092 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1093 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1099 // In multiple render passes all but the root pass should clear the
1101 Mock::VerifyAndClearExpectations(&mock_context
);
1104 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1106 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1108 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1110 void enable(GLenum cap
) override
{
1111 if (cap
== GL_SCISSOR_TEST
)
1112 scissor_enabled_
= true;
1115 void disable(GLenum cap
) override
{
1116 if (cap
== GL_SCISSOR_TEST
)
1117 scissor_enabled_
= false;
1121 bool scissor_enabled_
;
1124 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1125 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1126 new ScissorTestOnClearCheckingContext
);
1128 FakeOutputSurfaceClient output_surface_client
;
1129 scoped_ptr
<OutputSurface
> output_surface(
1130 FakeOutputSurface::Create3d(context_owned
.Pass()));
1131 CHECK(output_surface
->BindToClient(&output_surface_client
));
1133 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1134 new TestSharedBitmapManager());
1135 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1136 output_surface
.get(), shared_bitmap_manager
.get());
1138 RendererSettings settings
;
1139 FakeRendererClient renderer_client
;
1140 FakeRendererGL
renderer(&renderer_client
,
1142 output_surface
.get(),
1143 resource_provider
.get());
1144 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1146 gfx::Rect
viewport_rect(1, 1);
1148 gfx::Rect
grand_child_rect(25, 25);
1149 RenderPassId
grand_child_pass_id(3, 0);
1150 RenderPass
* grand_child_pass
=
1151 AddRenderPass(&render_passes_in_draw_order_
, grand_child_pass_id
,
1152 grand_child_rect
, gfx::Transform());
1153 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1155 gfx::Rect
child_rect(50, 50);
1156 RenderPassId
child_pass_id(2, 0);
1157 RenderPass
* child_pass
=
1158 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, child_rect
,
1160 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1162 RenderPassId
root_pass_id(1, 0);
1163 RenderPass
* root_pass
=
1164 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1166 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1168 AddRenderPassQuad(root_pass
, child_pass
);
1169 AddRenderPassQuad(child_pass
, grand_child_pass
);
1171 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1172 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1179 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1181 DiscardCheckingContext() : discarded_(0) {
1182 set_have_post_sub_buffer(true);
1183 set_have_discard_framebuffer(true);
1186 void discardFramebufferEXT(GLenum target
,
1187 GLsizei numAttachments
,
1188 const GLenum
* attachments
) override
{
1192 int discarded() const { return discarded_
; }
1193 void reset() { discarded_
= 0; }
1199 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1201 explicit NonReshapableOutputSurface(
1202 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1203 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1205 surface_size_
= gfx::Size(500, 500);
1207 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1208 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1211 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1212 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1213 DiscardCheckingContext
* context
= context_owned
.get();
1215 FakeOutputSurfaceClient output_surface_client
;
1216 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1217 new NonReshapableOutputSurface(context_owned
.Pass()));
1218 CHECK(output_surface
->BindToClient(&output_surface_client
));
1219 output_surface
->set_fixed_size(gfx::Size(100, 100));
1221 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1222 new TestSharedBitmapManager());
1223 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1224 output_surface
.get(), shared_bitmap_manager
.get());
1226 RendererSettings settings
;
1227 settings
.partial_swap_enabled
= true;
1228 FakeRendererClient renderer_client
;
1229 FakeRendererGL
renderer(&renderer_client
,
1231 output_surface
.get(),
1232 resource_provider
.get());
1233 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1235 gfx::Rect
viewport_rect(100, 100);
1236 gfx::Rect
clip_rect(100, 100);
1239 // Partial frame, should not discard.
1240 RenderPassId
root_pass_id(1, 0);
1241 RenderPass
* root_pass
=
1242 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1243 viewport_rect
, gfx::Transform());
1244 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1245 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1247 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1248 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1253 EXPECT_EQ(0, context
->discarded());
1257 // Full frame, should discard.
1258 RenderPassId
root_pass_id(1, 0);
1259 RenderPass
* root_pass
=
1260 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1261 viewport_rect
, gfx::Transform());
1262 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1263 root_pass
->damage_rect
= root_pass
->output_rect
;
1265 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1266 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1271 EXPECT_EQ(1, context
->discarded());
1275 // Full frame, external scissor is set, should not discard.
1276 output_surface
->set_has_external_stencil_test(true);
1277 RenderPassId
root_pass_id(1, 0);
1278 RenderPass
* root_pass
=
1279 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1280 viewport_rect
, gfx::Transform());
1281 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1282 root_pass
->damage_rect
= root_pass
->output_rect
;
1283 root_pass
->has_transparent_background
= false;
1285 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1286 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1291 EXPECT_EQ(0, context
->discarded());
1293 output_surface
->set_has_external_stencil_test(false);
1296 // Full frame, clipped, should not discard.
1297 clip_rect
= gfx::Rect(10, 10, 10, 10);
1298 RenderPassId
root_pass_id(1, 0);
1299 RenderPass
* root_pass
=
1300 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1301 viewport_rect
, gfx::Transform());
1302 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1303 root_pass
->damage_rect
= root_pass
->output_rect
;
1305 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1306 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1311 EXPECT_EQ(0, context
->discarded());
1315 // Full frame, doesn't cover the surface, should not discard.
1316 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1317 RenderPassId
root_pass_id(1, 0);
1318 RenderPass
* root_pass
=
1319 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1320 viewport_rect
, gfx::Transform());
1321 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1322 root_pass
->damage_rect
= root_pass
->output_rect
;
1324 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1325 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1330 EXPECT_EQ(0, context
->discarded());
1334 // Full frame, doesn't cover the surface (no offset), should not discard.
1335 clip_rect
= gfx::Rect(100, 100);
1336 viewport_rect
= gfx::Rect(50, 50);
1337 RenderPassId
root_pass_id(1, 0);
1338 RenderPass
* root_pass
=
1339 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
,
1340 viewport_rect
, gfx::Transform());
1341 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1342 root_pass
->damage_rect
= root_pass
->output_rect
;
1344 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1345 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1350 EXPECT_EQ(0, context
->discarded());
1355 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1357 MOCK_METHOD4(viewport
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1358 MOCK_METHOD4(scissor
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1361 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1362 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1363 // and maintains a fixed size. This test verifies that glViewport and
1364 // glScissor's Y coordinate is flipped correctly in this environment, and that
1365 // the glViewport can be at a nonzero origin within the surface.
1366 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1367 new FlippedScissorAndViewportContext
);
1369 // We expect exactly one call to viewport on this context and exactly two
1370 // to scissor (one to scissor the clear, one to scissor the quad draw).
1371 EXPECT_CALL(*context_owned
, viewport(10, 390, 100, 100));
1372 EXPECT_CALL(*context_owned
, scissor(10, 390, 100, 100));
1373 EXPECT_CALL(*context_owned
, scissor(30, 450, 20, 20));
1375 FakeOutputSurfaceClient output_surface_client
;
1376 scoped_ptr
<OutputSurface
> output_surface(
1377 new NonReshapableOutputSurface(context_owned
.Pass()));
1378 CHECK(output_surface
->BindToClient(&output_surface_client
));
1380 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1381 new TestSharedBitmapManager());
1382 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1383 output_surface
.get(), shared_bitmap_manager
.get());
1385 RendererSettings settings
;
1386 FakeRendererClient renderer_client
;
1387 FakeRendererGL
renderer(&renderer_client
,
1389 output_surface
.get(),
1390 resource_provider
.get());
1391 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1393 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1394 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1395 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1397 RenderPassId
root_pass_id(1, 0);
1398 RenderPass
* root_pass
=
1399 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1401 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1403 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1404 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1406 device_viewport_rect
,
1407 device_viewport_rect
,
1411 TEST_F(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1412 // When using render-to-FBO to display the surface, all rendering is done
1413 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1414 // the correct framebuffer during rendering, if changed.
1415 // Note: there is one path that will set it to 0, but that is after the render
1417 FakeOutputSurfaceClient output_surface_client
;
1418 scoped_ptr
<FakeOutputSurface
> output_surface(
1419 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1420 CHECK(output_surface
->BindToClient(&output_surface_client
));
1422 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1423 new TestSharedBitmapManager());
1424 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1425 output_surface
.get(), shared_bitmap_manager
.get());
1427 RendererSettings settings
;
1428 FakeRendererClient renderer_client
;
1429 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1430 resource_provider
.get());
1431 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1433 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1434 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1435 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1437 RenderPassId
root_pass_id(1, 0);
1438 RenderPass
* root_pass
=
1439 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1441 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1444 gpu::gles2::GLES2Interface
* gl
=
1445 output_surface
->context_provider()->ContextGL();
1446 gl
->GenFramebuffers(1, &fbo
);
1447 output_surface
->set_framebuffer(fbo
);
1449 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1450 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1451 device_viewport_rect
, false);
1454 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1455 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1458 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1459 gfx::Rect
viewport_rect(1, 1);
1461 gfx::Rect
child_rect(50, 50);
1462 RenderPassId
child_pass_id(2, 0);
1463 RenderPass
* child_pass
;
1465 RenderPassId
root_pass_id(1, 0);
1466 RenderPass
* root_pass
;
1468 ResourceId mask
= resource_provider_
->CreateResource(
1469 gfx::Size(20, 12), GL_CLAMP_TO_EDGE
,
1470 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1471 resource_provider_
->best_texture_format());
1472 resource_provider_
->AllocateForTesting(mask
);
1474 SkScalar matrix
[20];
1475 float amount
= 0.5f
;
1476 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1477 matrix
[1] = 0.715f
- 0.715f
* amount
;
1478 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1479 matrix
[3] = matrix
[4] = 0;
1480 matrix
[5] = 0.213f
- 0.213f
* amount
;
1481 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1482 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1483 matrix
[8] = matrix
[9] = 0;
1484 matrix
[10] = 0.213f
- 0.213f
* amount
;
1485 matrix
[11] = 0.715f
- 0.715f
* amount
;
1486 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1487 matrix
[13] = matrix
[14] = 0;
1488 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1490 skia::RefPtr
<SkColorFilter
> color_filter(
1491 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1492 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1493 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1494 FilterOperations filters
;
1495 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1497 gfx::Transform transform_causing_aa
;
1498 transform_causing_aa
.Rotate(20.0);
1500 for (int i
= 0; i
<= LAST_BLEND_MODE
; ++i
) {
1501 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1502 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1503 settings_
.force_blending_with_shaders
= (blend_mode
!= BLEND_MODE_NONE
);
1504 // RenderPassProgram
1505 render_passes_in_draw_order_
.clear();
1506 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1511 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1516 AddRenderPassQuad(root_pass
,
1523 renderer_
->DecideRenderPassAllocationsForFrame(
1524 render_passes_in_draw_order_
);
1525 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1530 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1532 // RenderPassColorMatrixProgram
1533 render_passes_in_draw_order_
.clear();
1535 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1538 transform_causing_aa
);
1540 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1546 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1548 renderer_
->DecideRenderPassAllocationsForFrame(
1549 render_passes_in_draw_order_
);
1550 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1555 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1557 // RenderPassMaskProgram
1558 render_passes_in_draw_order_
.clear();
1560 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1565 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1570 AddRenderPassQuad(root_pass
,
1577 renderer_
->DecideRenderPassAllocationsForFrame(
1578 render_passes_in_draw_order_
);
1579 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1584 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1587 // RenderPassMaskColorMatrixProgram
1588 render_passes_in_draw_order_
.clear();
1590 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1595 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1601 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1603 renderer_
->DecideRenderPassAllocationsForFrame(
1604 render_passes_in_draw_order_
);
1605 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1610 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
,
1611 SAMPLER_TYPE_2D
, blend_mode
);
1613 // RenderPassProgramAA
1614 render_passes_in_draw_order_
.clear();
1616 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1619 transform_causing_aa
);
1621 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1626 AddRenderPassQuad(root_pass
,
1630 transform_causing_aa
,
1633 renderer_
->DecideRenderPassAllocationsForFrame(
1634 render_passes_in_draw_order_
);
1635 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1640 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1642 // RenderPassColorMatrixProgramAA
1643 render_passes_in_draw_order_
.clear();
1645 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1648 transform_causing_aa
);
1650 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1656 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1658 renderer_
->DecideRenderPassAllocationsForFrame(
1659 render_passes_in_draw_order_
);
1660 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1665 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1667 // RenderPassMaskProgramAA
1668 render_passes_in_draw_order_
.clear();
1670 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1673 transform_causing_aa
);
1675 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1680 AddRenderPassQuad(root_pass
,
1684 transform_causing_aa
,
1687 renderer_
->DecideRenderPassAllocationsForFrame(
1688 render_passes_in_draw_order_
);
1689 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1694 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1697 // RenderPassMaskColorMatrixProgramAA
1698 render_passes_in_draw_order_
.clear();
1700 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1703 transform_causing_aa
);
1705 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1708 transform_causing_aa
);
1711 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1713 renderer_
->DecideRenderPassAllocationsForFrame(
1714 render_passes_in_draw_order_
);
1715 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1720 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
,
1721 SAMPLER_TYPE_2D
, blend_mode
);
1725 // At this time, the AA code path cannot be taken if the surface's rect would
1726 // project incorrectly by the given transform, because of w<0 clipping.
1727 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1728 gfx::Rect
child_rect(50, 50);
1729 RenderPassId
child_pass_id(2, 0);
1730 RenderPass
* child_pass
;
1732 gfx::Rect
viewport_rect(1, 1);
1733 RenderPassId
root_pass_id(1, 0);
1734 RenderPass
* root_pass
;
1736 gfx::Transform transform_preventing_aa
;
1737 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1738 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1739 transform_preventing_aa
.Scale(30.0, 1.0);
1741 // Verify that the test transform and test rect actually do cause the clipped
1742 // flag to trigger. Otherwise we are not testing the intended scenario.
1743 bool clipped
= false;
1744 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(gfx::RectF(child_rect
)),
1746 ASSERT_TRUE(clipped
);
1748 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1751 transform_preventing_aa
);
1753 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1758 AddRenderPassQuad(root_pass
,
1762 transform_preventing_aa
,
1763 SkXfermode::kSrcOver_Mode
);
1765 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1766 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1772 // If use_aa incorrectly ignores clipping, it will use the
1773 // RenderPassProgramAA shader instead of the RenderPassProgram.
1774 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, BLEND_MODE_NONE
);
1777 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1778 gfx::Rect
viewport_rect(1, 1);
1779 RenderPassId
root_pass_id(1, 0);
1780 RenderPass
* root_pass
;
1782 gfx::Transform pixel_aligned_transform_causing_aa
;
1783 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1784 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1786 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1790 AddTransformedQuad(root_pass
,
1793 pixel_aligned_transform_causing_aa
);
1795 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1796 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1802 TestSolidColorProgramAA();
1805 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1807 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1809 // Specifically override methods even if they are unused (used in conjunction
1810 // with StrictMock). We need to make sure that GLRenderer does not issue
1811 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1812 // through the OutputSurface abstraction.
1813 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1814 MOCK_METHOD3(reshapeWithScaleFactor
,
1815 void(int width
, int height
, float scale_factor
));
1816 MOCK_METHOD4(drawElements
,
1817 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1820 class MockOutputSurface
: public OutputSurface
{
1824 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1825 new StrictMock
<OutputSurfaceMockContext
>))) {
1826 surface_size_
= gfx::Size(100, 100);
1828 virtual ~MockOutputSurface() {}
1830 MOCK_METHOD0(EnsureBackbuffer
, void());
1831 MOCK_METHOD0(DiscardBackbuffer
, void());
1832 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1833 MOCK_METHOD0(BindFramebuffer
, void());
1834 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1837 class MockOutputSurfaceTest
: public GLRendererTest
{
1839 virtual void SetUp() {
1840 FakeOutputSurfaceClient output_surface_client_
;
1841 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1843 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1844 resource_provider_
= FakeResourceProvider::Create(
1845 &output_surface_
, shared_bitmap_manager_
.get());
1847 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1850 resource_provider_
.get()));
1853 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1855 void DrawFrame(float device_scale_factor
,
1856 const gfx::Rect
& device_viewport_rect
) {
1857 RenderPassId
render_pass_id(1, 0);
1858 RenderPass
* render_pass
=
1859 AddRenderPass(&render_passes_in_draw_order_
, render_pass_id
,
1860 device_viewport_rect
, gfx::Transform());
1861 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1863 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1865 EXPECT_CALL(output_surface_
,
1866 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1869 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1871 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1873 renderer_
->DecideRenderPassAllocationsForFrame(
1874 render_passes_in_draw_order_
);
1875 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1876 device_scale_factor
,
1877 device_viewport_rect
,
1878 device_viewport_rect
,
1882 OutputSurfaceMockContext
* Context() {
1883 return static_cast<OutputSurfaceMockContext
*>(
1884 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1888 RendererSettings settings_
;
1889 FakeOutputSurfaceClient output_surface_client_
;
1890 StrictMock
<MockOutputSurface
> output_surface_
;
1891 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1892 scoped_ptr
<ResourceProvider
> resource_provider_
;
1893 FakeRendererClient renderer_client_
;
1894 scoped_ptr
<FakeRendererGL
> renderer_
;
1897 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1898 gfx::Rect
device_viewport_rect(1, 1);
1899 DrawFrame(1.f
, device_viewport_rect
);
1901 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1902 renderer_
->SwapBuffers(CompositorFrameMetadata());
1905 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1906 gfx::Rect
device_viewport_rect(1, 1);
1908 DrawFrame(1.f
, device_viewport_rect
);
1909 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1910 renderer_
->SwapBuffers(CompositorFrameMetadata());
1912 device_viewport_rect
= gfx::Rect(2, 2);
1914 DrawFrame(2.f
, device_viewport_rect
);
1915 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1916 renderer_
->SwapBuffers(CompositorFrameMetadata());
1918 DrawFrame(2.f
, device_viewport_rect
);
1919 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1920 renderer_
->SwapBuffers(CompositorFrameMetadata());
1922 device_viewport_rect
= gfx::Rect(1, 1);
1924 DrawFrame(1.f
, device_viewport_rect
);
1925 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1926 renderer_
->SwapBuffers(CompositorFrameMetadata());
1929 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1931 static void SyncPointCallback(int* callback_count
) {
1932 ++(*callback_count
);
1933 base::MessageLoop::current()->QuitWhenIdle();
1936 static void OtherCallback(int* callback_count
) {
1937 ++(*callback_count
);
1938 base::MessageLoop::current()->QuitWhenIdle();
1942 #if !defined(OS_ANDROID)
1943 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1944 int sync_point_callback_count
= 0;
1945 int other_callback_count
= 0;
1946 gpu::gles2::GLES2Interface
* gl
=
1947 output_surface_
->context_provider()->ContextGL();
1948 gpu::ContextSupport
* context_support
=
1949 output_surface_
->context_provider()->ContextSupport();
1951 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1953 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1954 GL_INNOCENT_CONTEXT_RESET_ARB
);
1956 context_support
->SignalSyncPoint(
1957 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1958 EXPECT_EQ(0, sync_point_callback_count
);
1959 EXPECT_EQ(0, other_callback_count
);
1961 // Make the sync point happen.
1963 // Post a task after the sync point.
1964 base::ThreadTaskRunnerHandle::Get()->PostTask(
1965 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1967 base::MessageLoop::current()->Run();
1969 // The sync point shouldn't have happened since the context was lost.
1970 EXPECT_EQ(0, sync_point_callback_count
);
1971 EXPECT_EQ(1, other_callback_count
);
1974 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1975 int sync_point_callback_count
= 0;
1976 int other_callback_count
= 0;
1978 gpu::gles2::GLES2Interface
* gl
=
1979 output_surface_
->context_provider()->ContextGL();
1980 gpu::ContextSupport
* context_support
=
1981 output_surface_
->context_provider()->ContextSupport();
1983 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1985 context_support
->SignalSyncPoint(
1986 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1987 EXPECT_EQ(0, sync_point_callback_count
);
1988 EXPECT_EQ(0, other_callback_count
);
1990 // Make the sync point happen.
1992 // Post a task after the sync point.
1993 base::ThreadTaskRunnerHandle::Get()->PostTask(
1994 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1996 base::MessageLoop::current()->Run();
1998 // The sync point should have happened.
1999 EXPECT_EQ(1, sync_point_callback_count
);
2000 EXPECT_EQ(1, other_callback_count
);
2002 #endif // OS_ANDROID
2004 class TestOverlayProcessor
: public OverlayProcessor
{
2006 class Strategy
: public OverlayProcessor::Strategy
{
2009 ~Strategy() override
{}
2010 MOCK_METHOD3(Attempt
,
2011 bool(RenderPassList
* render_passes_in_draw_order
,
2012 OverlayCandidateList
* candidates
,
2013 float device_scale_factor
));
2016 explicit TestOverlayProcessor(OutputSurface
* surface
)
2017 : OverlayProcessor(surface
) {}
2018 ~TestOverlayProcessor() override
{}
2019 void Initialize() override
{
2020 strategy_
= new Strategy();
2021 strategies_
.push_back(scoped_ptr
<OverlayProcessor::Strategy
>(strategy_
));
2024 Strategy
* strategy_
;
2027 void MailboxReleased(unsigned sync_point
,
2029 BlockingTaskRunner
* main_thread_task_runner
) {
2032 void IgnoreCopyResult(scoped_ptr
<CopyOutputResult
> result
) {
2035 TEST_F(GLRendererTest
, DontOverlayWithCopyRequests
) {
2036 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
2037 FakeOutputSurfaceClient output_surface_client
;
2038 scoped_ptr
<OutputSurface
> output_surface(
2039 FakeOutputSurface::Create3d(context_owned
.Pass()));
2040 CHECK(output_surface
->BindToClient(&output_surface_client
));
2042 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2043 new TestSharedBitmapManager());
2044 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2045 output_surface
.get(), shared_bitmap_manager
.get());
2046 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2047 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2049 RendererSettings settings
;
2050 FakeRendererClient renderer_client
;
2051 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2052 resource_provider
.get(), mailbox_deleter
.get());
2054 TestOverlayProcessor
* processor
=
2055 new TestOverlayProcessor(output_surface
.get());
2056 processor
->Initialize();
2057 renderer
.SetOverlayProcessor(processor
);
2059 gfx::Rect
viewport_rect(1, 1);
2060 RenderPass
* root_pass
=
2061 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2062 viewport_rect
, gfx::Transform());
2063 root_pass
->has_transparent_background
= false;
2064 root_pass
->copy_requests
.push_back(
2065 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult
)));
2067 unsigned sync_point
= 0;
2068 TextureMailbox mailbox
=
2069 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2070 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2071 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2072 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2073 mailbox
, release_callback
.Pass());
2074 bool premultiplied_alpha
= false;
2075 bool flipped
= false;
2076 bool nearest_neighbor
= false;
2077 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2079 TextureDrawQuad
* overlay_quad
=
2080 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2081 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2082 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2083 premultiplied_alpha
, gfx::PointF(0, 0),
2084 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2085 flipped
, nearest_neighbor
);
2086 overlay_quad
->set_allow_overlay(true);
2088 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2089 // Attempt will be called for each strategy in OverlayProcessor. We have
2090 // added a fake strategy, so checking for Attempt calls checks if there was
2091 // any attempt to overlay, which there shouldn't be. We can't use the quad
2092 // list because the render pass is cleaned up by DrawFrame.
2093 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
, _
)).Times(0);
2094 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2095 viewport_rect
, false);
2096 Mock::VerifyAndClearExpectations(processor
->strategy_
);
2098 // Without a copy request Attempt() should be called once.
2099 root_pass
= AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2100 viewport_rect
, gfx::Transform());
2101 root_pass
->has_transparent_background
= false;
2103 overlay_quad
= root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2104 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2105 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2106 premultiplied_alpha
, gfx::PointF(0, 0),
2107 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2108 flipped
, nearest_neighbor
);
2110 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
, _
)).Times(1);
2111 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2112 viewport_rect
, false);
2115 class SingleOverlayOnTopProcessor
: public OverlayProcessor
{
2117 class SingleOverlayValidator
: public OverlayCandidateValidator
{
2119 void GetStrategies(OverlayProcessor::StrategyList
* strategies
) override
{
2120 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
2121 new OverlayStrategyCommon(this, new OverlayStrategySingleOnTop
)));
2122 strategies
->push_back(scoped_ptr
<OverlayProcessor::Strategy
>(
2123 new OverlayStrategyCommon(this, new OverlayStrategyUnderlay
)));
2126 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
2127 ASSERT_EQ(2U, surfaces
->size());
2128 OverlayCandidate
& candidate
= surfaces
->back();
2129 candidate
.overlay_handled
= true;
2133 explicit SingleOverlayOnTopProcessor(OutputSurface
* surface
)
2134 : OverlayProcessor(surface
) {}
2136 void Initialize() override
{
2137 strategies_
.push_back(scoped_ptr
<Strategy
>(new OverlayStrategyCommon(
2138 &validator_
, new OverlayStrategySingleOnTop
)));
2141 SingleOverlayValidator validator_
;
2144 class WaitSyncPointCountingContext
: public TestWebGraphicsContext3D
{
2146 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
2149 class MockOverlayScheduler
{
2151 MOCK_METHOD5(Schedule
,
2152 void(int plane_z_order
,
2153 gfx::OverlayTransform plane_transform
,
2154 unsigned overlay_texture_id
,
2155 const gfx::Rect
& display_bounds
,
2156 const gfx::RectF
& uv_rect
));
2159 TEST_F(GLRendererTest
, OverlaySyncPointsAreProcessed
) {
2160 scoped_ptr
<WaitSyncPointCountingContext
> context_owned(
2161 new WaitSyncPointCountingContext
);
2162 WaitSyncPointCountingContext
* context
= context_owned
.get();
2164 MockOverlayScheduler overlay_scheduler
;
2165 scoped_refptr
<TestContextProvider
> context_provider
=
2166 TestContextProvider::Create(context_owned
.Pass());
2167 context_provider
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2168 &MockOverlayScheduler::Schedule
, base::Unretained(&overlay_scheduler
)));
2170 FakeOutputSurfaceClient output_surface_client
;
2171 scoped_ptr
<OutputSurface
> output_surface(
2172 FakeOutputSurface::Create3d(context_provider
));
2173 CHECK(output_surface
->BindToClient(&output_surface_client
));
2175 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2176 new TestSharedBitmapManager());
2177 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2178 output_surface
.get(), shared_bitmap_manager
.get());
2179 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2180 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2182 RendererSettings settings
;
2183 FakeRendererClient renderer_client
;
2184 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2185 resource_provider
.get(), mailbox_deleter
.get());
2187 SingleOverlayOnTopProcessor
* processor
=
2188 new SingleOverlayOnTopProcessor(output_surface
.get());
2189 processor
->Initialize();
2190 renderer
.SetOverlayProcessor(processor
);
2192 gfx::Rect
viewport_rect(1, 1);
2193 RenderPass
* root_pass
=
2194 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2195 viewport_rect
, gfx::Transform());
2196 root_pass
->has_transparent_background
= false;
2198 unsigned sync_point
= 29;
2199 TextureMailbox mailbox
=
2200 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2201 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2202 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2203 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2204 mailbox
, release_callback
.Pass());
2205 bool premultiplied_alpha
= false;
2206 bool flipped
= false;
2207 bool nearest_neighbor
= false;
2208 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2209 gfx::PointF
uv_top_left(0, 0);
2210 gfx::PointF
uv_bottom_right(1, 1);
2212 TextureDrawQuad
* overlay_quad
=
2213 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2214 SharedQuadState
* shared_state
= root_pass
->CreateAndAppendSharedQuadState();
2215 shared_state
->SetAll(gfx::Transform(), viewport_rect
.size(), viewport_rect
,
2216 viewport_rect
, false, 1, SkXfermode::kSrcOver_Mode
, 0);
2217 overlay_quad
->SetNew(shared_state
, viewport_rect
, viewport_rect
,
2218 viewport_rect
, resource_id
, premultiplied_alpha
,
2219 uv_top_left
, uv_bottom_right
, SK_ColorTRANSPARENT
,
2220 vertex_opacity
, flipped
, nearest_neighbor
);
2221 overlay_quad
->set_allow_overlay(true);
2223 // Verify that overlay_quad actually gets turned into an overlay, and even
2224 // though it's not drawn, that its sync point is waited on.
2225 EXPECT_CALL(*context
, waitSyncPoint(sync_point
)).Times(1);
2226 EXPECT_CALL(overlay_scheduler
,
2227 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE
, _
, viewport_rect
,
2228 BoundingRect(uv_top_left
, uv_bottom_right
))).Times(1);
2230 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2231 viewport_rect
, false);