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/quads/texture_draw_quad.h"
17 #include "cc/resources/resource_provider.h"
18 #include "cc/resources/texture_mailbox_deleter.h"
19 #include "cc/test/fake_impl_proxy.h"
20 #include "cc/test/fake_layer_tree_host_impl.h"
21 #include "cc/test/fake_output_surface.h"
22 #include "cc/test/fake_output_surface_client.h"
23 #include "cc/test/fake_renderer_client.h"
24 #include "cc/test/pixel_test.h"
25 #include "cc/test/render_pass_test_common.h"
26 #include "cc/test/render_pass_test_utils.h"
27 #include "cc/test/test_shared_bitmap_manager.h"
28 #include "cc/test/test_web_graphics_context_3d.h"
29 #include "gpu/GLES2/gl2extchromium.h"
30 #include "gpu/command_buffer/client/context_support.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/skia/include/core/SkImageFilter.h"
34 #include "third_party/skia/include/core/SkMatrix.h"
35 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
36 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
37 #include "ui/gfx/transform.h"
40 using testing::AnyNumber
;
42 using testing::AtLeast
;
43 using testing::ElementsAre
;
44 using testing::Expectation
;
45 using testing::InSequence
;
47 using testing::Return
;
48 using testing::StrictMock
;
52 class GLRendererTest
: public testing::Test
{
54 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
56 RenderPassList render_passes_in_draw_order_
;
59 #define EXPECT_PROGRAM_VALID(program_binding) \
61 EXPECT_TRUE((program_binding)->program()); \
62 EXPECT_TRUE((program_binding)->initialized()); \
65 static inline SkXfermode::Mode
BlendModeToSkXfermode(BlendMode blend_mode
) {
68 case BLEND_MODE_NORMAL
:
69 return SkXfermode::kSrcOver_Mode
;
70 case BLEND_MODE_SCREEN
:
71 return SkXfermode::kScreen_Mode
;
72 case BLEND_MODE_OVERLAY
:
73 return SkXfermode::kOverlay_Mode
;
74 case BLEND_MODE_DARKEN
:
75 return SkXfermode::kDarken_Mode
;
76 case BLEND_MODE_LIGHTEN
:
77 return SkXfermode::kLighten_Mode
;
78 case BLEND_MODE_COLOR_DODGE
:
79 return SkXfermode::kColorDodge_Mode
;
80 case BLEND_MODE_COLOR_BURN
:
81 return SkXfermode::kColorBurn_Mode
;
82 case BLEND_MODE_HARD_LIGHT
:
83 return SkXfermode::kHardLight_Mode
;
84 case BLEND_MODE_SOFT_LIGHT
:
85 return SkXfermode::kSoftLight_Mode
;
86 case BLEND_MODE_DIFFERENCE
:
87 return SkXfermode::kDifference_Mode
;
88 case BLEND_MODE_EXCLUSION
:
89 return SkXfermode::kExclusion_Mode
;
90 case BLEND_MODE_MULTIPLY
:
91 return SkXfermode::kMultiply_Mode
;
93 return SkXfermode::kHue_Mode
;
94 case BLEND_MODE_SATURATION
:
95 return SkXfermode::kSaturation_Mode
;
96 case BLEND_MODE_COLOR
:
97 return SkXfermode::kColor_Mode
;
98 case BLEND_MODE_LUMINOSITY
:
99 return SkXfermode::kLuminosity_Mode
;
101 return SkXfermode::kSrcOver_Mode
;
104 // Explicitly named to be a friend in GLRenderer for shader access.
105 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
107 void SetUp() override
{
108 GLRendererPixelTest::SetUp();
109 ASSERT_FALSE(renderer()->IsContextLost());
112 void TearDown() override
{
113 GLRendererPixelTest::TearDown();
114 ASSERT_FALSE(renderer()->IsContextLost());
117 void TestBasicShaders() {
118 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
119 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
120 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
124 void TestShadersWithPrecision(TexCoordPrecision precision
) {
125 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
));
126 EXPECT_PROGRAM_VALID(
127 renderer()->GetNonPremultipliedTextureProgram(precision
));
128 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision
));
129 EXPECT_PROGRAM_VALID(
130 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
));
131 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
132 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
));
133 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
));
134 if (renderer()->Capabilities().using_egl_image
)
135 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
137 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
140 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision
,
141 BlendMode blend_mode
) {
142 EXPECT_PROGRAM_VALID(
143 renderer()->GetRenderPassProgram(precision
, blend_mode
));
144 EXPECT_PROGRAM_VALID(
145 renderer()->GetRenderPassProgramAA(precision
, blend_mode
));
148 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision
,
149 SamplerType sampler
) {
150 if (!renderer()->Capabilities().using_egl_image
&&
151 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
152 // This will likely be hit in tests due to usage of osmesa.
156 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
157 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
158 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
160 EXPECT_PROGRAM_VALID(
161 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
162 EXPECT_PROGRAM_VALID(
163 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
166 void TestShadersWithMasks(TexCoordPrecision precision
,
168 BlendMode blend_mode
,
169 bool mask_for_background
) {
170 if (!renderer()->Capabilities().using_egl_image
&&
171 sampler
== SAMPLER_TYPE_EXTERNAL_OES
) {
172 // This will likely be hit in tests due to usage of osmesa.
176 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
177 precision
, sampler
, blend_mode
, mask_for_background
));
178 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
179 precision
, sampler
, blend_mode
, mask_for_background
));
180 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
181 precision
, sampler
, blend_mode
, mask_for_background
));
182 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
183 precision
, sampler
, blend_mode
, mask_for_background
));
189 #if !defined(OS_ANDROID) && !defined(OS_WIN)
190 static const TexCoordPrecision kPrecisionList
[] = {TEX_COORD_PRECISION_MEDIUM
,
191 TEX_COORD_PRECISION_HIGH
};
193 static const BlendMode kBlendModeList
[LAST_BLEND_MODE
+ 1] = {
200 BLEND_MODE_COLOR_DODGE
,
201 BLEND_MODE_COLOR_BURN
,
202 BLEND_MODE_HARD_LIGHT
,
203 BLEND_MODE_SOFT_LIGHT
,
204 BLEND_MODE_DIFFERENCE
,
205 BLEND_MODE_EXCLUSION
,
208 BLEND_MODE_SATURATION
,
210 BLEND_MODE_LUMINOSITY
,
213 static const SamplerType kSamplerList
[] = {
215 SAMPLER_TYPE_2D_RECT
,
216 SAMPLER_TYPE_EXTERNAL_OES
,
219 TEST_F(GLRendererShaderPixelTest
, BasicShadersCompile
) {
223 class PrecisionShaderPixelTest
224 : public GLRendererShaderPixelTest
,
225 public ::testing::WithParamInterface
<TexCoordPrecision
> {};
227 TEST_P(PrecisionShaderPixelTest
, ShadersCompile
) {
228 TestShadersWithPrecision(GetParam());
231 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile
,
232 PrecisionShaderPixelTest
,
233 ::testing::ValuesIn(kPrecisionList
));
235 class PrecisionBlendShaderPixelTest
236 : public GLRendererShaderPixelTest
,
237 public ::testing::WithParamInterface
<
238 std::tr1::tuple
<TexCoordPrecision
, BlendMode
>> {};
240 TEST_P(PrecisionBlendShaderPixelTest
, ShadersCompile
) {
241 TestShadersWithPrecisionAndBlend(std::tr1::get
<0>(GetParam()),
242 std::tr1::get
<1>(GetParam()));
245 INSTANTIATE_TEST_CASE_P(
246 PrecisionBlendShadersCompile
,
247 PrecisionBlendShaderPixelTest
,
248 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
249 ::testing::ValuesIn(kBlendModeList
)));
251 class PrecisionSamplerShaderPixelTest
252 : public GLRendererShaderPixelTest
,
253 public ::testing::WithParamInterface
<
254 std::tr1::tuple
<TexCoordPrecision
, SamplerType
>> {};
256 TEST_P(PrecisionSamplerShaderPixelTest
, ShadersCompile
) {
257 TestShadersWithPrecisionAndSampler(std::tr1::get
<0>(GetParam()),
258 std::tr1::get
<1>(GetParam()));
261 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile
,
262 PrecisionSamplerShaderPixelTest
,
263 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
264 ::testing::ValuesIn(kSamplerList
)));
266 class MaskShaderPixelTest
267 : public GLRendererShaderPixelTest
,
268 public ::testing::WithParamInterface
<
269 std::tr1::tuple
<TexCoordPrecision
, SamplerType
, BlendMode
, bool>> {};
271 TEST_P(MaskShaderPixelTest
, ShadersCompile
) {
272 TestShadersWithMasks(
273 std::tr1::get
<0>(GetParam()), std::tr1::get
<1>(GetParam()),
274 std::tr1::get
<2>(GetParam()), std::tr1::get
<3>(GetParam()));
277 INSTANTIATE_TEST_CASE_P(MaskShadersCompile
,
279 ::testing::Combine(::testing::ValuesIn(kPrecisionList
),
280 ::testing::ValuesIn(kSamplerList
),
281 ::testing::ValuesIn(kBlendModeList
),
286 class FakeRendererGL
: public GLRenderer
{
288 FakeRendererGL(RendererClient
* client
,
289 const RendererSettings
* settings
,
290 OutputSurface
* output_surface
,
291 ResourceProvider
* resource_provider
)
299 FakeRendererGL(RendererClient
* client
,
300 const RendererSettings
* settings
,
301 OutputSurface
* output_surface
,
302 ResourceProvider
* resource_provider
,
303 TextureMailboxDeleter
* texture_mailbox_deleter
)
308 texture_mailbox_deleter
,
311 void SetOverlayProcessor(OverlayProcessor
* processor
) {
312 overlay_processor_
.reset(processor
);
315 // GLRenderer methods.
317 // Changing visibility to public.
318 using GLRenderer::IsBackbufferDiscarded
;
319 using GLRenderer::DoDrawQuad
;
320 using GLRenderer::BeginDrawingFrame
;
321 using GLRenderer::FinishDrawingQuadList
;
322 using GLRenderer::stencil_enabled
;
325 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
327 GLRendererWithDefaultHarnessTest() {
329 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
330 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
332 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
333 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
334 shared_bitmap_manager_
.get(),
340 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
342 output_surface_
.get(),
343 resource_provider_
.get()));
346 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
348 RendererSettings settings_
;
349 FakeOutputSurfaceClient output_surface_client_
;
350 scoped_ptr
<FakeOutputSurface
> output_surface_
;
351 FakeRendererClient renderer_client_
;
352 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
353 scoped_ptr
<ResourceProvider
> resource_provider_
;
354 scoped_ptr
<FakeRendererGL
> renderer_
;
357 // Closing the namespace here so that GLRendererShaderTest can take advantage
358 // of the friend relationship with GLRenderer and all of the mock classes
359 // declared above it.
362 class GLRendererShaderTest
: public GLRendererTest
{
364 GLRendererShaderTest() {
365 output_surface_
= FakeOutputSurface::Create3d().Pass();
366 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
368 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
369 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
370 shared_bitmap_manager_
.get(),
376 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
378 output_surface_
.get(),
379 resource_provider_
.get()));
382 void TestRenderPassProgram(TexCoordPrecision precision
,
383 BlendMode blend_mode
) {
384 EXPECT_PROGRAM_VALID(
385 &renderer_
->render_pass_program_
[precision
][blend_mode
]);
386 EXPECT_EQ(renderer_
->render_pass_program_
[precision
][blend_mode
].program(),
387 renderer_
->program_shadow_
);
390 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
,
391 BlendMode blend_mode
) {
392 EXPECT_PROGRAM_VALID(
393 &renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]);
395 renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]
397 renderer_
->program_shadow_
);
400 void TestRenderPassMaskProgram(TexCoordPrecision precision
,
402 BlendMode blend_mode
) {
403 EXPECT_PROGRAM_VALID(
404 &renderer_
->render_pass_mask_program_
[precision
]
409 renderer_
->render_pass_mask_program_
[precision
]
413 renderer_
->program_shadow_
);
416 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
,
418 BlendMode blend_mode
) {
419 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_
420 [precision
][sampler
][blend_mode
][NO_MASK
]);
421 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_
422 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
423 renderer_
->program_shadow_
);
426 void TestRenderPassProgramAA(TexCoordPrecision precision
,
427 BlendMode blend_mode
) {
428 EXPECT_PROGRAM_VALID(
429 &renderer_
->render_pass_program_aa_
[precision
][blend_mode
]);
431 renderer_
->render_pass_program_aa_
[precision
][blend_mode
].program(),
432 renderer_
->program_shadow_
);
435 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
,
436 BlendMode blend_mode
) {
437 EXPECT_PROGRAM_VALID(
439 ->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]);
441 renderer_
->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]
443 renderer_
->program_shadow_
);
446 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
,
448 BlendMode blend_mode
) {
449 EXPECT_PROGRAM_VALID(
451 ->render_pass_mask_program_aa_
452 [precision
][sampler
][blend_mode
][NO_MASK
]);
454 renderer_
->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]
456 renderer_
->program_shadow_
);
459 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
,
461 BlendMode blend_mode
) {
462 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_aa_
463 [precision
][sampler
][blend_mode
][NO_MASK
]);
464 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
465 [precision
][sampler
][blend_mode
][NO_MASK
].program(),
466 renderer_
->program_shadow_
);
469 void TestSolidColorProgramAA() {
470 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
471 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
472 renderer_
->program_shadow_
);
475 RendererSettings settings_
;
476 FakeOutputSurfaceClient output_surface_client_
;
477 scoped_ptr
<FakeOutputSurface
> output_surface_
;
478 FakeRendererClient renderer_client_
;
479 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
480 scoped_ptr
<ResourceProvider
> resource_provider_
;
481 scoped_ptr
<FakeRendererGL
> renderer_
;
486 // Test GLRenderer DiscardBackbuffer functionality:
487 // Suggest discarding framebuffer when one exists and the renderer is not
489 // Expected: it is discarded and damage tracker is reset.
491 GLRendererWithDefaultHarnessTest
,
492 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
493 renderer_
->SetVisible(false);
494 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
495 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
498 // Test GLRenderer DiscardBackbuffer functionality:
499 // Suggest discarding framebuffer when one exists and the renderer is visible.
500 // Expected: the allocation is ignored.
501 TEST_F(GLRendererWithDefaultHarnessTest
,
502 SuggestBackbufferNoDoNothingWhenVisible
) {
503 renderer_
->SetVisible(true);
504 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
505 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
508 // Test GLRenderer DiscardBackbuffer functionality:
509 // Suggest discarding framebuffer when one does not exist.
510 // Expected: it does nothing.
511 TEST_F(GLRendererWithDefaultHarnessTest
,
512 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
513 renderer_
->SetVisible(false);
514 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
515 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
517 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
518 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
521 // Test GLRenderer DiscardBackbuffer functionality:
522 // Begin drawing a frame while a framebuffer is discarded.
523 // Expected: will recreate framebuffer.
524 TEST_F(GLRendererWithDefaultHarnessTest
,
525 DiscardedBackbufferIsRecreatedForScopeDuration
) {
526 gfx::Rect
viewport_rect(1, 1);
527 renderer_
->SetVisible(false);
528 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
529 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
531 AddRenderPass(&render_passes_in_draw_order_
,
536 renderer_
->SetVisible(true);
537 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
542 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
545 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
548 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
549 gfx::Rect
viewport_rect(1, 1);
550 EXPECT_FALSE(renderer_
->stencil_enabled());
552 output_surface_
->set_has_external_stencil_test(true);
554 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
558 root_pass
->has_transparent_background
= false;
560 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
565 EXPECT_TRUE(renderer_
->stencil_enabled());
568 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
570 ForbidSynchronousCallContext() {}
572 void getAttachedShaders(GLuint program
,
575 GLuint
* shaders
) override
{
578 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
582 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
583 void getBufferParameteriv(GLenum target
,
585 GLint
* value
) override
{
588 GLenum
getError() override
{
592 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
593 void getFramebufferAttachmentParameteriv(GLenum target
,
596 GLint
* value
) override
{
599 void getIntegerv(GLenum pname
, GLint
* value
) override
{
600 if (pname
== GL_MAX_TEXTURE_SIZE
) {
601 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
608 // We allow querying the shader compilation and program link status in debug
609 // mode, but not release.
610 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
618 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
626 void getRenderbufferParameteriv(GLenum target
,
628 GLint
* value
) override
{
632 void getShaderPrecisionFormat(GLenum shadertype
,
633 GLenum precisiontype
,
635 GLint
* precision
) override
{
638 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
641 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
644 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
647 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
650 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
654 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
657 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
660 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
665 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
666 FakeOutputSurfaceClient output_surface_client
;
667 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
668 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
669 CHECK(output_surface
->BindToClient(&output_surface_client
));
671 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
672 new TestSharedBitmapManager());
673 scoped_ptr
<ResourceProvider
> resource_provider(
674 ResourceProvider::Create(output_surface
.get(),
675 shared_bitmap_manager
.get(),
682 RendererSettings settings
;
683 FakeRendererClient renderer_client
;
684 FakeRendererGL
renderer(&renderer_client
,
686 output_surface
.get(),
687 resource_provider
.get());
690 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
692 LoseContextOnFirstGetContext() {}
694 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
695 context_lost_
= true;
699 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
700 context_lost_
= true;
705 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
706 FakeOutputSurfaceClient output_surface_client
;
707 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
708 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
709 CHECK(output_surface
->BindToClient(&output_surface_client
));
711 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
712 new TestSharedBitmapManager());
713 scoped_ptr
<ResourceProvider
> resource_provider(
714 ResourceProvider::Create(output_surface
.get(),
715 shared_bitmap_manager
.get(),
722 RendererSettings settings
;
723 FakeRendererClient renderer_client
;
724 FakeRendererGL
renderer(&renderer_client
,
726 output_surface
.get(),
727 resource_provider
.get());
730 class ClearCountingContext
: public TestWebGraphicsContext3D
{
732 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
734 MOCK_METHOD3(discardFramebufferEXT
,
736 GLsizei numAttachments
,
737 const GLenum
* attachments
));
738 MOCK_METHOD1(clear
, void(GLbitfield mask
));
741 TEST_F(GLRendererTest
, OpaqueBackground
) {
742 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
743 ClearCountingContext
* context
= context_owned
.get();
745 FakeOutputSurfaceClient output_surface_client
;
746 scoped_ptr
<OutputSurface
> output_surface(
747 FakeOutputSurface::Create3d(context_owned
.Pass()));
748 CHECK(output_surface
->BindToClient(&output_surface_client
));
750 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
751 new TestSharedBitmapManager());
752 scoped_ptr
<ResourceProvider
> resource_provider(
753 ResourceProvider::Create(output_surface
.get(),
754 shared_bitmap_manager
.get(),
761 RendererSettings settings
;
762 FakeRendererClient renderer_client
;
763 FakeRendererGL
renderer(&renderer_client
,
765 output_surface
.get(),
766 resource_provider
.get());
768 gfx::Rect
viewport_rect(1, 1);
769 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
773 root_pass
->has_transparent_background
= false;
775 // On DEBUG builds, render passes with opaque background clear to blue to
776 // easily see regions that were not drawn on the screen.
777 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
778 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
781 EXPECT_CALL(*context
, clear(_
)).Times(0);
783 EXPECT_CALL(*context
, clear(_
)).Times(1);
785 renderer
.DrawFrame(&render_passes_in_draw_order_
,
790 Mock::VerifyAndClearExpectations(context
);
793 TEST_F(GLRendererTest
, TransparentBackground
) {
794 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
795 ClearCountingContext
* context
= context_owned
.get();
797 FakeOutputSurfaceClient output_surface_client
;
798 scoped_ptr
<OutputSurface
> output_surface(
799 FakeOutputSurface::Create3d(context_owned
.Pass()));
800 CHECK(output_surface
->BindToClient(&output_surface_client
));
802 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
803 new TestSharedBitmapManager());
804 scoped_ptr
<ResourceProvider
> resource_provider(
805 ResourceProvider::Create(output_surface
.get(),
806 shared_bitmap_manager
.get(),
813 RendererSettings settings
;
814 FakeRendererClient renderer_client
;
815 FakeRendererGL
renderer(&renderer_client
,
817 output_surface
.get(),
818 resource_provider
.get());
820 gfx::Rect
viewport_rect(1, 1);
821 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
825 root_pass
->has_transparent_background
= true;
827 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
828 EXPECT_CALL(*context
, clear(_
)).Times(1);
829 renderer
.DrawFrame(&render_passes_in_draw_order_
,
835 Mock::VerifyAndClearExpectations(context
);
838 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
839 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
840 ClearCountingContext
* context
= context_owned
.get();
842 FakeOutputSurfaceClient output_surface_client
;
843 scoped_ptr
<OutputSurface
> output_surface(
844 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
845 CHECK(output_surface
->BindToClient(&output_surface_client
));
847 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
848 new TestSharedBitmapManager());
849 scoped_ptr
<ResourceProvider
> resource_provider(
850 ResourceProvider::Create(output_surface
.get(),
851 shared_bitmap_manager
.get(),
858 RendererSettings settings
;
859 FakeRendererClient renderer_client
;
860 FakeRendererGL
renderer(&renderer_client
,
862 output_surface
.get(),
863 resource_provider
.get());
865 gfx::Rect
viewport_rect(1, 1);
866 AddRenderPass(&render_passes_in_draw_order_
,
871 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
872 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
874 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
875 renderer
.DrawFrame(&render_passes_in_draw_order_
,
880 Mock::VerifyAndClearExpectations(context
);
883 class VisibilityChangeIsLastCallTrackingContext
884 : public TestWebGraphicsContext3D
{
886 VisibilityChangeIsLastCallTrackingContext()
887 : last_call_was_set_visibility_(false) {}
889 // TestWebGraphicsContext3D methods.
890 void flush() override
{ last_call_was_set_visibility_
= false; }
891 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
892 void deleteFramebuffer(GLuint
) override
{
893 last_call_was_set_visibility_
= false;
895 void deleteQueryEXT(GLuint
) override
{
896 last_call_was_set_visibility_
= false;
898 void deleteRenderbuffer(GLuint
) override
{
899 last_call_was_set_visibility_
= false;
902 // Methods added for test.
903 void set_last_call_was_visibility(bool visible
) {
904 DCHECK(last_call_was_set_visibility_
== false);
905 last_call_was_set_visibility_
= true;
907 bool last_call_was_set_visibility() const {
908 return last_call_was_set_visibility_
;
912 bool last_call_was_set_visibility_
;
915 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
916 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
917 new VisibilityChangeIsLastCallTrackingContext
);
918 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
920 scoped_refptr
<TestContextProvider
> provider
=
921 TestContextProvider::Create(context_owned
.Pass());
923 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
924 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
925 base::Unretained(context
)));
927 FakeOutputSurfaceClient output_surface_client
;
928 scoped_ptr
<OutputSurface
> output_surface(
929 FakeOutputSurface::Create3d(provider
));
930 CHECK(output_surface
->BindToClient(&output_surface_client
));
932 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
933 new TestSharedBitmapManager());
934 scoped_ptr
<ResourceProvider
> resource_provider(
935 ResourceProvider::Create(output_surface
.get(),
936 shared_bitmap_manager
.get(),
943 RendererSettings settings
;
944 FakeRendererClient renderer_client
;
945 FakeRendererGL
renderer(&renderer_client
,
947 output_surface
.get(),
948 resource_provider
.get());
950 gfx::Rect
viewport_rect(1, 1);
951 AddRenderPass(&render_passes_in_draw_order_
,
956 // Ensure that the call to SetSurfaceVisible is the last call issue to the
957 // GPU process, after glFlush is called, and after the RendererClient's
958 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
959 // RenderClient and the Context by giving them both a pointer to a variable on
961 renderer
.SetVisible(true);
962 renderer
.DrawFrame(&render_passes_in_draw_order_
,
967 renderer
.SetVisible(false);
968 EXPECT_TRUE(context
->last_call_was_set_visibility());
971 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
973 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
974 test_capabilities_
.gpu
.egl_image_external
= true;
977 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
978 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
979 MOCK_METHOD4(drawElements
,
980 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
982 virtual void activeTexture(GLenum texture
) {
983 EXPECT_NE(texture
, active_texture_
);
984 active_texture_
= texture
;
987 GLenum
active_texture() const { return active_texture_
; }
990 GLenum active_texture_
;
993 TEST_F(GLRendererTest
, ActiveTextureState
) {
994 scoped_ptr
<TextureStateTrackingContext
> context_owned(
995 new TextureStateTrackingContext
);
996 TextureStateTrackingContext
* context
= context_owned
.get();
998 FakeOutputSurfaceClient output_surface_client
;
999 scoped_ptr
<OutputSurface
> output_surface(
1000 FakeOutputSurface::Create3d(context_owned
.Pass()));
1001 CHECK(output_surface
->BindToClient(&output_surface_client
));
1003 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1004 new TestSharedBitmapManager());
1005 scoped_ptr
<ResourceProvider
> resource_provider(
1006 ResourceProvider::Create(output_surface
.get(),
1007 shared_bitmap_manager
.get(),
1014 RendererSettings settings
;
1015 FakeRendererClient renderer_client
;
1016 FakeRendererGL
renderer(&renderer_client
,
1018 output_surface
.get(),
1019 resource_provider
.get());
1021 // During initialization we are allowed to set any texture parameters.
1022 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
1024 TestRenderPass
* root_pass
=
1025 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 1),
1026 gfx::Rect(100, 100), gfx::Transform());
1027 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
1028 RenderPassId(0, 0));
1030 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1032 // Set up expected texture filter state transitions that match the quads
1033 // created in AppendOneOfEveryQuadType().
1034 Mock::VerifyAndClearExpectations(context
);
1036 InSequence sequence
;
1038 // The sync points for all quads are waited on first. This sync point is
1039 // for a texture quad drawn later in the frame.
1040 EXPECT_CALL(*context
,
1041 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
1044 // yuv_quad is drawn with the default linear filter.
1045 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1047 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1051 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
1054 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
1055 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1057 // transformed_tile_quad uses GL_LINEAR.
1058 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1060 // scaled_tile_quad also uses GL_LINEAR.
1061 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
1063 // The remaining quads also use GL_LINEAR because nearest neighbor
1064 // filtering is currently only used with tile quads.
1065 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(7);
1068 gfx::Rect
viewport_rect(100, 100);
1069 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1074 Mock::VerifyAndClearExpectations(context
);
1077 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
1079 MOCK_METHOD1(clear
, void(GLbitfield mask
));
1080 MOCK_METHOD4(drawElements
,
1081 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1084 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
1085 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
1086 new NoClearRootRenderPassMockContext
);
1087 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
1089 FakeOutputSurfaceClient output_surface_client
;
1090 scoped_ptr
<OutputSurface
> output_surface(
1091 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
1092 CHECK(output_surface
->BindToClient(&output_surface_client
));
1094 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1095 new TestSharedBitmapManager());
1096 scoped_ptr
<ResourceProvider
> resource_provider(
1097 ResourceProvider::Create(output_surface
.get(),
1098 shared_bitmap_manager
.get(),
1105 RendererSettings settings
;
1106 settings
.should_clear_root_render_pass
= false;
1108 FakeRendererClient renderer_client
;
1109 FakeRendererGL
renderer(&renderer_client
,
1111 output_surface
.get(),
1112 resource_provider
.get());
1114 gfx::Rect
viewport_rect(10, 10);
1116 RenderPassId
child_pass_id(2, 0);
1117 TestRenderPass
* child_pass
=
1118 AddRenderPass(&render_passes_in_draw_order_
, child_pass_id
, viewport_rect
,
1120 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
1122 RenderPassId
root_pass_id(1, 0);
1123 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1127 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1130 AddRenderPassQuad(root_pass
, child_pass
);
1133 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
1135 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1138 // First render pass is not the root one, clearing should happen.
1139 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1141 Expectation first_render_pass
=
1142 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1144 // The second render pass is the root one, clearing should be prevented.
1145 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1148 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1151 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1152 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1158 // In multiple render passes all but the root pass should clear the
1160 Mock::VerifyAndClearExpectations(&mock_context
);
1163 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1165 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1167 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1169 void enable(GLenum cap
) override
{
1170 if (cap
== GL_SCISSOR_TEST
)
1171 scissor_enabled_
= true;
1174 void disable(GLenum cap
) override
{
1175 if (cap
== GL_SCISSOR_TEST
)
1176 scissor_enabled_
= false;
1180 bool scissor_enabled_
;
1183 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1184 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1185 new ScissorTestOnClearCheckingContext
);
1187 FakeOutputSurfaceClient output_surface_client
;
1188 scoped_ptr
<OutputSurface
> output_surface(
1189 FakeOutputSurface::Create3d(context_owned
.Pass()));
1190 CHECK(output_surface
->BindToClient(&output_surface_client
));
1192 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1193 new TestSharedBitmapManager());
1194 scoped_ptr
<ResourceProvider
> resource_provider(
1195 ResourceProvider::Create(output_surface
.get(),
1196 shared_bitmap_manager
.get(),
1203 RendererSettings settings
;
1204 FakeRendererClient renderer_client
;
1205 FakeRendererGL
renderer(&renderer_client
,
1207 output_surface
.get(),
1208 resource_provider
.get());
1209 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1211 gfx::Rect
viewport_rect(1, 1);
1213 gfx::Rect
grand_child_rect(25, 25);
1214 RenderPassId
grand_child_pass_id(3, 0);
1215 TestRenderPass
* grand_child_pass
=
1216 AddRenderPass(&render_passes_in_draw_order_
,
1217 grand_child_pass_id
,
1220 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1222 gfx::Rect
child_rect(50, 50);
1223 RenderPassId
child_pass_id(2, 0);
1224 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1228 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1230 RenderPassId
root_pass_id(1, 0);
1231 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1235 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1237 AddRenderPassQuad(root_pass
, child_pass
);
1238 AddRenderPassQuad(child_pass
, grand_child_pass
);
1240 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1241 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1248 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1250 DiscardCheckingContext() : discarded_(0) {
1251 set_have_post_sub_buffer(true);
1252 set_have_discard_framebuffer(true);
1255 void discardFramebufferEXT(GLenum target
,
1256 GLsizei numAttachments
,
1257 const GLenum
* attachments
) override
{
1261 int discarded() const { return discarded_
; }
1262 void reset() { discarded_
= 0; }
1268 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1270 explicit NonReshapableOutputSurface(
1271 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1272 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1274 surface_size_
= gfx::Size(500, 500);
1276 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1277 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1280 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1281 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1282 DiscardCheckingContext
* context
= context_owned
.get();
1284 FakeOutputSurfaceClient output_surface_client
;
1285 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1286 new NonReshapableOutputSurface(context_owned
.Pass()));
1287 CHECK(output_surface
->BindToClient(&output_surface_client
));
1288 output_surface
->set_fixed_size(gfx::Size(100, 100));
1290 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1291 new TestSharedBitmapManager());
1292 scoped_ptr
<ResourceProvider
> resource_provider(
1293 ResourceProvider::Create(output_surface
.get(),
1294 shared_bitmap_manager
.get(),
1301 RendererSettings settings
;
1302 settings
.partial_swap_enabled
= true;
1303 FakeRendererClient renderer_client
;
1304 FakeRendererGL
renderer(&renderer_client
,
1306 output_surface
.get(),
1307 resource_provider
.get());
1308 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1310 gfx::Rect
viewport_rect(100, 100);
1311 gfx::Rect
clip_rect(100, 100);
1314 // Partial frame, should not discard.
1315 RenderPassId
root_pass_id(1, 0);
1316 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1320 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1321 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1323 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1324 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1329 EXPECT_EQ(0, context
->discarded());
1333 // Full frame, should discard.
1334 RenderPassId
root_pass_id(1, 0);
1335 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1339 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1340 root_pass
->damage_rect
= root_pass
->output_rect
;
1342 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1343 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1348 EXPECT_EQ(1, context
->discarded());
1352 // Full frame, external scissor is set, should not discard.
1353 output_surface
->set_has_external_stencil_test(true);
1354 RenderPassId
root_pass_id(1, 0);
1355 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1359 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1360 root_pass
->damage_rect
= root_pass
->output_rect
;
1361 root_pass
->has_transparent_background
= false;
1363 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1364 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1369 EXPECT_EQ(0, context
->discarded());
1371 output_surface
->set_has_external_stencil_test(false);
1374 // Full frame, clipped, should not discard.
1375 clip_rect
= gfx::Rect(10, 10, 10, 10);
1376 RenderPassId
root_pass_id(1, 0);
1377 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1381 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1382 root_pass
->damage_rect
= root_pass
->output_rect
;
1384 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1385 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1390 EXPECT_EQ(0, context
->discarded());
1394 // Full frame, doesn't cover the surface, should not discard.
1395 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1396 RenderPassId
root_pass_id(1, 0);
1397 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1401 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1402 root_pass
->damage_rect
= root_pass
->output_rect
;
1404 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1405 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1410 EXPECT_EQ(0, context
->discarded());
1414 // Full frame, doesn't cover the surface (no offset), should not discard.
1415 clip_rect
= gfx::Rect(100, 100);
1416 viewport_rect
= gfx::Rect(50, 50);
1417 RenderPassId
root_pass_id(1, 0);
1418 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1422 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1423 root_pass
->damage_rect
= root_pass
->output_rect
;
1425 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1426 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1431 EXPECT_EQ(0, context
->discarded());
1436 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1438 MOCK_METHOD4(viewport
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1439 MOCK_METHOD4(scissor
, void(GLint x
, GLint y
, GLsizei width
, GLsizei height
));
1442 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1443 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1444 // and maintains a fixed size. This test verifies that glViewport and
1445 // glScissor's Y coordinate is flipped correctly in this environment, and that
1446 // the glViewport can be at a nonzero origin within the surface.
1447 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1448 new FlippedScissorAndViewportContext
);
1450 // We expect exactly one call to viewport on this context and exactly two
1451 // to scissor (one to scissor the clear, one to scissor the quad draw).
1452 EXPECT_CALL(*context_owned
, viewport(10, 390, 100, 100));
1453 EXPECT_CALL(*context_owned
, scissor(10, 390, 100, 100));
1454 EXPECT_CALL(*context_owned
, scissor(30, 450, 20, 20));
1456 FakeOutputSurfaceClient output_surface_client
;
1457 scoped_ptr
<OutputSurface
> output_surface(
1458 new NonReshapableOutputSurface(context_owned
.Pass()));
1459 CHECK(output_surface
->BindToClient(&output_surface_client
));
1461 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1462 new TestSharedBitmapManager());
1463 scoped_ptr
<ResourceProvider
> resource_provider(
1464 ResourceProvider::Create(output_surface
.get(),
1465 shared_bitmap_manager
.get(),
1472 RendererSettings settings
;
1473 FakeRendererClient renderer_client
;
1474 FakeRendererGL
renderer(&renderer_client
,
1476 output_surface
.get(),
1477 resource_provider
.get());
1478 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1480 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1481 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1482 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1484 RenderPassId
root_pass_id(1, 0);
1485 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1489 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1491 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1492 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1494 device_viewport_rect
,
1495 device_viewport_rect
,
1499 TEST_F(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1500 // When using render-to-FBO to display the surface, all rendering is done
1501 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1502 // the correct framebuffer during rendering, if changed.
1503 // Note: there is one path that will set it to 0, but that is after the render
1505 FakeOutputSurfaceClient output_surface_client
;
1506 scoped_ptr
<FakeOutputSurface
> output_surface(
1507 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1508 CHECK(output_surface
->BindToClient(&output_surface_client
));
1510 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1511 new TestSharedBitmapManager());
1512 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1513 output_surface
.get(), shared_bitmap_manager
.get(), NULL
, NULL
, 0, false,
1516 RendererSettings settings
;
1517 FakeRendererClient renderer_client
;
1518 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1519 resource_provider
.get());
1520 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1522 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1523 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1524 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1526 RenderPassId
root_pass_id(1, 0);
1527 TestRenderPass
* root_pass
=
1528 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1530 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1533 gpu::gles2::GLES2Interface
* gl
=
1534 output_surface
->context_provider()->ContextGL();
1535 gl
->GenFramebuffers(1, &fbo
);
1536 output_surface
->set_framebuffer(fbo
);
1538 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1539 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1540 device_viewport_rect
, false);
1543 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1544 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1547 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1548 gfx::Rect
viewport_rect(1, 1);
1550 gfx::Rect
child_rect(50, 50);
1551 RenderPassId
child_pass_id(2, 0);
1552 TestRenderPass
* child_pass
;
1554 RenderPassId
root_pass_id(1, 0);
1555 TestRenderPass
* root_pass
;
1557 ResourceProvider::ResourceId mask
= resource_provider_
->CreateResource(
1558 gfx::Size(20, 12), GL_CLAMP_TO_EDGE
,
1559 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
1560 resource_provider_
->best_texture_format());
1561 resource_provider_
->AllocateForTesting(mask
);
1563 SkScalar matrix
[20];
1564 float amount
= 0.5f
;
1565 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1566 matrix
[1] = 0.715f
- 0.715f
* amount
;
1567 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1568 matrix
[3] = matrix
[4] = 0;
1569 matrix
[5] = 0.213f
- 0.213f
* amount
;
1570 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1571 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1572 matrix
[8] = matrix
[9] = 0;
1573 matrix
[10] = 0.213f
- 0.213f
* amount
;
1574 matrix
[11] = 0.715f
- 0.715f
* amount
;
1575 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1576 matrix
[13] = matrix
[14] = 0;
1577 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1579 skia::RefPtr
<SkColorFilter
> color_filter(
1580 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1581 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1582 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1583 FilterOperations filters
;
1584 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1586 gfx::Transform transform_causing_aa
;
1587 transform_causing_aa
.Rotate(20.0);
1589 for (int i
= 0; i
<= LAST_BLEND_MODE
; ++i
) {
1590 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1591 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1592 settings_
.force_blending_with_shaders
= (blend_mode
!= BLEND_MODE_NONE
);
1593 // RenderPassProgram
1594 render_passes_in_draw_order_
.clear();
1595 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1600 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1605 AddRenderPassQuad(root_pass
,
1612 renderer_
->DecideRenderPassAllocationsForFrame(
1613 render_passes_in_draw_order_
);
1614 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1619 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1621 // RenderPassColorMatrixProgram
1622 render_passes_in_draw_order_
.clear();
1624 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1627 transform_causing_aa
);
1629 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1635 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1637 renderer_
->DecideRenderPassAllocationsForFrame(
1638 render_passes_in_draw_order_
);
1639 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1644 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1646 // RenderPassMaskProgram
1647 render_passes_in_draw_order_
.clear();
1649 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1654 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1659 AddRenderPassQuad(root_pass
,
1666 renderer_
->DecideRenderPassAllocationsForFrame(
1667 render_passes_in_draw_order_
);
1668 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1673 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1676 // RenderPassMaskColorMatrixProgram
1677 render_passes_in_draw_order_
.clear();
1679 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1684 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1690 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1692 renderer_
->DecideRenderPassAllocationsForFrame(
1693 render_passes_in_draw_order_
);
1694 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1699 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM
,
1700 SAMPLER_TYPE_2D
, blend_mode
);
1702 // RenderPassProgramAA
1703 render_passes_in_draw_order_
.clear();
1705 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1708 transform_causing_aa
);
1710 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1715 AddRenderPassQuad(root_pass
,
1719 transform_causing_aa
,
1722 renderer_
->DecideRenderPassAllocationsForFrame(
1723 render_passes_in_draw_order_
);
1724 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1729 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1731 // RenderPassColorMatrixProgramAA
1732 render_passes_in_draw_order_
.clear();
1734 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1737 transform_causing_aa
);
1739 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1745 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1747 renderer_
->DecideRenderPassAllocationsForFrame(
1748 render_passes_in_draw_order_
);
1749 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1754 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
, blend_mode
);
1756 // RenderPassMaskProgramAA
1757 render_passes_in_draw_order_
.clear();
1759 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1762 transform_causing_aa
);
1764 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1769 AddRenderPassQuad(root_pass
,
1773 transform_causing_aa
,
1776 renderer_
->DecideRenderPassAllocationsForFrame(
1777 render_passes_in_draw_order_
);
1778 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1783 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM
, SAMPLER_TYPE_2D
,
1786 // RenderPassMaskColorMatrixProgramAA
1787 render_passes_in_draw_order_
.clear();
1789 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1792 transform_causing_aa
);
1794 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1797 transform_causing_aa
);
1800 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1802 renderer_
->DecideRenderPassAllocationsForFrame(
1803 render_passes_in_draw_order_
);
1804 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1809 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM
,
1810 SAMPLER_TYPE_2D
, blend_mode
);
1814 // At this time, the AA code path cannot be taken if the surface's rect would
1815 // project incorrectly by the given transform, because of w<0 clipping.
1816 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1817 gfx::Rect
child_rect(50, 50);
1818 RenderPassId
child_pass_id(2, 0);
1819 TestRenderPass
* child_pass
;
1821 gfx::Rect
viewport_rect(1, 1);
1822 RenderPassId
root_pass_id(1, 0);
1823 TestRenderPass
* root_pass
;
1825 gfx::Transform transform_preventing_aa
;
1826 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1827 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1828 transform_preventing_aa
.Scale(30.0, 1.0);
1830 // Verify that the test transform and test rect actually do cause the clipped
1831 // flag to trigger. Otherwise we are not testing the intended scenario.
1832 bool clipped
= false;
1833 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1834 ASSERT_TRUE(clipped
);
1836 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1839 transform_preventing_aa
);
1841 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1846 AddRenderPassQuad(root_pass
,
1850 transform_preventing_aa
,
1851 SkXfermode::kSrcOver_Mode
);
1853 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1854 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1860 // If use_aa incorrectly ignores clipping, it will use the
1861 // RenderPassProgramAA shader instead of the RenderPassProgram.
1862 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM
, BLEND_MODE_NONE
);
1865 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1866 gfx::Rect
viewport_rect(1, 1);
1867 RenderPassId
root_pass_id(1, 0);
1868 TestRenderPass
* root_pass
;
1870 gfx::Transform pixel_aligned_transform_causing_aa
;
1871 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1872 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1874 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1878 AddTransformedQuad(root_pass
,
1881 pixel_aligned_transform_causing_aa
);
1883 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1884 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1890 TestSolidColorProgramAA();
1893 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1895 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1897 // Specifically override methods even if they are unused (used in conjunction
1898 // with StrictMock). We need to make sure that GLRenderer does not issue
1899 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1900 // through the OutputSurface abstraction.
1901 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1902 MOCK_METHOD3(reshapeWithScaleFactor
,
1903 void(int width
, int height
, float scale_factor
));
1904 MOCK_METHOD4(drawElements
,
1905 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1908 class MockOutputSurface
: public OutputSurface
{
1912 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1913 new StrictMock
<OutputSurfaceMockContext
>))) {
1914 surface_size_
= gfx::Size(100, 100);
1916 virtual ~MockOutputSurface() {}
1918 MOCK_METHOD0(EnsureBackbuffer
, void());
1919 MOCK_METHOD0(DiscardBackbuffer
, void());
1920 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1921 MOCK_METHOD0(BindFramebuffer
, void());
1922 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1925 class MockOutputSurfaceTest
: public GLRendererTest
{
1927 virtual void SetUp() {
1928 FakeOutputSurfaceClient output_surface_client_
;
1929 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1931 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1932 resource_provider_
= ResourceProvider::Create(&output_surface_
,
1933 shared_bitmap_manager_
.get(),
1940 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1943 resource_provider_
.get()));
1946 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1948 void DrawFrame(float device_scale_factor
,
1949 const gfx::Rect
& device_viewport_rect
) {
1950 RenderPassId
render_pass_id(1, 0);
1951 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1953 device_viewport_rect
,
1955 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1957 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1959 EXPECT_CALL(output_surface_
,
1960 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1963 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1965 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1967 renderer_
->DecideRenderPassAllocationsForFrame(
1968 render_passes_in_draw_order_
);
1969 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1970 device_scale_factor
,
1971 device_viewport_rect
,
1972 device_viewport_rect
,
1976 OutputSurfaceMockContext
* Context() {
1977 return static_cast<OutputSurfaceMockContext
*>(
1978 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1982 RendererSettings settings_
;
1983 FakeOutputSurfaceClient output_surface_client_
;
1984 StrictMock
<MockOutputSurface
> output_surface_
;
1985 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1986 scoped_ptr
<ResourceProvider
> resource_provider_
;
1987 FakeRendererClient renderer_client_
;
1988 scoped_ptr
<FakeRendererGL
> renderer_
;
1991 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1992 gfx::Rect
device_viewport_rect(1, 1);
1993 DrawFrame(1.f
, device_viewport_rect
);
1995 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1996 renderer_
->SwapBuffers(CompositorFrameMetadata());
1999 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
2000 gfx::Rect
device_viewport_rect(1, 1);
2002 DrawFrame(1.f
, device_viewport_rect
);
2003 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
2004 renderer_
->SwapBuffers(CompositorFrameMetadata());
2006 device_viewport_rect
= gfx::Rect(2, 2);
2008 DrawFrame(2.f
, device_viewport_rect
);
2009 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
2010 renderer_
->SwapBuffers(CompositorFrameMetadata());
2012 DrawFrame(2.f
, device_viewport_rect
);
2013 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
2014 renderer_
->SwapBuffers(CompositorFrameMetadata());
2016 device_viewport_rect
= gfx::Rect(1, 1);
2018 DrawFrame(1.f
, device_viewport_rect
);
2019 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
2020 renderer_
->SwapBuffers(CompositorFrameMetadata());
2023 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
2025 static void SyncPointCallback(int* callback_count
) {
2026 ++(*callback_count
);
2027 base::MessageLoop::current()->QuitWhenIdle();
2030 static void OtherCallback(int* callback_count
) {
2031 ++(*callback_count
);
2032 base::MessageLoop::current()->QuitWhenIdle();
2036 #if !defined(OS_ANDROID)
2037 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
2038 int sync_point_callback_count
= 0;
2039 int other_callback_count
= 0;
2040 gpu::gles2::GLES2Interface
* gl
=
2041 output_surface_
->context_provider()->ContextGL();
2042 gpu::ContextSupport
* context_support
=
2043 output_surface_
->context_provider()->ContextSupport();
2045 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
2047 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
2048 GL_INNOCENT_CONTEXT_RESET_ARB
);
2050 context_support
->SignalSyncPoint(
2051 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
2052 EXPECT_EQ(0, sync_point_callback_count
);
2053 EXPECT_EQ(0, other_callback_count
);
2055 // Make the sync point happen.
2057 // Post a task after the sync point.
2058 base::ThreadTaskRunnerHandle::Get()->PostTask(
2059 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
2061 base::MessageLoop::current()->Run();
2063 // The sync point shouldn't have happened since the context was lost.
2064 EXPECT_EQ(0, sync_point_callback_count
);
2065 EXPECT_EQ(1, other_callback_count
);
2068 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
2069 int sync_point_callback_count
= 0;
2070 int other_callback_count
= 0;
2072 gpu::gles2::GLES2Interface
* gl
=
2073 output_surface_
->context_provider()->ContextGL();
2074 gpu::ContextSupport
* context_support
=
2075 output_surface_
->context_provider()->ContextSupport();
2077 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
2079 context_support
->SignalSyncPoint(
2080 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
2081 EXPECT_EQ(0, sync_point_callback_count
);
2082 EXPECT_EQ(0, other_callback_count
);
2084 // Make the sync point happen.
2086 // Post a task after the sync point.
2087 base::ThreadTaskRunnerHandle::Get()->PostTask(
2088 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
2090 base::MessageLoop::current()->Run();
2092 // The sync point should have happened.
2093 EXPECT_EQ(1, sync_point_callback_count
);
2094 EXPECT_EQ(1, other_callback_count
);
2096 #endif // OS_ANDROID
2098 class TestOverlayProcessor
: public OverlayProcessor
{
2100 class Strategy
: public OverlayProcessor::Strategy
{
2103 ~Strategy() override
{}
2104 MOCK_METHOD2(Attempt
,
2105 bool(RenderPassList
* render_passes_in_draw_order
,
2106 OverlayCandidateList
* candidates
));
2109 TestOverlayProcessor(OutputSurface
* surface
,
2110 ResourceProvider
* resource_provider
)
2111 : OverlayProcessor(surface
, resource_provider
) {}
2112 ~TestOverlayProcessor() override
{}
2113 void Initialize() override
{
2114 strategy_
= new Strategy();
2115 strategies_
.push_back(scoped_ptr
<OverlayProcessor::Strategy
>(strategy_
));
2118 Strategy
* strategy_
;
2121 void MailboxReleased(unsigned sync_point
,
2123 BlockingTaskRunner
* main_thread_task_runner
) {
2126 void IgnoreCopyResult(scoped_ptr
<CopyOutputResult
> result
) {
2129 TEST_F(GLRendererTest
, DontOverlayWithCopyRequests
) {
2130 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
2131 FakeOutputSurfaceClient output_surface_client
;
2132 scoped_ptr
<OutputSurface
> output_surface(
2133 FakeOutputSurface::Create3d(context_owned
.Pass()));
2134 CHECK(output_surface
->BindToClient(&output_surface_client
));
2136 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
2137 new TestSharedBitmapManager());
2138 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
2139 output_surface
.get(), shared_bitmap_manager
.get(), NULL
, NULL
, 0, false,
2141 scoped_ptr
<TextureMailboxDeleter
> mailbox_deleter(
2142 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2144 RendererSettings settings
;
2145 FakeRendererClient renderer_client
;
2146 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
2147 resource_provider
.get(), mailbox_deleter
.get());
2149 TestOverlayProcessor
* processor
=
2150 new TestOverlayProcessor(output_surface
.get(), resource_provider
.get());
2151 processor
->Initialize();
2152 renderer
.SetOverlayProcessor(processor
);
2154 gfx::Rect
viewport_rect(1, 1);
2155 TestRenderPass
* root_pass
=
2156 AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2157 viewport_rect
, gfx::Transform());
2158 root_pass
->has_transparent_background
= false;
2159 root_pass
->copy_requests
.push_back(
2160 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult
)));
2162 unsigned sync_point
= 0;
2163 TextureMailbox mailbox
=
2164 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D
, sync_point
);
2165 mailbox
.set_allow_overlay(true);
2166 scoped_ptr
<SingleReleaseCallbackImpl
> release_callback
=
2167 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased
));
2168 ResourceProvider::ResourceId resource_id
=
2169 resource_provider
->CreateResourceFromTextureMailbox(
2170 mailbox
, release_callback
.Pass());
2171 bool premultiplied_alpha
= false;
2172 bool flipped
= false;
2173 bool nearest_neighbor
= false;
2174 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2176 TextureDrawQuad
* overlay_quad
=
2177 root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2178 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2179 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2180 premultiplied_alpha
, gfx::PointF(0, 0),
2181 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2182 flipped
, nearest_neighbor
);
2184 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2185 // Attempt will be called for each strategy in OverlayProcessor. We have
2186 // added a fake strategy, so checking for Attempt calls checks if there was
2187 // any attempt to overlay, which there shouldn't be. We can't use the quad
2188 // list because the render pass is cleaned up by DrawFrame.
2189 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(0);
2190 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2191 viewport_rect
, false);
2192 Mock::VerifyAndClearExpectations(processor
->strategy_
);
2194 // Without a copy request Attempt() should be called once.
2195 root_pass
= AddRenderPass(&render_passes_in_draw_order_
, RenderPassId(1, 0),
2196 viewport_rect
, gfx::Transform());
2197 root_pass
->has_transparent_background
= false;
2199 overlay_quad
= root_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2200 overlay_quad
->SetNew(root_pass
->CreateAndAppendSharedQuadState(),
2201 viewport_rect
, viewport_rect
, viewport_rect
, resource_id
,
2202 premultiplied_alpha
, gfx::PointF(0, 0),
2203 gfx::PointF(1, 1), SK_ColorTRANSPARENT
, vertex_opacity
,
2204 flipped
, nearest_neighbor
);
2206 EXPECT_CALL(*processor
->strategy_
, Attempt(_
, _
)).Times(1);
2207 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, viewport_rect
,
2208 viewport_rect
, false);