1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/gl_renderer.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "cc/base/math_util.h"
13 #include "cc/output/compositor_frame_metadata.h"
14 #include "cc/output/copy_output_request.h"
15 #include "cc/output/copy_output_result.h"
16 #include "cc/output/overlay_strategy_single_on_top.h"
17 #include "cc/output/texture_mailbox_deleter.h"
18 #include "cc/quads/texture_draw_quad.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/test/fake_impl_proxy.h"
21 #include "cc/test/fake_layer_tree_host_impl.h"
22 #include "cc/test/fake_output_surface.h"
23 #include "cc/test/fake_output_surface_client.h"
24 #include "cc/test/fake_renderer_client.h"
25 #include "cc/test/fake_resource_provider.h"
26 #include "cc/test/pixel_test.h"
27 #include "cc/test/render_pass_test_common.h"
28 #include "cc/test/render_pass_test_utils.h"
29 #include "cc/test/test_shared_bitmap_manager.h"
30 #include "cc/test/test_web_graphics_context_3d.h"
31 #include "gpu/GLES2/gl2extchromium.h"
32 #include "gpu/command_buffer/client/context_support.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/skia/include/core/SkImageFilter.h"
36 #include "third_party/skia/include/core/SkMatrix.h"
37 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
38 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
39 #include "ui/gfx/transform.h"
42 using testing::AnyNumber
;
44 using testing::AtLeast
;
45 using testing::ElementsAre
;
46 using testing::Expectation
;
47 using testing::InSequence
;
49 using testing::Return
;
50 using testing::StrictMock
;
54 class GLRendererTest
: public testing::Test
{
56 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
58 RenderPassList render_passes_in_draw_order_
;
61 #define EXPECT_PROGRAM_VALID(program_binding) \
63 EXPECT_TRUE((program_binding)->program()); \
64 EXPECT_TRUE((program_binding)->initialized()); \
67 static inline SkXfermode::Mode
BlendModeToSkXfermode(BlendMode blend_mode
) {
70 case BLEND_MODE_NORMAL
:
71 return SkXfermode::kSrcOver_Mode
;
72 case BLEND_MODE_SCREEN
:
73 return SkXfermode::kScreen_Mode
;
74 case BLEND_MODE_OVERLAY
:
75 return SkXfermode::kOverlay_Mode
;
76 case BLEND_MODE_DARKEN
:
77 return SkXfermode::kDarken_Mode
;
78 case BLEND_MODE_LIGHTEN
:
79 return SkXfermode::kLighten_Mode
;
80 case BLEND_MODE_COLOR_DODGE
:
81 return SkXfermode::kColorDodge_Mode
;
82 case BLEND_MODE_COLOR_BURN
:
83 return SkXfermode::kColorBurn_Mode
;
84 case BLEND_MODE_HARD_LIGHT
:
85 return SkXfermode::kHardLight_Mode
;
86 case BLEND_MODE_SOFT_LIGHT
:
87 return SkXfermode::kSoftLight_Mode
;
88 case BLEND_MODE_DIFFERENCE
:
89 return SkXfermode::kDifference_Mode
;
90 case BLEND_MODE_EXCLUSION
:
91 return SkXfermode::kExclusion_Mode
;
92 case BLEND_MODE_MULTIPLY
:
93 return SkXfermode::kMultiply_Mode
;
95 return SkXfermode::kHue_Mode
;
96 case BLEND_MODE_SATURATION
:
97 return SkXfermode::kSaturation_Mode
;
98 case BLEND_MODE_COLOR
:
99 return SkXfermode::kColor_Mode
;
100 case BLEND_MODE_LUMINOSITY
:
101 return SkXfermode::kLuminosity_Mode
;
103 return SkXfermode::kSrcOver_Mode
;
106 // Explicitly named to be a friend in GLRenderer for shader access.
107 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
109 void SetUp() override
{
110 GLRendererPixelTest::SetUp();
111 ASSERT_FALSE(renderer()->IsContextLost());
114 void TearDown() override
{
115 GLRendererPixelTest::TearDown();
116 ASSERT_FALSE(renderer()->IsContextLost());
119 void TestBasicShaders() {
120 EXPECT_PROGRAM_VALID(renderer()->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 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
552 root_pass
->has_transparent_background
= false;
554 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
559 EXPECT_TRUE(renderer_
->stencil_enabled());
562 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
564 ForbidSynchronousCallContext() {}
566 void getAttachedShaders(GLuint program
,
569 GLuint
* shaders
) override
{
572 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
576 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
577 void getBufferParameteriv(GLenum target
,
579 GLint
* value
) override
{
582 GLenum
getError() override
{
586 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
587 void getFramebufferAttachmentParameteriv(GLenum target
,
590 GLint
* value
) override
{
593 void getIntegerv(GLenum pname
, GLint
* value
) override
{
594 if (pname
== GL_MAX_TEXTURE_SIZE
) {
595 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
602 // We allow querying the shader compilation and program link status in debug
603 // mode, but not release.
604 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
612 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
620 void getRenderbufferParameteriv(GLenum target
,
622 GLint
* value
) override
{
626 void getShaderPrecisionFormat(GLenum shadertype
,
627 GLenum precisiontype
,
629 GLint
* precision
) override
{
632 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
635 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
638 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
641 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
644 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
648 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
651 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
654 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
659 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
660 FakeOutputSurfaceClient output_surface_client
;
661 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
662 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
663 CHECK(output_surface
->BindToClient(&output_surface_client
));
665 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
666 new TestSharedBitmapManager());
667 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
668 output_surface
.get(), shared_bitmap_manager
.get());
670 RendererSettings settings
;
671 FakeRendererClient renderer_client
;
672 FakeRendererGL
renderer(&renderer_client
,
674 output_surface
.get(),
675 resource_provider
.get());
678 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
680 LoseContextOnFirstGetContext() {}
682 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
683 context_lost_
= true;
687 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
688 context_lost_
= true;
693 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
694 FakeOutputSurfaceClient output_surface_client
;
695 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
696 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
697 CHECK(output_surface
->BindToClient(&output_surface_client
));
699 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
700 new TestSharedBitmapManager());
701 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
702 output_surface
.get(), shared_bitmap_manager
.get());
704 RendererSettings settings
;
705 FakeRendererClient renderer_client
;
706 FakeRendererGL
renderer(&renderer_client
,
708 output_surface
.get(),
709 resource_provider
.get());
712 class ClearCountingContext
: public TestWebGraphicsContext3D
{
714 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
716 MOCK_METHOD3(discardFramebufferEXT
,
718 GLsizei numAttachments
,
719 const GLenum
* attachments
));
720 MOCK_METHOD1(clear
, void(GLbitfield mask
));
723 TEST_F(GLRendererTest
, OpaqueBackground
) {
724 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
725 ClearCountingContext
* context
= context_owned
.get();
727 FakeOutputSurfaceClient output_surface_client
;
728 scoped_ptr
<OutputSurface
> output_surface(
729 FakeOutputSurface::Create3d(context_owned
.Pass()));
730 CHECK(output_surface
->BindToClient(&output_surface_client
));
732 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
733 new TestSharedBitmapManager());
734 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
735 output_surface
.get(), shared_bitmap_manager
.get());
737 RendererSettings settings
;
738 FakeRendererClient renderer_client
;
739 FakeRendererGL
renderer(&renderer_client
,
741 output_surface
.get(),
742 resource_provider
.get());
744 gfx::Rect
viewport_rect(1, 1);
745 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
749 root_pass
->has_transparent_background
= false;
751 // On DEBUG builds, render passes with opaque background clear to blue to
752 // easily see regions that were not drawn on the screen.
753 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
754 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
757 EXPECT_CALL(*context
, clear(_
)).Times(0);
759 EXPECT_CALL(*context
, clear(_
)).Times(1);
761 renderer
.DrawFrame(&render_passes_in_draw_order_
,
766 Mock::VerifyAndClearExpectations(context
);
769 TEST_F(GLRendererTest
, TransparentBackground
) {
770 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
771 ClearCountingContext
* context
= context_owned
.get();
773 FakeOutputSurfaceClient output_surface_client
;
774 scoped_ptr
<OutputSurface
> output_surface(
775 FakeOutputSurface::Create3d(context_owned
.Pass()));
776 CHECK(output_surface
->BindToClient(&output_surface_client
));
778 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
779 new TestSharedBitmapManager());
780 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
781 output_surface
.get(), shared_bitmap_manager
.get());
783 RendererSettings settings
;
784 FakeRendererClient renderer_client
;
785 FakeRendererGL
renderer(&renderer_client
,
787 output_surface
.get(),
788 resource_provider
.get());
790 gfx::Rect
viewport_rect(1, 1);
791 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
795 root_pass
->has_transparent_background
= true;
797 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
798 EXPECT_CALL(*context
, clear(_
)).Times(1);
799 renderer
.DrawFrame(&render_passes_in_draw_order_
,
805 Mock::VerifyAndClearExpectations(context
);
808 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
809 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
810 ClearCountingContext
* context
= context_owned
.get();
812 FakeOutputSurfaceClient output_surface_client
;
813 scoped_ptr
<OutputSurface
> output_surface(
814 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
815 CHECK(output_surface
->BindToClient(&output_surface_client
));
817 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
818 new TestSharedBitmapManager());
819 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
820 output_surface
.get(), shared_bitmap_manager
.get());
822 RendererSettings settings
;
823 FakeRendererClient renderer_client
;
824 FakeRendererGL
renderer(&renderer_client
,
826 output_surface
.get(),
827 resource_provider
.get());
829 gfx::Rect
viewport_rect(1, 1);
830 AddRenderPass(&render_passes_in_draw_order_
,
835 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
836 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
838 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
839 renderer
.DrawFrame(&render_passes_in_draw_order_
,
844 Mock::VerifyAndClearExpectations(context
);
847 class VisibilityChangeIsLastCallTrackingContext
848 : public TestWebGraphicsContext3D
{
850 VisibilityChangeIsLastCallTrackingContext()
851 : last_call_was_set_visibility_(false) {}
853 // TestWebGraphicsContext3D methods.
854 void flush() override
{ last_call_was_set_visibility_
= false; }
855 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
856 void deleteFramebuffer(GLuint
) override
{
857 last_call_was_set_visibility_
= false;
859 void deleteQueryEXT(GLuint
) override
{
860 last_call_was_set_visibility_
= false;
862 void deleteRenderbuffer(GLuint
) override
{
863 last_call_was_set_visibility_
= false;
866 // Methods added for test.
867 void set_last_call_was_visibility(bool visible
) {
868 DCHECK(last_call_was_set_visibility_
== false);
869 last_call_was_set_visibility_
= true;
871 bool last_call_was_set_visibility() const {
872 return last_call_was_set_visibility_
;
876 bool last_call_was_set_visibility_
;
879 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
880 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
881 new VisibilityChangeIsLastCallTrackingContext
);
882 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
884 scoped_refptr
<TestContextProvider
> provider
=
885 TestContextProvider::Create(context_owned
.Pass());
887 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
888 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
889 base::Unretained(context
)));
891 FakeOutputSurfaceClient output_surface_client
;
892 scoped_ptr
<OutputSurface
> output_surface(
893 FakeOutputSurface::Create3d(provider
));
894 CHECK(output_surface
->BindToClient(&output_surface_client
));
896 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
897 new TestSharedBitmapManager());
898 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
899 output_surface
.get(), shared_bitmap_manager
.get());
901 RendererSettings settings
;
902 FakeRendererClient renderer_client
;
903 FakeRendererGL
renderer(&renderer_client
,
905 output_surface
.get(),
906 resource_provider
.get());
908 gfx::Rect
viewport_rect(1, 1);
909 AddRenderPass(&render_passes_in_draw_order_
,
914 // Ensure that the call to SetSurfaceVisible is the last call issue to the
915 // GPU process, after glFlush is called, and after the RendererClient's
916 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
917 // RenderClient and the Context by giving them both a pointer to a variable on
919 renderer
.SetVisible(true);
920 renderer
.DrawFrame(&render_passes_in_draw_order_
,
925 renderer
.SetVisible(false);
926 EXPECT_TRUE(context
->last_call_was_set_visibility());
929 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
931 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
932 test_capabilities_
.gpu
.egl_image_external
= true;
935 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
936 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
937 MOCK_METHOD4(drawElements
,
938 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
940 virtual void activeTexture(GLenum texture
) {
941 EXPECT_NE(texture
, active_texture_
);
942 active_texture_
= texture
;
945 GLenum
active_texture() const { return active_texture_
; }
948 GLenum active_texture_
;
951 TEST_F(GLRendererTest
, ActiveTextureState
) {
952 scoped_ptr
<TextureStateTrackingContext
> context_owned(
953 new TextureStateTrackingContext
);
954 TextureStateTrackingContext
* context
= context_owned
.get();
956 FakeOutputSurfaceClient output_surface_client
;
957 scoped_ptr
<OutputSurface
> output_surface(
958 FakeOutputSurface::Create3d(context_owned
.Pass()));
959 CHECK(output_surface
->BindToClient(&output_surface_client
));
961 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
962 new TestSharedBitmapManager());
963 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
964 output_surface
.get(), shared_bitmap_manager
.get());
966 RendererSettings settings
;
967 FakeRendererClient renderer_client
;
968 FakeRendererGL
renderer(&renderer_client
,
970 output_surface
.get(),
971 resource_provider
.get());
973 // During initialization we are allowed to set any texture parameters.
974 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
976 TestRenderPass
* root_pass
=
977 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 1),
978 gfx::Rect(100, 100), gfx::Transform());
979 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
982 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
984 // Set up expected texture filter state transitions that match the quads
985 // created in AppendOneOfEveryQuadType().
986 Mock::VerifyAndClearExpectations(context
);
990 // The sync points for all quads are waited on first. This sync point is
991 // for a texture quad drawn later in the frame.
992 EXPECT_CALL(*context
,
993 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
996 // yuv_quad is drawn with the default linear filter.
997 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
999 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1003 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
1006 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
1007 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1009 // transformed_tile_quad uses GL_LINEAR.
1010 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1012 // scaled_tile_quad also uses GL_LINEAR.
1013 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1015 // The remaining quads also use GL_LINEAR because nearest neighbor
1016 // filtering is currently only used with tile quads.
1017 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(6);
1020 gfx::Rect
viewport_rect(100, 100);
1021 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1026 Mock::VerifyAndClearExpectations(context
);
1029 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
1031 MOCK_METHOD1(clear
, void(GLbitfield mask
));
1032 MOCK_METHOD4(drawElements
,
1033 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1036 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
1037 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
1038 new NoClearRootRenderPassMockContext
);
1039 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
1041 FakeOutputSurfaceClient output_surface_client
;
1042 scoped_ptr
<OutputSurface
> output_surface(
1043 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
1044 CHECK(output_surface
->BindToClient(&output_surface_client
));
1046 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1047 new TestSharedBitmapManager());
1048 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1049 output_surface
.get(), shared_bitmap_manager
.get());
1051 RendererSettings settings
;
1052 settings
.should_clear_root_render_pass
= false;
1054 FakeRendererClient renderer_client
;
1055 FakeRendererGL
renderer(&renderer_client
,
1057 output_surface
.get(),
1058 resource_provider
.get());
1060 gfx::Rect
viewport_rect(10, 10);
1062 RenderPassId
child_pass_id(2, 0);
1063 TestRenderPass
* child_pass
=
1064 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, viewport_rect
,
1066 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
1068 RenderPassId
root_pass_id(1, 0);
1069 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1073 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1076 AddRenderPassQuad(root_pass
, child_pass
);
1079 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
1081 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1084 // First render pass is not the root one, clearing should happen.
1085 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1087 Expectation first_render_pass
=
1088 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1090 // The second render pass is the root one, clearing should be prevented.
1091 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1094 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1097 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1098 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1104 // In multiple render passes all but the root pass should clear the
1106 Mock::VerifyAndClearExpectations(&mock_context
);
1109 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1111 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1113 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1115 void enable(GLenum cap
) override
{
1116 if (cap
== GL_SCISSOR_TEST
)
1117 scissor_enabled_
= true;
1120 void disable(GLenum cap
) override
{
1121 if (cap
== GL_SCISSOR_TEST
)
1122 scissor_enabled_
= false;
1126 bool scissor_enabled_
;
1129 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1130 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1131 new ScissorTestOnClearCheckingContext
);
1133 FakeOutputSurfaceClient output_surface_client
;
1134 scoped_ptr
<OutputSurface
> output_surface(
1135 FakeOutputSurface::Create3d(context_owned
.Pass()));
1136 CHECK(output_surface
->BindToClient(&output_surface_client
));
1138 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1139 new TestSharedBitmapManager());
1140 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1141 output_surface
.get(), shared_bitmap_manager
.get());
1143 RendererSettings settings
;
1144 FakeRendererClient renderer_client
;
1145 FakeRendererGL
renderer(&renderer_client
,
1147 output_surface
.get(),
1148 resource_provider
.get());
1149 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1151 gfx::Rect
viewport_rect(1, 1);
1153 gfx::Rect
grand_child_rect(25, 25);
1154 RenderPassId
grand_child_pass_id(3, 0);
1155 TestRenderPass
* grand_child_pass
=
1156 AddRenderPass(&render_passes_in_draw_order_
,
1157 grand_child_pass_id
,
1160 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1162 gfx::Rect
child_rect(50, 50);
1163 RenderPassId
child_pass_id(2, 0);
1164 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1168 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1170 RenderPassId
root_pass_id(1, 0);
1171 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1175 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1177 AddRenderPassQuad(root_pass
, child_pass
);
1178 AddRenderPassQuad(child_pass
, grand_child_pass
);
1180 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1181 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1188 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1190 DiscardCheckingContext() : discarded_(0) {
1191 set_have_post_sub_buffer(true);
1192 set_have_discard_framebuffer(true);
1195 void discardFramebufferEXT(GLenum target
,
1196 GLsizei numAttachments
,
1197 const GLenum
* attachments
) override
{
1201 int discarded() const { return discarded_
; }
1202 void reset() { discarded_
= 0; }
1208 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1210 explicit NonReshapableOutputSurface(
1211 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1212 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1214 surface_size_
= gfx::Size(500, 500);
1216 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1217 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1220 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1221 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1222 DiscardCheckingContext
* context
= context_owned
.get();
1224 FakeOutputSurfaceClient output_surface_client
;
1225 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1226 new NonReshapableOutputSurface(context_owned
.Pass()));
1227 CHECK(output_surface
->BindToClient(&output_surface_client
));
1228 output_surface
->set_fixed_size(gfx::Size(100, 100));
1230 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1231 new TestSharedBitmapManager());
1232 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1233 output_surface
.get(), shared_bitmap_manager
.get());
1235 RendererSettings settings
;
1236 settings
.partial_swap_enabled
= true;
1237 FakeRendererClient renderer_client
;
1238 FakeRendererGL
renderer(&renderer_client
,
1240 output_surface
.get(),
1241 resource_provider
.get());
1242 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1244 gfx::Rect
viewport_rect(100, 100);
1245 gfx::Rect
clip_rect(100, 100);
1248 // Partial frame, should not discard.
1249 RenderPassId
root_pass_id(1, 0);
1250 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1254 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1255 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1257 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1258 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1263 EXPECT_EQ(0, context
->discarded());
1267 // Full frame, should discard.
1268 RenderPassId
root_pass_id(1, 0);
1269 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1273 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1274 root_pass
->damage_rect
= root_pass
->output_rect
;
1276 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1277 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1282 EXPECT_EQ(1, context
->discarded());
1286 // Full frame, external scissor is set, should not discard.
1287 output_surface
->set_has_external_stencil_test(true);
1288 RenderPassId
root_pass_id(1, 0);
1289 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1293 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1294 root_pass
->damage_rect
= root_pass
->output_rect
;
1295 root_pass
->has_transparent_background
= false;
1297 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1298 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1303 EXPECT_EQ(0, context
->discarded());
1305 output_surface
->set_has_external_stencil_test(false);
1308 // Full frame, clipped, should not discard.
1309 clip_rect
= gfx::Rect(10, 10, 10, 10);
1310 RenderPassId
root_pass_id(1, 0);
1311 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1315 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1316 root_pass
->damage_rect
= root_pass
->output_rect
;
1318 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1319 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1324 EXPECT_EQ(0, context
->discarded());
1328 // Full frame, doesn't cover the surface, should not discard.
1329 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1330 RenderPassId
root_pass_id(1, 0);
1331 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1335 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1336 root_pass
->damage_rect
= root_pass
->output_rect
;
1338 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1339 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1344 EXPECT_EQ(0, context
->discarded());
1348 // Full frame, doesn't cover the surface (no offset), should not discard.
1349 clip_rect
= gfx::Rect(100, 100);
1350 viewport_rect
= gfx::Rect(50, 50);
1351 RenderPassId
root_pass_id(1, 0);
1352 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1356 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1357 root_pass
->damage_rect
= root_pass
->output_rect
;
1359 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1360 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1365 EXPECT_EQ(0, context
->discarded());
1370 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1372 MOCK_METHOD4(viewport
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1373 MOCK_METHOD4(scissor
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1376 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1377 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1378 // and maintains a fixed size. This test verifies that glViewport and
1379 // glScissor's Y coordinate is flipped correctly in this environment, and that
1380 // the glViewport can be at a nonzero origin within the surface.
1381 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1382 new FlippedScissorAndViewportContext
);
1384 // We expect exactly one call to viewport on this context and exactly two
1385 // to scissor (one to scissor the clear, one to scissor the quad draw).
1386 EXPECT_CALL(*context_owned
, viewport(10, 390, 100, 100));
1387 EXPECT_CALL(*context_owned
, scissor(10, 390, 100, 100));
1388 EXPECT_CALL(*context_owned
, scissor(30, 450, 20, 20));
1390 FakeOutputSurfaceClient output_surface_client
;
1391 scoped_ptr
<OutputSurface
> output_surface(
1392 new NonReshapableOutputSurface(context_owned
.Pass()));
1393 CHECK(output_surface
->BindToClient(&output_surface_client
));
1395 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1396 new TestSharedBitmapManager());
1397 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1398 output_surface
.get(), shared_bitmap_manager
.get());
1400 RendererSettings settings
;
1401 FakeRendererClient renderer_client
;
1402 FakeRendererGL
renderer(&renderer_client
,
1404 output_surface
.get(),
1405 resource_provider
.get());
1406 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1408 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1409 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1410 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1412 RenderPassId
root_pass_id(1, 0);
1413 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1417 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1419 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1420 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1422 device_viewport_rect
,
1423 device_viewport_rect
,
1427 TEST_F(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1428 // When using render-to-FBO to display the surface, all rendering is done
1429 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1430 // the correct framebuffer during rendering, if changed.
1431 // Note: there is one path that will set it to 0, but that is after the render
1433 FakeOutputSurfaceClient output_surface_client
;
1434 scoped_ptr
<FakeOutputSurface
> output_surface(
1435 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1436 CHECK(output_surface
->BindToClient(&output_surface_client
));
1438 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1439 new TestSharedBitmapManager());
1440 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
1441 output_surface
.get(), shared_bitmap_manager
.get());
1443 RendererSettings settings
;
1444 FakeRendererClient renderer_client
;
1445 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1446 resource_provider
.get());
1447 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1449 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1450 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1451 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1453 RenderPassId
root_pass_id(1, 0);
1454 TestRenderPass
* root_pass
=
1455 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1457 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1460 gpu::gles2::GLES2Interface
* gl
=
1461 output_surface
->context_provider()->ContextGL();
1462 gl
->GenFramebuffers(1, &fbo
);
1463 output_surface
->set_framebuffer(fbo
);
1465 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1466 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1467 device_viewport_rect
, false);
1470 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1471 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1474 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1475 gfx::Rect
viewport_rect(1, 1);
1477 gfx::Rect
child_rect(50, 50);
1478 RenderPassId
child_pass_id(2, 0);
1479 TestRenderPass
* child_pass
;
1481 RenderPassId
root_pass_id(1, 0);
1482 TestRenderPass
* root_pass
;
1484 ResourceId mask
= resource_provider_
->CreateResource(
1485 gfx::Size(20, 12), GL_CLAMP_TO_EDGE
,
1486 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1487 resource_provider_
->best_texture_format());
1488 resource_provider_
->AllocateForTesting(mask
);
1490 SkScalar matrix
[20];
1491 float amount
= 0.5f
;
1492 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1493 matrix
[1] = 0.715f
- 0.715f
* amount
;
1494 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1495 matrix
[3] = matrix
[4] = 0;
1496 matrix
[5] = 0.213f
- 0.213f
* amount
;
1497 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1498 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1499 matrix
[8] = matrix
[9] = 0;
1500 matrix
[10] = 0.213f
- 0.213f
* amount
;
1501 matrix
[11] = 0.715f
- 0.715f
* amount
;
1502 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1503 matrix
[13] = matrix
[14] = 0;
1504 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1506 skia::RefPtr
<SkColorFilter
> color_filter(
1507 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1508 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1509 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1510 FilterOperations filters
;
1511 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1513 gfx::Transform transform_causing_aa
;
1514 transform_causing_aa
.Rotate(20.0);
1516 for (int i
= 0; i
<= LAST_BLEND_MODE
; ++i
) {
1517 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1518 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1519 settings_
.force_blending_with_shaders
= (blend_mode
!= BLEND_MODE_NONE
);
1520 // RenderPassProgram
1521 render_passes_in_draw_order_
.clear();
1522 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1527 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1532 AddRenderPassQuad(root_pass
,
1539 renderer_
->DecideRenderPassAllocationsForFrame(
1540 render_passes_in_draw_order_
);
1541 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1546 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1548 // RenderPassColorMatrixProgram
1549 render_passes_in_draw_order_
.clear();
1551 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1554 transform_causing_aa
);
1556 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1562 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1564 renderer_
->DecideRenderPassAllocationsForFrame(
1565 render_passes_in_draw_order_
);
1566 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1571 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1573 // RenderPassMaskProgram
1574 render_passes_in_draw_order_
.clear();
1576 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1581 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1586 AddRenderPassQuad(root_pass
,
1593 renderer_
->DecideRenderPassAllocationsForFrame(
1594 render_passes_in_draw_order_
);
1595 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1600 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1603 // RenderPassMaskColorMatrixProgram
1604 render_passes_in_draw_order_
.clear();
1606 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1611 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1617 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1619 renderer_
->DecideRenderPassAllocationsForFrame(
1620 render_passes_in_draw_order_
);
1621 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1626 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
,
1627 SAMPLER_TYPE_2D
, blend_mode
);
1629 // RenderPassProgramAA
1630 render_passes_in_draw_order_
.clear();
1632 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1635 transform_causing_aa
);
1637 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1642 AddRenderPassQuad(root_pass
,
1646 transform_causing_aa
,
1649 renderer_
->DecideRenderPassAllocationsForFrame(
1650 render_passes_in_draw_order_
);
1651 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1656 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1658 // RenderPassColorMatrixProgramAA
1659 render_passes_in_draw_order_
.clear();
1661 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1664 transform_causing_aa
);
1666 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1672 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1674 renderer_
->DecideRenderPassAllocationsForFrame(
1675 render_passes_in_draw_order_
);
1676 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1681 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1683 // RenderPassMaskProgramAA
1684 render_passes_in_draw_order_
.clear();
1686 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1689 transform_causing_aa
);
1691 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1696 AddRenderPassQuad(root_pass
,
1700 transform_causing_aa
,
1703 renderer_
->DecideRenderPassAllocationsForFrame(
1704 render_passes_in_draw_order_
);
1705 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1710 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1713 // RenderPassMaskColorMatrixProgramAA
1714 render_passes_in_draw_order_
.clear();
1716 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1719 transform_causing_aa
);
1721 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1724 transform_causing_aa
);
1727 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1729 renderer_
->DecideRenderPassAllocationsForFrame(
1730 render_passes_in_draw_order_
);
1731 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1736 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
,
1737 SAMPLER_TYPE_2D
, blend_mode
);
1741 // At this time, the AA code path cannot be taken if the surface's rect would
1742 // project incorrectly by the given transform, because of w<0 clipping.
1743 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1744 gfx::Rect
child_rect(50, 50);
1745 RenderPassId
child_pass_id(2, 0);
1746 TestRenderPass
* child_pass
;
1748 gfx::Rect
viewport_rect(1, 1);
1749 RenderPassId
root_pass_id(1, 0);
1750 TestRenderPass
* root_pass
;
1752 gfx::Transform transform_preventing_aa
;
1753 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1754 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1755 transform_preventing_aa
.Scale(30.0, 1.0);
1757 // Verify that the test transform and test rect actually do cause the clipped
1758 // flag to trigger. Otherwise we are not testing the intended scenario.
1759 bool clipped
= false;
1760 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1761 ASSERT_TRUE(clipped
);
1763 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1766 transform_preventing_aa
);
1768 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1773 AddRenderPassQuad(root_pass
,
1777 transform_preventing_aa
,
1778 SkXfermode::kSrcOver_Mode
);
1780 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1781 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1787 // If use_aa incorrectly ignores clipping, it will use the
1788 // RenderPassProgramAA shader instead of the RenderPassProgram.
1789 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, BLEND_MODE_NONE
);
1792 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1793 gfx::Rect
viewport_rect(1, 1);
1794 RenderPassId
root_pass_id(1, 0);
1795 TestRenderPass
* root_pass
;
1797 gfx::Transform pixel_aligned_transform_causing_aa
;
1798 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1799 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1801 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1805 AddTransformedQuad(root_pass
,
1808 pixel_aligned_transform_causing_aa
);
1810 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1811 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1817 TestSolidColorProgramAA();
1820 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1822 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1824 // Specifically override methods even if they are unused (used in conjunction
1825 // with StrictMock). We need to make sure that GLRenderer does not issue
1826 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1827 // through the OutputSurface abstraction.
1828 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1829 MOCK_METHOD3(reshapeWithScaleFactor
,
1830 void(int width
, int height
, float scale_factor
));
1831 MOCK_METHOD4(drawElements
,
1832 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1835 class MockOutputSurface
: public OutputSurface
{
1839 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1840 new StrictMock
<OutputSurfaceMockContext
>))) {
1841 surface_size_
= gfx::Size(100, 100);
1843 virtual ~MockOutputSurface() {}
1845 MOCK_METHOD0(EnsureBackbuffer
, void());
1846 MOCK_METHOD0(DiscardBackbuffer
, void());
1847 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1848 MOCK_METHOD0(BindFramebuffer
, void());
1849 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1852 class MockOutputSurfaceTest
: public GLRendererTest
{
1854 virtual void SetUp() {
1855 FakeOutputSurfaceClient output_surface_client_
;
1856 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1858 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1859 resource_provider_
= FakeResourceProvider::Create(
1860 &output_surface_
, shared_bitmap_manager_
.get());
1862 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1865 resource_provider_
.get()));
1868 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1870 void DrawFrame(float device_scale_factor
,
1871 const gfx::Rect
& device_viewport_rect
) {
1872 RenderPassId
render_pass_id(1, 0);
1873 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1875 device_viewport_rect
,
1877 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1879 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1881 EXPECT_CALL(output_surface_
,
1882 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1885 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1887 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1889 renderer_
->DecideRenderPassAllocationsForFrame(
1890 render_passes_in_draw_order_
);
1891 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1892 device_scale_factor
,
1893 device_viewport_rect
,
1894 device_viewport_rect
,
1898 OutputSurfaceMockContext
* Context() {
1899 return static_cast<OutputSurfaceMockContext
*>(
1900 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1904 RendererSettings settings_
;
1905 FakeOutputSurfaceClient output_surface_client_
;
1906 StrictMock
<MockOutputSurface
> output_surface_
;
1907 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1908 scoped_ptr
<ResourceProvider
> resource_provider_
;
1909 FakeRendererClient renderer_client_
;
1910 scoped_ptr
<FakeRendererGL
> renderer_
;
1913 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1914 gfx::Rect
device_viewport_rect(1, 1);
1915 DrawFrame(1.f
, device_viewport_rect
);
1917 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1918 renderer_
->SwapBuffers(CompositorFrameMetadata());
1921 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1922 gfx::Rect
device_viewport_rect(1, 1);
1924 DrawFrame(1.f
, device_viewport_rect
);
1925 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1926 renderer_
->SwapBuffers(CompositorFrameMetadata());
1928 device_viewport_rect
= gfx::Rect(2, 2);
1930 DrawFrame(2.f
, device_viewport_rect
);
1931 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1932 renderer_
->SwapBuffers(CompositorFrameMetadata());
1934 DrawFrame(2.f
, device_viewport_rect
);
1935 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1936 renderer_
->SwapBuffers(CompositorFrameMetadata());
1938 device_viewport_rect
= gfx::Rect(1, 1);
1940 DrawFrame(1.f
, device_viewport_rect
);
1941 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1942 renderer_
->SwapBuffers(CompositorFrameMetadata());
1945 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1947 static void SyncPointCallback(int* callback_count
) {
1948 ++(*callback_count
);
1949 base::MessageLoop::current()->QuitWhenIdle();
1952 static void OtherCallback(int* callback_count
) {
1953 ++(*callback_count
);
1954 base::MessageLoop::current()->QuitWhenIdle();
1958 #if !defined(OS_ANDROID)
1959 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1960 int sync_point_callback_count
= 0;
1961 int other_callback_count
= 0;
1962 gpu::gles2::GLES2Interface
* gl
=
1963 output_surface_
->context_provider()->ContextGL();
1964 gpu::ContextSupport
* context_support
=
1965 output_surface_
->context_provider()->ContextSupport();
1967 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1969 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1970 GL_INNOCENT_CONTEXT_RESET_ARB
);
1972 context_support
->SignalSyncPoint(
1973 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1974 EXPECT_EQ(0, sync_point_callback_count
);
1975 EXPECT_EQ(0, other_callback_count
);
1977 // Make the sync point happen.
1979 // Post a task after the sync point.
1980 base::ThreadTaskRunnerHandle::Get()->PostTask(
1981 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1983 base::MessageLoop::current()->Run();
1985 // The sync point shouldn't have happened since the context was lost.
1986 EXPECT_EQ(0, sync_point_callback_count
);
1987 EXPECT_EQ(1, other_callback_count
);
1990 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1991 int sync_point_callback_count
= 0;
1992 int other_callback_count
= 0;
1994 gpu::gles2::GLES2Interface
* gl
=
1995 output_surface_
->context_provider()->ContextGL();
1996 gpu::ContextSupport
* context_support
=
1997 output_surface_
->context_provider()->ContextSupport();
1999 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
2001 context_support
->SignalSyncPoint(
2002 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
2003 EXPECT_EQ(0, sync_point_callback_count
);
2004 EXPECT_EQ(0, other_callback_count
);
2006 // Make the sync point happen.
2008 // Post a task after the sync point.
2009 base::ThreadTaskRunnerHandle::Get()->PostTask(
2010 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
2012 base::MessageLoop::current()->Run();
2014 // The sync point should have happened.
2015 EXPECT_EQ(1, sync_point_callback_count
);
2016 EXPECT_EQ(1, other_callback_count
);
2018 #endif // OS_ANDROID
2020 class TestOverlayProcessor
: public OverlayProcessor
{
2022 class Strategy
: public OverlayProcessor::Strategy
{
2025 ~Strategy() override
{}
2026 MOCK_METHOD2(Attempt
,
2027 bool(RenderPassList
* render_passes_in_draw_order
,
2028 OverlayCandidateList
* candidates
));
2031 explicit TestOverlayProcessor(OutputSurface
* surface
)
2032 : OverlayProcessor(surface
) {}
2033 ~TestOverlayProcessor() override
{}
2034 void Initialize() override
{
2035 strategy_
= new Strategy();
2036 strategies_
.push_back(scoped_ptr
<OverlayProcessor::Strategy
>(strategy_
));
2039 Strategy
* strategy_
;
2042 void MailboxReleased(unsigned sync_point
,
2044 BlockingTaskRunner
* main_thread_task_runner
) {
2047 void IgnoreCopyResult(scoped_ptr
<CopyOutputResult
> result
) {
2050 TEST_F(GLRendererTest
, DontOverlayWithCopyRequests
) {
2051 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
2052 FakeOutputSurfaceClient output_surface_client
;
2053 scoped_ptr
<OutputSurface
> output_surface(
2054 FakeOutputSurface::Create3d(context_owned
.Pass()));
2055 CHECK(output_surface
->BindToClient(&output_surface_client
));
2057 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2058 new TestSharedBitmapManager());
2059 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2060 output_surface
.get(), shared_bitmap_manager
.get());
2061 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2062 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2064 RendererSettings settings
;
2065 FakeRendererClient renderer_client
;
2066 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2067 resource_provider
.get(), mailbox_deleter
.get());
2069 TestOverlayProcessor
* processor
=
2070 new TestOverlayProcessor(output_surface
.get());
2071 processor
->Initialize();
2072 renderer
.SetOverlayProcessor(processor
);
2074 gfx::Rect
viewport_rect(1, 1);
2075 TestRenderPass
* root_pass
=
2076 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2077 viewport_rect
, gfx::Transform());
2078 root_pass
->has_transparent_background
= false;
2079 root_pass
->copy_requests
.push_back(
2080 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult
)));
2082 unsigned sync_point
= 0;
2083 TextureMailbox mailbox
=
2084 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2085 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2086 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2087 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2088 mailbox
, release_callback
.Pass());
2089 bool premultiplied_alpha
= false;
2090 bool flipped
= false;
2091 bool nearest_neighbor
= false;
2092 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2094 TextureDrawQuad
* overlay_quad
=
2095 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2096 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2097 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2098 premultiplied_alpha
, gfx::PointF(0, 0),
2099 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2100 flipped
, nearest_neighbor
);
2101 overlay_quad
->set_allow_overlay(true);
2103 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2104 // Attempt will be called for each strategy in OverlayProcessor. We have
2105 // added a fake strategy, so checking for Attempt calls checks if there was
2106 // any attempt to overlay, which there shouldn't be. We can't use the quad
2107 // list because the render pass is cleaned up by DrawFrame.
2108 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(0);
2109 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2110 viewport_rect
, false);
2111 Mock::VerifyAndClearExpectations(processor
->strategy_
);
2113 // Without a copy request Attempt() should be called once.
2114 root_pass
= AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2115 viewport_rect
, gfx::Transform());
2116 root_pass
->has_transparent_background
= false;
2118 overlay_quad
= root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2119 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2120 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2121 premultiplied_alpha
, gfx::PointF(0, 0),
2122 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2123 flipped
, nearest_neighbor
);
2125 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(1);
2126 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2127 viewport_rect
, false);
2130 class SingleOverlayOnTopProcessor
: public OverlayProcessor
{
2132 class SingleOverlayValidator
: public OverlayCandidateValidator
{
2134 void CheckOverlaySupport(OverlayCandidateList
* surfaces
) override
{
2135 ASSERT_EQ(2U, surfaces
->size());
2136 OverlayCandidate
& candidate
= surfaces
->back();
2137 candidate
.overlay_handled
= true;
2141 explicit SingleOverlayOnTopProcessor(OutputSurface
* surface
)
2142 : OverlayProcessor(surface
) {}
2144 void Initialize() override
{
2145 strategies_
.push_back(
2146 scoped_ptr
<Strategy
>(new OverlayStrategySingleOnTop(&validator_
)));
2149 SingleOverlayValidator validator_
;
2152 class WaitSyncPointCountingContext
: public TestWebGraphicsContext3D
{
2154 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
2157 class MockOverlayScheduler
{
2159 MOCK_METHOD5(Schedule
,
2160 void(int plane_z_order
,
2161 gfx::OverlayTransform plane_transform
,
2162 unsigned overlay_texture_id
,
2163 const gfx::Rect
& display_bounds
,
2164 const gfx::RectF
& uv_rect
));
2167 TEST_F(GLRendererTest
, OverlaySyncPointsAreProcessed
) {
2168 scoped_ptr
<WaitSyncPointCountingContext
> context_owned(
2169 new WaitSyncPointCountingContext
);
2170 WaitSyncPointCountingContext
* context
= context_owned
.get();
2172 MockOverlayScheduler overlay_scheduler
;
2173 scoped_refptr
<TestContextProvider
> context_provider
=
2174 TestContextProvider::Create(context_owned
.Pass());
2175 context_provider
->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2176 &MockOverlayScheduler::Schedule
, base::Unretained(&overlay_scheduler
)));
2178 FakeOutputSurfaceClient output_surface_client
;
2179 scoped_ptr
<OutputSurface
> output_surface(
2180 FakeOutputSurface::Create3d(context_provider
));
2181 CHECK(output_surface
->BindToClient(&output_surface_client
));
2183 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2184 new TestSharedBitmapManager());
2185 scoped_ptr
<ResourceProvider
> resource_provider
= FakeResourceProvider::Create(
2186 output_surface
.get(), shared_bitmap_manager
.get());
2187 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2188 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2190 RendererSettings settings
;
2191 FakeRendererClient renderer_client
;
2192 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2193 resource_provider
.get(), mailbox_deleter
.get());
2195 SingleOverlayOnTopProcessor
* processor
=
2196 new SingleOverlayOnTopProcessor(output_surface
.get());
2197 processor
->Initialize();
2198 renderer
.SetOverlayProcessor(processor
);
2200 gfx::Rect
viewport_rect(1, 1);
2201 TestRenderPass
* root_pass
=
2202 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2203 viewport_rect
, gfx::Transform());
2204 root_pass
->has_transparent_background
= false;
2206 unsigned sync_point
= TestRenderPass::kSyncPointForMailboxTextureQuad
;
2207 TextureMailbox mailbox
=
2208 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2209 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2210 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2211 ResourceId resource_id
= resource_provider
->CreateResourceFromTextureMailbox(
2212 mailbox
, release_callback
.Pass());
2213 bool premultiplied_alpha
= false;
2214 bool flipped
= false;
2215 bool nearest_neighbor
= false;
2216 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2217 gfx::PointF
uv_top_left(0, 0);
2218 gfx::PointF
uv_bottom_right(1, 1);
2220 TextureDrawQuad
* overlay_quad
=
2221 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2222 SharedQuadState
* shared_state
= root_pass
->CreateAndAppendSharedQuadState();
2223 shared_state
->SetAll(gfx::Transform(), viewport_rect
.size(), viewport_rect
,
2224 viewport_rect
, false, 1, SkXfermode::kSrcOver_Mode
, 0);
2225 overlay_quad
->SetNew(shared_state
, viewport_rect
, viewport_rect
,
2226 viewport_rect
, resource_id
, premultiplied_alpha
,
2227 uv_top_left
, uv_bottom_right
, SK_ColorTRANSPARENT
,
2228 vertex_opacity
, flipped
, nearest_neighbor
);
2229 overlay_quad
->set_allow_overlay(true);
2231 // Verify that overlay_quad actually gets turned into an overlay, and even
2232 // though it's not drawn, that its sync point is waited on.
2233 EXPECT_CALL(*context
,
2234 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
2236 EXPECT_CALL(overlay_scheduler
,
2237 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE
, _
, viewport_rect
,
2238 BoundingRect(uv_top_left
, uv_bottom_right
))).Times(1);
2240 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2241 viewport_rect
, false);