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 "cc/base/math_util.h"
10 #include "cc/output/compositor_frame_metadata.h"
11 #include "cc/resources/resource_provider.h"
12 #include "cc/test/fake_impl_proxy.h"
13 #include "cc/test/fake_layer_tree_host_impl.h"
14 #include "cc/test/fake_output_surface.h"
15 #include "cc/test/fake_output_surface_client.h"
16 #include "cc/test/fake_renderer_client.h"
17 #include "cc/test/pixel_test.h"
18 #include "cc/test/render_pass_test_common.h"
19 #include "cc/test/render_pass_test_utils.h"
20 #include "cc/test/test_shared_bitmap_manager.h"
21 #include "cc/test/test_web_graphics_context_3d.h"
22 #include "gpu/GLES2/gl2extchromium.h"
23 #include "gpu/command_buffer/client/context_support.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/skia/include/core/SkImageFilter.h"
27 #include "third_party/skia/include/core/SkMatrix.h"
28 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
29 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
30 #include "ui/gfx/transform.h"
33 using testing::AnyNumber
;
35 using testing::AtLeast
;
36 using testing::ElementsAre
;
37 using testing::Expectation
;
38 using testing::InSequence
;
40 using testing::Return
;
41 using testing::StrictMock
;
45 class GLRendererTest
: public testing::Test
{
47 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
49 RenderPassList render_passes_in_draw_order_
;
52 #define EXPECT_PROGRAM_VALID(program_binding) \
54 EXPECT_TRUE((program_binding)->program()); \
55 EXPECT_TRUE((program_binding)->initialized()); \
58 static inline SkXfermode::Mode
BlendModeToSkXfermode(BlendMode blend_mode
) {
62 return SkXfermode::kSrcOver_Mode
;
64 return SkXfermode::kScreen_Mode
;
65 case BlendModeOverlay
:
66 return SkXfermode::kOverlay_Mode
;
68 return SkXfermode::kDarken_Mode
;
69 case BlendModeLighten
:
70 return SkXfermode::kLighten_Mode
;
71 case BlendModeColorDodge
:
72 return SkXfermode::kColorDodge_Mode
;
73 case BlendModeColorBurn
:
74 return SkXfermode::kColorBurn_Mode
;
75 case BlendModeHardLight
:
76 return SkXfermode::kHardLight_Mode
;
77 case BlendModeSoftLight
:
78 return SkXfermode::kSoftLight_Mode
;
79 case BlendModeDifference
:
80 return SkXfermode::kDifference_Mode
;
81 case BlendModeExclusion
:
82 return SkXfermode::kExclusion_Mode
;
83 case BlendModeMultiply
:
84 return SkXfermode::kMultiply_Mode
;
86 return SkXfermode::kHue_Mode
;
87 case BlendModeSaturation
:
88 return SkXfermode::kSaturation_Mode
;
90 return SkXfermode::kColor_Mode
;
91 case BlendModeLuminosity
:
92 return SkXfermode::kLuminosity_Mode
;
96 return SkXfermode::kSrcOver_Mode
;
99 // Explicitly named to be a friend in GLRenderer for shader access.
100 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
103 ASSERT_FALSE(renderer()->IsContextLost());
104 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
105 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
106 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
107 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
108 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium
);
109 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh
);
110 ASSERT_FALSE(renderer()->IsContextLost());
113 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision
) {
114 for (int i
= 0; i
< NumBlendModes
; ++i
) {
115 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
116 EXPECT_PROGRAM_VALID(
117 renderer()->GetRenderPassProgram(precision
, blend_mode
));
118 EXPECT_PROGRAM_VALID(
119 renderer()->GetRenderPassProgramAA(precision
, blend_mode
));
121 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
));
122 EXPECT_PROGRAM_VALID(
123 renderer()->GetNonPremultipliedTextureProgram(precision
));
124 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision
));
125 EXPECT_PROGRAM_VALID(
126 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
));
127 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
128 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
));
129 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
));
130 // This is unlikely to be ever true in tests due to usage of osmesa.
131 if (renderer()->Capabilities().using_egl_image
)
132 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
134 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
135 TestShadersWithSamplerType(precision
, SamplerType2D
);
136 TestShadersWithSamplerType(precision
, SamplerType2DRect
);
137 // This is unlikely to be ever true in tests due to usage of osmesa.
138 if (renderer()->Capabilities().using_egl_image
)
139 TestShadersWithSamplerType(precision
, SamplerTypeExternalOES
);
142 void TestShadersWithSamplerType(TexCoordPrecision precision
,
143 SamplerType sampler
) {
144 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
145 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
146 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
147 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
148 EXPECT_PROGRAM_VALID(
149 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
150 EXPECT_PROGRAM_VALID(
151 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
152 for (int i
= 0; i
< NumBlendModes
; ++i
) {
153 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
154 EXPECT_PROGRAM_VALID(
155 renderer()->GetRenderPassMaskProgram(precision
, sampler
, blend_mode
));
156 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
157 precision
, sampler
, blend_mode
));
158 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
159 precision
, sampler
, blend_mode
));
160 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
161 precision
, sampler
, blend_mode
));
168 #if !defined(OS_ANDROID)
169 TEST_F(GLRendererShaderPixelTest
, AllShadersCompile
) { TestShaders(); }
172 class FakeRendererGL
: public GLRenderer
{
174 FakeRendererGL(RendererClient
* client
,
175 const RendererSettings
* settings
,
176 OutputSurface
* output_surface
,
177 ResourceProvider
* resource_provider
)
185 // GLRenderer methods.
187 // Changing visibility to public.
188 using GLRenderer::IsBackbufferDiscarded
;
189 using GLRenderer::DoDrawQuad
;
190 using GLRenderer::BeginDrawingFrame
;
191 using GLRenderer::FinishDrawingQuadList
;
192 using GLRenderer::stencil_enabled
;
195 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
197 GLRendererWithDefaultHarnessTest() {
199 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
200 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
202 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
203 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
204 shared_bitmap_manager_
.get(),
210 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
212 output_surface_
.get(),
213 resource_provider_
.get()));
216 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
218 RendererSettings settings_
;
219 FakeOutputSurfaceClient output_surface_client_
;
220 scoped_ptr
<FakeOutputSurface
> output_surface_
;
221 FakeRendererClient renderer_client_
;
222 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
223 scoped_ptr
<ResourceProvider
> resource_provider_
;
224 scoped_ptr
<FakeRendererGL
> renderer_
;
227 // Closing the namespace here so that GLRendererShaderTest can take advantage
228 // of the friend relationship with GLRenderer and all of the mock classes
229 // declared above it.
232 class GLRendererShaderTest
: public GLRendererTest
{
234 GLRendererShaderTest() {
235 output_surface_
= FakeOutputSurface::Create3d().Pass();
236 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
238 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
239 resource_provider_
= ResourceProvider::Create(output_surface_
.get(),
240 shared_bitmap_manager_
.get(),
246 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
248 output_surface_
.get(),
249 resource_provider_
.get()));
252 void TestRenderPassProgram(TexCoordPrecision precision
,
253 BlendMode blend_mode
) {
254 EXPECT_PROGRAM_VALID(
255 &renderer_
->render_pass_program_
[precision
][blend_mode
]);
256 EXPECT_EQ(renderer_
->render_pass_program_
[precision
][blend_mode
].program(),
257 renderer_
->program_shadow_
);
260 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
,
261 BlendMode blend_mode
) {
262 EXPECT_PROGRAM_VALID(
263 &renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]);
265 renderer_
->render_pass_color_matrix_program_
[precision
][blend_mode
]
267 renderer_
->program_shadow_
);
270 void TestRenderPassMaskProgram(TexCoordPrecision precision
,
272 BlendMode blend_mode
) {
273 EXPECT_PROGRAM_VALID(
274 &renderer_
->render_pass_mask_program_
[precision
][sampler
][blend_mode
]);
276 renderer_
->render_pass_mask_program_
[precision
][sampler
][blend_mode
]
278 renderer_
->program_shadow_
);
281 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
,
283 BlendMode blend_mode
) {
284 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_
285 [precision
][sampler
][blend_mode
]);
286 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_
287 [precision
][sampler
][blend_mode
].program(),
288 renderer_
->program_shadow_
);
291 void TestRenderPassProgramAA(TexCoordPrecision precision
,
292 BlendMode blend_mode
) {
293 EXPECT_PROGRAM_VALID(
294 &renderer_
->render_pass_program_aa_
[precision
][blend_mode
]);
296 renderer_
->render_pass_program_aa_
[precision
][blend_mode
].program(),
297 renderer_
->program_shadow_
);
300 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
,
301 BlendMode blend_mode
) {
302 EXPECT_PROGRAM_VALID(
304 ->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]);
306 renderer_
->render_pass_color_matrix_program_aa_
[precision
][blend_mode
]
308 renderer_
->program_shadow_
);
311 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
,
313 BlendMode blend_mode
) {
314 EXPECT_PROGRAM_VALID(
316 ->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]);
318 renderer_
->render_pass_mask_program_aa_
[precision
][sampler
][blend_mode
]
320 renderer_
->program_shadow_
);
323 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
,
325 BlendMode blend_mode
) {
326 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_color_matrix_program_aa_
327 [precision
][sampler
][blend_mode
]);
328 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
329 [precision
][sampler
][blend_mode
].program(),
330 renderer_
->program_shadow_
);
333 void TestSolidColorProgramAA() {
334 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
335 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
336 renderer_
->program_shadow_
);
339 RendererSettings settings_
;
340 FakeOutputSurfaceClient output_surface_client_
;
341 scoped_ptr
<FakeOutputSurface
> output_surface_
;
342 FakeRendererClient renderer_client_
;
343 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
344 scoped_ptr
<ResourceProvider
> resource_provider_
;
345 scoped_ptr
<FakeRendererGL
> renderer_
;
350 // Test GLRenderer DiscardBackbuffer functionality:
351 // Suggest discarding framebuffer when one exists and the renderer is not
353 // Expected: it is discarded and damage tracker is reset.
355 GLRendererWithDefaultHarnessTest
,
356 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
357 renderer_
->SetVisible(false);
358 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
359 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
362 // Test GLRenderer DiscardBackbuffer functionality:
363 // Suggest discarding framebuffer when one exists and the renderer is visible.
364 // Expected: the allocation is ignored.
365 TEST_F(GLRendererWithDefaultHarnessTest
,
366 SuggestBackbufferNoDoNothingWhenVisible
) {
367 renderer_
->SetVisible(true);
368 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
369 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
372 // Test GLRenderer DiscardBackbuffer functionality:
373 // Suggest discarding framebuffer when one does not exist.
374 // Expected: it does nothing.
375 TEST_F(GLRendererWithDefaultHarnessTest
,
376 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
377 renderer_
->SetVisible(false);
378 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
379 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
381 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
382 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
385 // Test GLRenderer DiscardBackbuffer functionality:
386 // Begin drawing a frame while a framebuffer is discarded.
387 // Expected: will recreate framebuffer.
388 TEST_F(GLRendererWithDefaultHarnessTest
,
389 DiscardedBackbufferIsRecreatedForScopeDuration
) {
390 gfx::Rect
viewport_rect(1, 1);
391 renderer_
->SetVisible(false);
392 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
393 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
395 AddRenderPass(&render_passes_in_draw_order_
,
400 renderer_
->SetVisible(true);
401 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
406 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
409 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
412 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
413 gfx::Rect
viewport_rect(1, 1);
414 EXPECT_FALSE(renderer_
->stencil_enabled());
416 output_surface_
->set_has_external_stencil_test(true);
418 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
422 root_pass
->has_transparent_background
= false;
424 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
429 EXPECT_TRUE(renderer_
->stencil_enabled());
432 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
434 ForbidSynchronousCallContext() {}
436 void getAttachedShaders(GLuint program
,
439 GLuint
* shaders
) override
{
442 GLint
getAttribLocation(GLuint program
, const GLchar
* name
) override
{
446 void getBooleanv(GLenum pname
, GLboolean
* value
) override
{ ADD_FAILURE(); }
447 void getBufferParameteriv(GLenum target
,
449 GLint
* value
) override
{
452 GLenum
getError() override
{
456 void getFloatv(GLenum pname
, GLfloat
* value
) override
{ ADD_FAILURE(); }
457 void getFramebufferAttachmentParameteriv(GLenum target
,
460 GLint
* value
) override
{
463 void getIntegerv(GLenum pname
, GLint
* value
) override
{
464 if (pname
== GL_MAX_TEXTURE_SIZE
) {
465 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
472 // We allow querying the shader compilation and program link status in debug
473 // mode, but not release.
474 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
482 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
490 void getRenderbufferParameteriv(GLenum target
,
492 GLint
* value
) override
{
496 void getShaderPrecisionFormat(GLenum shadertype
,
497 GLenum precisiontype
,
499 GLint
* precision
) override
{
502 void getTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* value
) override
{
505 void getTexParameteriv(GLenum target
, GLenum pname
, GLint
* value
) override
{
508 void getUniformfv(GLuint program
, GLint location
, GLfloat
* value
) override
{
511 void getUniformiv(GLuint program
, GLint location
, GLint
* value
) override
{
514 GLint
getUniformLocation(GLuint program
, const GLchar
* name
) override
{
518 void getVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* value
) override
{
521 void getVertexAttribiv(GLuint index
, GLenum pname
, GLint
* value
) override
{
524 GLsizeiptr
getVertexAttribOffset(GLuint index
, GLenum pname
) override
{
529 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
530 FakeOutputSurfaceClient output_surface_client
;
531 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
532 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
533 CHECK(output_surface
->BindToClient(&output_surface_client
));
535 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
536 new TestSharedBitmapManager());
537 scoped_ptr
<ResourceProvider
> resource_provider(
538 ResourceProvider::Create(output_surface
.get(),
539 shared_bitmap_manager
.get(),
546 RendererSettings settings
;
547 FakeRendererClient renderer_client
;
548 FakeRendererGL
renderer(&renderer_client
,
550 output_surface
.get(),
551 resource_provider
.get());
554 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
556 LoseContextOnFirstGetContext() {}
558 void getProgramiv(GLuint program
, GLenum pname
, GLint
* value
) override
{
559 context_lost_
= true;
563 void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) override
{
564 context_lost_
= true;
569 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
570 FakeOutputSurfaceClient output_surface_client
;
571 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
572 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
573 CHECK(output_surface
->BindToClient(&output_surface_client
));
575 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
576 new TestSharedBitmapManager());
577 scoped_ptr
<ResourceProvider
> resource_provider(
578 ResourceProvider::Create(output_surface
.get(),
579 shared_bitmap_manager
.get(),
586 RendererSettings settings
;
587 FakeRendererClient renderer_client
;
588 FakeRendererGL
renderer(&renderer_client
,
590 output_surface
.get(),
591 resource_provider
.get());
594 class ClearCountingContext
: public TestWebGraphicsContext3D
{
596 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
598 MOCK_METHOD3(discardFramebufferEXT
,
600 GLsizei numAttachments
,
601 const GLenum
* attachments
));
602 MOCK_METHOD1(clear
, void(GLbitfield mask
));
605 TEST_F(GLRendererTest
, OpaqueBackground
) {
606 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
607 ClearCountingContext
* context
= context_owned
.get();
609 FakeOutputSurfaceClient output_surface_client
;
610 scoped_ptr
<OutputSurface
> output_surface(
611 FakeOutputSurface::Create3d(context_owned
.Pass()));
612 CHECK(output_surface
->BindToClient(&output_surface_client
));
614 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
615 new TestSharedBitmapManager());
616 scoped_ptr
<ResourceProvider
> resource_provider(
617 ResourceProvider::Create(output_surface
.get(),
618 shared_bitmap_manager
.get(),
625 RendererSettings settings
;
626 FakeRendererClient renderer_client
;
627 FakeRendererGL
renderer(&renderer_client
,
629 output_surface
.get(),
630 resource_provider
.get());
632 gfx::Rect
viewport_rect(1, 1);
633 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
637 root_pass
->has_transparent_background
= false;
639 // On DEBUG builds, render passes with opaque background clear to blue to
640 // easily see regions that were not drawn on the screen.
641 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
642 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
645 EXPECT_CALL(*context
, clear(_
)).Times(0);
647 EXPECT_CALL(*context
, clear(_
)).Times(1);
649 renderer
.DrawFrame(&render_passes_in_draw_order_
,
654 Mock::VerifyAndClearExpectations(context
);
657 TEST_F(GLRendererTest
, TransparentBackground
) {
658 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
659 ClearCountingContext
* context
= context_owned
.get();
661 FakeOutputSurfaceClient output_surface_client
;
662 scoped_ptr
<OutputSurface
> output_surface(
663 FakeOutputSurface::Create3d(context_owned
.Pass()));
664 CHECK(output_surface
->BindToClient(&output_surface_client
));
666 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
667 new TestSharedBitmapManager());
668 scoped_ptr
<ResourceProvider
> resource_provider(
669 ResourceProvider::Create(output_surface
.get(),
670 shared_bitmap_manager
.get(),
677 RendererSettings settings
;
678 FakeRendererClient renderer_client
;
679 FakeRendererGL
renderer(&renderer_client
,
681 output_surface
.get(),
682 resource_provider
.get());
684 gfx::Rect
viewport_rect(1, 1);
685 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
689 root_pass
->has_transparent_background
= true;
691 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
692 EXPECT_CALL(*context
, clear(_
)).Times(1);
693 renderer
.DrawFrame(&render_passes_in_draw_order_
,
699 Mock::VerifyAndClearExpectations(context
);
702 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
703 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
704 ClearCountingContext
* context
= context_owned
.get();
706 FakeOutputSurfaceClient output_surface_client
;
707 scoped_ptr
<OutputSurface
> output_surface(
708 FakeOutputSurface::CreateOffscreen(context_owned
.Pass()));
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());
729 gfx::Rect
viewport_rect(1, 1);
730 AddRenderPass(&render_passes_in_draw_order_
,
735 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
736 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
738 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
739 renderer
.DrawFrame(&render_passes_in_draw_order_
,
744 Mock::VerifyAndClearExpectations(context
);
747 class VisibilityChangeIsLastCallTrackingContext
748 : public TestWebGraphicsContext3D
{
750 VisibilityChangeIsLastCallTrackingContext()
751 : last_call_was_set_visibility_(false) {}
753 // TestWebGraphicsContext3D methods.
754 void flush() override
{ last_call_was_set_visibility_
= false; }
755 void deleteTexture(GLuint
) override
{ last_call_was_set_visibility_
= false; }
756 void deleteFramebuffer(GLuint
) override
{
757 last_call_was_set_visibility_
= false;
759 void deleteQueryEXT(GLuint
) override
{
760 last_call_was_set_visibility_
= false;
762 void deleteRenderbuffer(GLuint
) override
{
763 last_call_was_set_visibility_
= false;
766 // Methods added for test.
767 void set_last_call_was_visibility(bool visible
) {
768 DCHECK(last_call_was_set_visibility_
== false);
769 last_call_was_set_visibility_
= true;
771 bool last_call_was_set_visibility() const {
772 return last_call_was_set_visibility_
;
776 bool last_call_was_set_visibility_
;
779 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
780 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
781 new VisibilityChangeIsLastCallTrackingContext
);
782 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
784 scoped_refptr
<TestContextProvider
> provider
=
785 TestContextProvider::Create(context_owned
.Pass());
787 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
788 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
789 base::Unretained(context
)));
791 FakeOutputSurfaceClient output_surface_client
;
792 scoped_ptr
<OutputSurface
> output_surface(
793 FakeOutputSurface::Create3d(provider
));
794 CHECK(output_surface
->BindToClient(&output_surface_client
));
796 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
797 new TestSharedBitmapManager());
798 scoped_ptr
<ResourceProvider
> resource_provider(
799 ResourceProvider::Create(output_surface
.get(),
800 shared_bitmap_manager
.get(),
807 RendererSettings settings
;
808 FakeRendererClient renderer_client
;
809 FakeRendererGL
renderer(&renderer_client
,
811 output_surface
.get(),
812 resource_provider
.get());
814 gfx::Rect
viewport_rect(1, 1);
815 AddRenderPass(&render_passes_in_draw_order_
,
820 // Ensure that the call to SetSurfaceVisible is the last call issue to the
821 // GPU process, after glFlush is called, and after the RendererClient's
822 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
823 // RenderClient and the Context by giving them both a pointer to a variable on
825 renderer
.SetVisible(true);
826 renderer
.DrawFrame(&render_passes_in_draw_order_
,
831 renderer
.SetVisible(false);
832 EXPECT_TRUE(context
->last_call_was_set_visibility());
835 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
837 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
838 test_capabilities_
.gpu
.egl_image_external
= true;
841 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
842 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
843 MOCK_METHOD4(drawElements
,
844 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
846 virtual void activeTexture(GLenum texture
) {
847 EXPECT_NE(texture
, active_texture_
);
848 active_texture_
= texture
;
851 GLenum
active_texture() const { return active_texture_
; }
854 GLenum active_texture_
;
857 TEST_F(GLRendererTest
, ActiveTextureState
) {
858 scoped_ptr
<TextureStateTrackingContext
> context_owned(
859 new TextureStateTrackingContext
);
860 TextureStateTrackingContext
* context
= context_owned
.get();
862 FakeOutputSurfaceClient output_surface_client
;
863 scoped_ptr
<OutputSurface
> output_surface(
864 FakeOutputSurface::Create3d(context_owned
.Pass()));
865 CHECK(output_surface
->BindToClient(&output_surface_client
));
867 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
868 new TestSharedBitmapManager());
869 scoped_ptr
<ResourceProvider
> resource_provider(
870 ResourceProvider::Create(output_surface
.get(),
871 shared_bitmap_manager
.get(),
878 RendererSettings settings
;
879 FakeRendererClient renderer_client
;
880 FakeRendererGL
renderer(&renderer_client
,
882 output_surface
.get(),
883 resource_provider
.get());
885 // During initialization we are allowed to set any texture parameters.
886 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
888 RenderPassId
id(1, 1);
889 TestRenderPass
* root_pass
= AddRenderPass(
890 &render_passes_in_draw_order_
, id
, gfx::Rect(100, 100), gfx::Transform());
891 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
894 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
896 // Set up expected texture filter state transitions that match the quads
897 // created in AppendOneOfEveryQuadType().
898 Mock::VerifyAndClearExpectations(context
);
902 // The sync points for all quads are waited on first. This sync point is
903 // for a texture quad drawn later in the frame.
904 EXPECT_CALL(*context
,
905 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
908 // yuv_quad is drawn with the default linear filter.
909 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
911 // tile_quad is drawn with GL_NEAREST because it is not transformed or
915 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
918 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
919 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
921 // transformed_tile_quad uses GL_LINEAR.
922 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
924 // scaled_tile_quad also uses GL_LINEAR.
925 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
927 // The remaining quads also use GL_LINEAR because nearest neighbor
928 // filtering is currently only used with tile quads.
929 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(7);
932 gfx::Rect
viewport_rect(100, 100);
933 renderer
.DrawFrame(&render_passes_in_draw_order_
,
938 Mock::VerifyAndClearExpectations(context
);
941 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
943 MOCK_METHOD1(clear
, void(GLbitfield mask
));
944 MOCK_METHOD4(drawElements
,
945 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
948 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
949 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
950 new NoClearRootRenderPassMockContext
);
951 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
953 FakeOutputSurfaceClient output_surface_client
;
954 scoped_ptr
<OutputSurface
> output_surface(
955 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
956 CHECK(output_surface
->BindToClient(&output_surface_client
));
958 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
959 new TestSharedBitmapManager());
960 scoped_ptr
<ResourceProvider
> resource_provider(
961 ResourceProvider::Create(output_surface
.get(),
962 shared_bitmap_manager
.get(),
969 RendererSettings settings
;
970 settings
.should_clear_root_render_pass
= false;
972 FakeRendererClient renderer_client
;
973 FakeRendererGL
renderer(&renderer_client
,
975 output_surface
.get(),
976 resource_provider
.get());
978 gfx::Rect
viewport_rect(10, 10);
980 RenderPassId
root_pass_id(1, 0);
981 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
985 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
987 RenderPassId
child_pass_id(2, 0);
988 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
992 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
994 AddRenderPassQuad(root_pass
, child_pass
);
997 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
999 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
1002 // First render pass is not the root one, clearing should happen.
1003 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
1005 Expectation first_render_pass
=
1006 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
1008 // The second render pass is the root one, clearing should be prevented.
1009 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
1012 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
1015 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1016 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1022 // In multiple render passes all but the root pass should clear the
1024 Mock::VerifyAndClearExpectations(&mock_context
);
1027 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
1029 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1031 void clear(GLbitfield
) override
{ EXPECT_FALSE(scissor_enabled_
); }
1033 void enable(GLenum cap
) override
{
1034 if (cap
== GL_SCISSOR_TEST
)
1035 scissor_enabled_
= true;
1038 void disable(GLenum cap
) override
{
1039 if (cap
== GL_SCISSOR_TEST
)
1040 scissor_enabled_
= false;
1044 bool scissor_enabled_
;
1047 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
1048 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
1049 new ScissorTestOnClearCheckingContext
);
1051 FakeOutputSurfaceClient output_surface_client
;
1052 scoped_ptr
<OutputSurface
> output_surface(
1053 FakeOutputSurface::Create3d(context_owned
.Pass()));
1054 CHECK(output_surface
->BindToClient(&output_surface_client
));
1056 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1057 new TestSharedBitmapManager());
1058 scoped_ptr
<ResourceProvider
> resource_provider(
1059 ResourceProvider::Create(output_surface
.get(),
1060 shared_bitmap_manager
.get(),
1067 RendererSettings settings
;
1068 FakeRendererClient renderer_client
;
1069 FakeRendererGL
renderer(&renderer_client
,
1071 output_surface
.get(),
1072 resource_provider
.get());
1073 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1075 gfx::Rect
viewport_rect(1, 1);
1077 gfx::Rect
grand_child_rect(25, 25);
1078 RenderPassId
grand_child_pass_id(3, 0);
1079 TestRenderPass
* grand_child_pass
=
1080 AddRenderPass(&render_passes_in_draw_order_
,
1081 grand_child_pass_id
,
1084 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1086 gfx::Rect
child_rect(50, 50);
1087 RenderPassId
child_pass_id(2, 0);
1088 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1092 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1094 RenderPassId
root_pass_id(1, 0);
1095 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1099 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1101 AddRenderPassQuad(root_pass
, child_pass
);
1102 AddRenderPassQuad(child_pass
, grand_child_pass
);
1104 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1105 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1112 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1114 DiscardCheckingContext() : discarded_(0) {
1115 set_have_post_sub_buffer(true);
1116 set_have_discard_framebuffer(true);
1119 void discardFramebufferEXT(GLenum target
,
1120 GLsizei numAttachments
,
1121 const GLenum
* attachments
) override
{
1125 int discarded() const { return discarded_
; }
1126 void reset() { discarded_
= 0; }
1132 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1134 explicit NonReshapableOutputSurface(
1135 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1136 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1138 surface_size_
= gfx::Size(500, 500);
1140 void Reshape(const gfx::Size
& size
, float scale_factor
) override
{}
1141 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1144 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1145 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1146 DiscardCheckingContext
* context
= context_owned
.get();
1148 FakeOutputSurfaceClient output_surface_client
;
1149 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1150 new NonReshapableOutputSurface(context_owned
.Pass()));
1151 CHECK(output_surface
->BindToClient(&output_surface_client
));
1152 output_surface
->set_fixed_size(gfx::Size(100, 100));
1154 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1155 new TestSharedBitmapManager());
1156 scoped_ptr
<ResourceProvider
> resource_provider(
1157 ResourceProvider::Create(output_surface
.get(),
1158 shared_bitmap_manager
.get(),
1165 RendererSettings settings
;
1166 settings
.partial_swap_enabled
= true;
1167 FakeRendererClient renderer_client
;
1168 FakeRendererGL
renderer(&renderer_client
,
1170 output_surface
.get(),
1171 resource_provider
.get());
1172 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1174 gfx::Rect
viewport_rect(100, 100);
1175 gfx::Rect
clip_rect(100, 100);
1178 // Partial frame, should not discard.
1179 RenderPassId
root_pass_id(1, 0);
1180 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1184 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1185 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1187 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1188 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1193 EXPECT_EQ(0, context
->discarded());
1197 // Full frame, should discard.
1198 RenderPassId
root_pass_id(1, 0);
1199 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1203 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1204 root_pass
->damage_rect
= root_pass
->output_rect
;
1206 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1207 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1212 EXPECT_EQ(1, context
->discarded());
1216 // Full frame, external scissor is set, should not discard.
1217 output_surface
->set_has_external_stencil_test(true);
1218 RenderPassId
root_pass_id(1, 0);
1219 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1223 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1224 root_pass
->damage_rect
= root_pass
->output_rect
;
1225 root_pass
->has_transparent_background
= false;
1227 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1228 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1233 EXPECT_EQ(0, context
->discarded());
1235 output_surface
->set_has_external_stencil_test(false);
1238 // Full frame, clipped, should not discard.
1239 clip_rect
= gfx::Rect(10, 10, 10, 10);
1240 RenderPassId
root_pass_id(1, 0);
1241 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1245 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1246 root_pass
->damage_rect
= root_pass
->output_rect
;
1248 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1249 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1254 EXPECT_EQ(0, context
->discarded());
1258 // Full frame, doesn't cover the surface, should not discard.
1259 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1260 RenderPassId
root_pass_id(1, 0);
1261 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1265 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1266 root_pass
->damage_rect
= root_pass
->output_rect
;
1268 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1269 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1274 EXPECT_EQ(0, context
->discarded());
1278 // Full frame, doesn't cover the surface (no offset), should not discard.
1279 clip_rect
= gfx::Rect(100, 100);
1280 viewport_rect
= gfx::Rect(50, 50);
1281 RenderPassId
root_pass_id(1, 0);
1282 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1286 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1287 root_pass
->damage_rect
= root_pass
->output_rect
;
1289 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1290 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1295 EXPECT_EQ(0, context
->discarded());
1300 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1302 FlippedScissorAndViewportContext()
1303 : did_call_viewport_(false), did_call_scissor_(false) {}
1304 ~FlippedScissorAndViewportContext() override
{
1305 EXPECT_TRUE(did_call_viewport_
);
1306 EXPECT_TRUE(did_call_scissor_
);
1309 void viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
) override
{
1312 EXPECT_EQ(100, width
);
1313 EXPECT_EQ(100, height
);
1314 did_call_viewport_
= true;
1317 void scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
) override
{
1320 EXPECT_EQ(20, width
);
1321 EXPECT_EQ(20, height
);
1322 did_call_scissor_
= true;
1326 bool did_call_viewport_
;
1327 bool did_call_scissor_
;
1330 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1331 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1332 // and maintains a fixed size. This test verifies that glViewport and
1333 // glScissor's Y coordinate is flipped correctly in this environment, and that
1334 // the glViewport can be at a nonzero origin within the surface.
1335 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1336 new FlippedScissorAndViewportContext
);
1338 FakeOutputSurfaceClient output_surface_client
;
1339 scoped_ptr
<OutputSurface
> output_surface(
1340 new NonReshapableOutputSurface(context_owned
.Pass()));
1341 CHECK(output_surface
->BindToClient(&output_surface_client
));
1343 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1344 new TestSharedBitmapManager());
1345 scoped_ptr
<ResourceProvider
> resource_provider(
1346 ResourceProvider::Create(output_surface
.get(),
1347 shared_bitmap_manager
.get(),
1354 RendererSettings settings
;
1355 FakeRendererClient renderer_client
;
1356 FakeRendererGL
renderer(&renderer_client
,
1358 output_surface
.get(),
1359 resource_provider
.get());
1360 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1362 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1363 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1364 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1366 RenderPassId
root_pass_id(1, 0);
1367 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1371 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1373 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1374 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1376 device_viewport_rect
,
1377 device_viewport_rect
,
1381 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1382 gfx::Rect
viewport_rect(1, 1);
1384 gfx::Rect
child_rect(50, 50);
1385 RenderPassId
child_pass_id(2, 0);
1386 TestRenderPass
* child_pass
;
1388 RenderPassId
root_pass_id(1, 0);
1389 TestRenderPass
* root_pass
;
1391 ResourceProvider::ResourceId mask
= resource_provider_
->CreateResource(
1394 ResourceProvider::TextureHintImmutable
,
1395 resource_provider_
->best_texture_format());
1396 resource_provider_
->AllocateForTesting(mask
);
1398 SkScalar matrix
[20];
1399 float amount
= 0.5f
;
1400 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1401 matrix
[1] = 0.715f
- 0.715f
* amount
;
1402 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1403 matrix
[3] = matrix
[4] = 0;
1404 matrix
[5] = 0.213f
- 0.213f
* amount
;
1405 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1406 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1407 matrix
[8] = matrix
[9] = 0;
1408 matrix
[10] = 0.213f
- 0.213f
* amount
;
1409 matrix
[11] = 0.715f
- 0.715f
* amount
;
1410 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1411 matrix
[13] = matrix
[14] = 0;
1412 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1414 skia::RefPtr
<SkColorFilter
> color_filter(
1415 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1416 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1417 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1418 FilterOperations filters
;
1419 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1421 gfx::Transform transform_causing_aa
;
1422 transform_causing_aa
.Rotate(20.0);
1424 for (int i
= 0; i
< NumBlendModes
; ++i
) {
1425 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1426 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1427 settings_
.force_blending_with_shaders
= (blend_mode
!= BlendModeNone
);
1428 // RenderPassProgram
1429 render_passes_in_draw_order_
.clear();
1430 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1435 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1440 AddRenderPassQuad(root_pass
,
1447 renderer_
->DecideRenderPassAllocationsForFrame(
1448 render_passes_in_draw_order_
);
1449 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1454 TestRenderPassProgram(TexCoordPrecisionMedium
, blend_mode
);
1456 // RenderPassColorMatrixProgram
1457 render_passes_in_draw_order_
.clear();
1459 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1462 transform_causing_aa
);
1464 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1470 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1472 renderer_
->DecideRenderPassAllocationsForFrame(
1473 render_passes_in_draw_order_
);
1474 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1479 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium
, blend_mode
);
1481 // RenderPassMaskProgram
1482 render_passes_in_draw_order_
.clear();
1484 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1489 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1494 AddRenderPassQuad(root_pass
,
1501 renderer_
->DecideRenderPassAllocationsForFrame(
1502 render_passes_in_draw_order_
);
1503 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1508 TestRenderPassMaskProgram(
1509 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1511 // RenderPassMaskColorMatrixProgram
1512 render_passes_in_draw_order_
.clear();
1514 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1519 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1525 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1527 renderer_
->DecideRenderPassAllocationsForFrame(
1528 render_passes_in_draw_order_
);
1529 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1534 TestRenderPassMaskColorMatrixProgram(
1535 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1537 // RenderPassProgramAA
1538 render_passes_in_draw_order_
.clear();
1540 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1543 transform_causing_aa
);
1545 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1550 AddRenderPassQuad(root_pass
,
1554 transform_causing_aa
,
1557 renderer_
->DecideRenderPassAllocationsForFrame(
1558 render_passes_in_draw_order_
);
1559 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1564 TestRenderPassProgramAA(TexCoordPrecisionMedium
, blend_mode
);
1566 // RenderPassColorMatrixProgramAA
1567 render_passes_in_draw_order_
.clear();
1569 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1572 transform_causing_aa
);
1574 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1580 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1582 renderer_
->DecideRenderPassAllocationsForFrame(
1583 render_passes_in_draw_order_
);
1584 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1589 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium
, blend_mode
);
1591 // RenderPassMaskProgramAA
1592 render_passes_in_draw_order_
.clear();
1594 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1597 transform_causing_aa
);
1599 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1604 AddRenderPassQuad(root_pass
,
1608 transform_causing_aa
,
1611 renderer_
->DecideRenderPassAllocationsForFrame(
1612 render_passes_in_draw_order_
);
1613 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1618 TestRenderPassMaskProgramAA(
1619 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1621 // RenderPassMaskColorMatrixProgramAA
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_
,
1632 transform_causing_aa
);
1635 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1637 renderer_
->DecideRenderPassAllocationsForFrame(
1638 render_passes_in_draw_order_
);
1639 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1644 TestRenderPassMaskColorMatrixProgramAA(
1645 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1649 // At this time, the AA code path cannot be taken if the surface's rect would
1650 // project incorrectly by the given transform, because of w<0 clipping.
1651 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1652 gfx::Rect
child_rect(50, 50);
1653 RenderPassId
child_pass_id(2, 0);
1654 TestRenderPass
* child_pass
;
1656 gfx::Rect
viewport_rect(1, 1);
1657 RenderPassId
root_pass_id(1, 0);
1658 TestRenderPass
* root_pass
;
1660 gfx::Transform transform_preventing_aa
;
1661 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1662 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1663 transform_preventing_aa
.Scale(30.0, 1.0);
1665 // Verify that the test transform and test rect actually do cause the clipped
1666 // flag to trigger. Otherwise we are not testing the intended scenario.
1667 bool clipped
= false;
1668 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1669 ASSERT_TRUE(clipped
);
1671 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1674 transform_preventing_aa
);
1676 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1681 AddRenderPassQuad(root_pass
,
1685 transform_preventing_aa
,
1686 SkXfermode::kSrcOver_Mode
);
1688 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1689 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1695 // If use_aa incorrectly ignores clipping, it will use the
1696 // RenderPassProgramAA shader instead of the RenderPassProgram.
1697 TestRenderPassProgram(TexCoordPrecisionMedium
, BlendModeNone
);
1700 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1701 gfx::Rect
viewport_rect(1, 1);
1702 RenderPassId
root_pass_id(1, 0);
1703 TestRenderPass
* root_pass
;
1705 gfx::Transform pixel_aligned_transform_causing_aa
;
1706 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1707 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1709 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1713 AddTransformedQuad(root_pass
,
1716 pixel_aligned_transform_causing_aa
);
1718 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1719 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1725 TestSolidColorProgramAA();
1728 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1730 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1732 // Specifically override methods even if they are unused (used in conjunction
1733 // with StrictMock). We need to make sure that GLRenderer does not issue
1734 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1735 // through the OutputSurface abstraction.
1736 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1737 MOCK_METHOD3(reshapeWithScaleFactor
,
1738 void(int width
, int height
, float scale_factor
));
1739 MOCK_METHOD4(drawElements
,
1740 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1743 class MockOutputSurface
: public OutputSurface
{
1747 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1748 new StrictMock
<OutputSurfaceMockContext
>))) {
1749 surface_size_
= gfx::Size(100, 100);
1751 virtual ~MockOutputSurface() {}
1753 MOCK_METHOD0(EnsureBackbuffer
, void());
1754 MOCK_METHOD0(DiscardBackbuffer
, void());
1755 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1756 MOCK_METHOD0(BindFramebuffer
, void());
1757 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1760 class MockOutputSurfaceTest
: public GLRendererTest
{
1762 virtual void SetUp() {
1763 FakeOutputSurfaceClient output_surface_client_
;
1764 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1766 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1767 resource_provider_
= ResourceProvider::Create(&output_surface_
,
1768 shared_bitmap_manager_
.get(),
1775 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1778 resource_provider_
.get()));
1781 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1783 void DrawFrame(float device_scale_factor
,
1784 const gfx::Rect
& device_viewport_rect
) {
1785 RenderPassId
render_pass_id(1, 0);
1786 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1788 device_viewport_rect
,
1790 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1792 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1794 EXPECT_CALL(output_surface_
,
1795 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1798 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1800 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1802 renderer_
->DecideRenderPassAllocationsForFrame(
1803 render_passes_in_draw_order_
);
1804 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1805 device_scale_factor
,
1806 device_viewport_rect
,
1807 device_viewport_rect
,
1811 OutputSurfaceMockContext
* Context() {
1812 return static_cast<OutputSurfaceMockContext
*>(
1813 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1817 RendererSettings settings_
;
1818 FakeOutputSurfaceClient output_surface_client_
;
1819 StrictMock
<MockOutputSurface
> output_surface_
;
1820 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1821 scoped_ptr
<ResourceProvider
> resource_provider_
;
1822 FakeRendererClient renderer_client_
;
1823 scoped_ptr
<FakeRendererGL
> renderer_
;
1826 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1827 gfx::Rect
device_viewport_rect(1, 1);
1828 DrawFrame(1.f
, device_viewport_rect
);
1830 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1831 renderer_
->SwapBuffers(CompositorFrameMetadata());
1834 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1835 gfx::Rect
device_viewport_rect(1, 1);
1837 DrawFrame(1.f
, device_viewport_rect
);
1838 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1839 renderer_
->SwapBuffers(CompositorFrameMetadata());
1841 device_viewport_rect
= gfx::Rect(2, 2);
1843 DrawFrame(2.f
, device_viewport_rect
);
1844 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1845 renderer_
->SwapBuffers(CompositorFrameMetadata());
1847 DrawFrame(2.f
, device_viewport_rect
);
1848 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1849 renderer_
->SwapBuffers(CompositorFrameMetadata());
1851 device_viewport_rect
= gfx::Rect(1, 1);
1853 DrawFrame(1.f
, device_viewport_rect
);
1854 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1855 renderer_
->SwapBuffers(CompositorFrameMetadata());
1858 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1860 static void SyncPointCallback(int* callback_count
) {
1861 ++(*callback_count
);
1862 base::MessageLoop::current()->QuitWhenIdle();
1865 static void OtherCallback(int* callback_count
) {
1866 ++(*callback_count
);
1867 base::MessageLoop::current()->QuitWhenIdle();
1871 #if !defined(OS_ANDROID)
1872 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1873 int sync_point_callback_count
= 0;
1874 int other_callback_count
= 0;
1875 gpu::gles2::GLES2Interface
* gl
=
1876 output_surface_
->context_provider()->ContextGL();
1877 gpu::ContextSupport
* context_support
=
1878 output_surface_
->context_provider()->ContextSupport();
1880 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1882 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1883 GL_INNOCENT_CONTEXT_RESET_ARB
);
1885 context_support
->SignalSyncPoint(
1886 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1887 EXPECT_EQ(0, sync_point_callback_count
);
1888 EXPECT_EQ(0, other_callback_count
);
1890 // Make the sync point happen.
1892 // Post a task after the sync point.
1893 base::MessageLoop::current()->PostTask(
1894 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1896 base::MessageLoop::current()->Run();
1898 // The sync point shouldn't have happened since the context was lost.
1899 EXPECT_EQ(0, sync_point_callback_count
);
1900 EXPECT_EQ(1, other_callback_count
);
1903 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1904 int sync_point_callback_count
= 0;
1905 int other_callback_count
= 0;
1907 gpu::gles2::GLES2Interface
* gl
=
1908 output_surface_
->context_provider()->ContextGL();
1909 gpu::ContextSupport
* context_support
=
1910 output_surface_
->context_provider()->ContextSupport();
1912 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1914 context_support
->SignalSyncPoint(
1915 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1916 EXPECT_EQ(0, sync_point_callback_count
);
1917 EXPECT_EQ(0, other_callback_count
);
1919 // Make the sync point happen.
1921 // Post a task after the sync point.
1922 base::MessageLoop::current()->PostTask(
1923 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1925 base::MessageLoop::current()->Run();
1927 // The sync point should have happened.
1928 EXPECT_EQ(1, sync_point_callback_count
);
1929 EXPECT_EQ(1, other_callback_count
);
1931 #endif // OS_ANDROID