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(GLRendererTest
, DrawFramePreservesFramebuffer
) {
1382 // When using render-to-FBO to display the surface, all rendering is done
1383 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1384 // the correct framebuffer during rendering, if changed.
1385 // Note: there is one path that will set it to 0, but that is after the render
1387 FakeOutputSurfaceClient output_surface_client
;
1388 scoped_ptr
<FakeOutputSurface
> output_surface(
1389 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1390 CHECK(output_surface
->BindToClient(&output_surface_client
));
1392 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1393 new TestSharedBitmapManager());
1394 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1395 output_surface
.get(), shared_bitmap_manager
.get(), NULL
, NULL
, 0, false,
1398 RendererSettings settings
;
1399 FakeRendererClient renderer_client
;
1400 FakeRendererGL
renderer(&renderer_client
, &settings
, output_surface
.get(),
1401 resource_provider
.get());
1402 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1404 gfx::Rect
device_viewport_rect(0, 0, 100, 100);
1405 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1406 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1408 RenderPassId
root_pass_id(1, 0);
1409 TestRenderPass
* root_pass
=
1410 AddRenderPass(&render_passes_in_draw_order_
, root_pass_id
, viewport_rect
,
1412 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1415 gpu::gles2::GLES2Interface
* gl
=
1416 output_surface
->context_provider()->ContextGL();
1417 gl
->GenFramebuffers(1, &fbo
);
1418 output_surface
->set_framebuffer(fbo
);
1420 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1421 renderer
.DrawFrame(&render_passes_in_draw_order_
, 1.f
, device_viewport_rect
,
1422 device_viewport_rect
, false);
1425 gl
->GetIntegerv(GL_FRAMEBUFFER_BINDING
, &bound_fbo
);
1426 EXPECT_EQ(static_cast<int>(fbo
), bound_fbo
);
1429 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1430 gfx::Rect
viewport_rect(1, 1);
1432 gfx::Rect
child_rect(50, 50);
1433 RenderPassId
child_pass_id(2, 0);
1434 TestRenderPass
* child_pass
;
1436 RenderPassId
root_pass_id(1, 0);
1437 TestRenderPass
* root_pass
;
1439 ResourceProvider::ResourceId mask
= resource_provider_
->CreateResource(
1442 ResourceProvider::TextureHintImmutable
,
1443 resource_provider_
->best_texture_format());
1444 resource_provider_
->AllocateForTesting(mask
);
1446 SkScalar matrix
[20];
1447 float amount
= 0.5f
;
1448 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1449 matrix
[1] = 0.715f
- 0.715f
* amount
;
1450 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1451 matrix
[3] = matrix
[4] = 0;
1452 matrix
[5] = 0.213f
- 0.213f
* amount
;
1453 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1454 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1455 matrix
[8] = matrix
[9] = 0;
1456 matrix
[10] = 0.213f
- 0.213f
* amount
;
1457 matrix
[11] = 0.715f
- 0.715f
* amount
;
1458 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1459 matrix
[13] = matrix
[14] = 0;
1460 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1462 skia::RefPtr
<SkColorFilter
> color_filter(
1463 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1464 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1465 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1466 FilterOperations filters
;
1467 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1469 gfx::Transform transform_causing_aa
;
1470 transform_causing_aa
.Rotate(20.0);
1472 for (int i
= 0; i
< NumBlendModes
; ++i
) {
1473 BlendMode blend_mode
= static_cast<BlendMode
>(i
);
1474 SkXfermode::Mode xfer_mode
= BlendModeToSkXfermode(blend_mode
);
1475 settings_
.force_blending_with_shaders
= (blend_mode
!= BlendModeNone
);
1476 // RenderPassProgram
1477 render_passes_in_draw_order_
.clear();
1478 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1483 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1488 AddRenderPassQuad(root_pass
,
1495 renderer_
->DecideRenderPassAllocationsForFrame(
1496 render_passes_in_draw_order_
);
1497 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1502 TestRenderPassProgram(TexCoordPrecisionMedium
, blend_mode
);
1504 // RenderPassColorMatrixProgram
1505 render_passes_in_draw_order_
.clear();
1507 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1510 transform_causing_aa
);
1512 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1518 root_pass
, child_pass
, 0, filters
, gfx::Transform(), xfer_mode
);
1520 renderer_
->DecideRenderPassAllocationsForFrame(
1521 render_passes_in_draw_order_
);
1522 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1527 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium
, blend_mode
);
1529 // RenderPassMaskProgram
1530 render_passes_in_draw_order_
.clear();
1532 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1537 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1542 AddRenderPassQuad(root_pass
,
1549 renderer_
->DecideRenderPassAllocationsForFrame(
1550 render_passes_in_draw_order_
);
1551 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1556 TestRenderPassMaskProgram(
1557 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1559 // RenderPassMaskColorMatrixProgram
1560 render_passes_in_draw_order_
.clear();
1562 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1567 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1573 root_pass
, child_pass
, mask
, filters
, gfx::Transform(), xfer_mode
);
1575 renderer_
->DecideRenderPassAllocationsForFrame(
1576 render_passes_in_draw_order_
);
1577 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1582 TestRenderPassMaskColorMatrixProgram(
1583 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1585 // RenderPassProgramAA
1586 render_passes_in_draw_order_
.clear();
1588 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1591 transform_causing_aa
);
1593 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1598 AddRenderPassQuad(root_pass
,
1602 transform_causing_aa
,
1605 renderer_
->DecideRenderPassAllocationsForFrame(
1606 render_passes_in_draw_order_
);
1607 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1612 TestRenderPassProgramAA(TexCoordPrecisionMedium
, blend_mode
);
1614 // RenderPassColorMatrixProgramAA
1615 render_passes_in_draw_order_
.clear();
1617 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1620 transform_causing_aa
);
1622 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1628 root_pass
, child_pass
, 0, filters
, transform_causing_aa
, xfer_mode
);
1630 renderer_
->DecideRenderPassAllocationsForFrame(
1631 render_passes_in_draw_order_
);
1632 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1637 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium
, blend_mode
);
1639 // RenderPassMaskProgramAA
1640 render_passes_in_draw_order_
.clear();
1642 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1645 transform_causing_aa
);
1647 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1652 AddRenderPassQuad(root_pass
,
1656 transform_causing_aa
,
1659 renderer_
->DecideRenderPassAllocationsForFrame(
1660 render_passes_in_draw_order_
);
1661 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1666 TestRenderPassMaskProgramAA(
1667 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1669 // RenderPassMaskColorMatrixProgramAA
1670 render_passes_in_draw_order_
.clear();
1672 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1675 transform_causing_aa
);
1677 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1680 transform_causing_aa
);
1683 root_pass
, child_pass
, mask
, filters
, transform_causing_aa
, xfer_mode
);
1685 renderer_
->DecideRenderPassAllocationsForFrame(
1686 render_passes_in_draw_order_
);
1687 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1692 TestRenderPassMaskColorMatrixProgramAA(
1693 TexCoordPrecisionMedium
, SamplerType2D
, blend_mode
);
1697 // At this time, the AA code path cannot be taken if the surface's rect would
1698 // project incorrectly by the given transform, because of w<0 clipping.
1699 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1700 gfx::Rect
child_rect(50, 50);
1701 RenderPassId
child_pass_id(2, 0);
1702 TestRenderPass
* child_pass
;
1704 gfx::Rect
viewport_rect(1, 1);
1705 RenderPassId
root_pass_id(1, 0);
1706 TestRenderPass
* root_pass
;
1708 gfx::Transform transform_preventing_aa
;
1709 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1710 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1711 transform_preventing_aa
.Scale(30.0, 1.0);
1713 // Verify that the test transform and test rect actually do cause the clipped
1714 // flag to trigger. Otherwise we are not testing the intended scenario.
1715 bool clipped
= false;
1716 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1717 ASSERT_TRUE(clipped
);
1719 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1722 transform_preventing_aa
);
1724 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1729 AddRenderPassQuad(root_pass
,
1733 transform_preventing_aa
,
1734 SkXfermode::kSrcOver_Mode
);
1736 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1737 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1743 // If use_aa incorrectly ignores clipping, it will use the
1744 // RenderPassProgramAA shader instead of the RenderPassProgram.
1745 TestRenderPassProgram(TexCoordPrecisionMedium
, BlendModeNone
);
1748 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1749 gfx::Rect
viewport_rect(1, 1);
1750 RenderPassId
root_pass_id(1, 0);
1751 TestRenderPass
* root_pass
;
1753 gfx::Transform pixel_aligned_transform_causing_aa
;
1754 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1755 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1757 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1761 AddTransformedQuad(root_pass
,
1764 pixel_aligned_transform_causing_aa
);
1766 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1767 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1773 TestSolidColorProgramAA();
1776 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1778 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1780 // Specifically override methods even if they are unused (used in conjunction
1781 // with StrictMock). We need to make sure that GLRenderer does not issue
1782 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1783 // through the OutputSurface abstraction.
1784 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1785 MOCK_METHOD3(reshapeWithScaleFactor
,
1786 void(int width
, int height
, float scale_factor
));
1787 MOCK_METHOD4(drawElements
,
1788 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1791 class MockOutputSurface
: public OutputSurface
{
1795 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1796 new StrictMock
<OutputSurfaceMockContext
>))) {
1797 surface_size_
= gfx::Size(100, 100);
1799 virtual ~MockOutputSurface() {}
1801 MOCK_METHOD0(EnsureBackbuffer
, void());
1802 MOCK_METHOD0(DiscardBackbuffer
, void());
1803 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1804 MOCK_METHOD0(BindFramebuffer
, void());
1805 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1808 class MockOutputSurfaceTest
: public GLRendererTest
{
1810 virtual void SetUp() {
1811 FakeOutputSurfaceClient output_surface_client_
;
1812 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1814 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1815 resource_provider_
= ResourceProvider::Create(&output_surface_
,
1816 shared_bitmap_manager_
.get(),
1823 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1826 resource_provider_
.get()));
1829 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1831 void DrawFrame(float device_scale_factor
,
1832 const gfx::Rect
& device_viewport_rect
) {
1833 RenderPassId
render_pass_id(1, 0);
1834 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1836 device_viewport_rect
,
1838 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1840 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1842 EXPECT_CALL(output_surface_
,
1843 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1846 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1848 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1850 renderer_
->DecideRenderPassAllocationsForFrame(
1851 render_passes_in_draw_order_
);
1852 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1853 device_scale_factor
,
1854 device_viewport_rect
,
1855 device_viewport_rect
,
1859 OutputSurfaceMockContext
* Context() {
1860 return static_cast<OutputSurfaceMockContext
*>(
1861 static_cast<TestContextProvider
*>(output_surface_
.context_provider())
1865 RendererSettings settings_
;
1866 FakeOutputSurfaceClient output_surface_client_
;
1867 StrictMock
<MockOutputSurface
> output_surface_
;
1868 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1869 scoped_ptr
<ResourceProvider
> resource_provider_
;
1870 FakeRendererClient renderer_client_
;
1871 scoped_ptr
<FakeRendererGL
> renderer_
;
1874 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1875 gfx::Rect
device_viewport_rect(1, 1);
1876 DrawFrame(1.f
, device_viewport_rect
);
1878 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1879 renderer_
->SwapBuffers(CompositorFrameMetadata());
1882 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1883 gfx::Rect
device_viewport_rect(1, 1);
1885 DrawFrame(1.f
, device_viewport_rect
);
1886 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1887 renderer_
->SwapBuffers(CompositorFrameMetadata());
1889 device_viewport_rect
= gfx::Rect(2, 2);
1891 DrawFrame(2.f
, device_viewport_rect
);
1892 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1893 renderer_
->SwapBuffers(CompositorFrameMetadata());
1895 DrawFrame(2.f
, device_viewport_rect
);
1896 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1897 renderer_
->SwapBuffers(CompositorFrameMetadata());
1899 device_viewport_rect
= gfx::Rect(1, 1);
1901 DrawFrame(1.f
, device_viewport_rect
);
1902 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1903 renderer_
->SwapBuffers(CompositorFrameMetadata());
1906 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1908 static void SyncPointCallback(int* callback_count
) {
1909 ++(*callback_count
);
1910 base::MessageLoop::current()->QuitWhenIdle();
1913 static void OtherCallback(int* callback_count
) {
1914 ++(*callback_count
);
1915 base::MessageLoop::current()->QuitWhenIdle();
1919 #if !defined(OS_ANDROID)
1920 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1921 int sync_point_callback_count
= 0;
1922 int other_callback_count
= 0;
1923 gpu::gles2::GLES2Interface
* gl
=
1924 output_surface_
->context_provider()->ContextGL();
1925 gpu::ContextSupport
* context_support
=
1926 output_surface_
->context_provider()->ContextSupport();
1928 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1930 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1931 GL_INNOCENT_CONTEXT_RESET_ARB
);
1933 context_support
->SignalSyncPoint(
1934 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1935 EXPECT_EQ(0, sync_point_callback_count
);
1936 EXPECT_EQ(0, other_callback_count
);
1938 // Make the sync point happen.
1940 // Post a task after the sync point.
1941 base::MessageLoop::current()->PostTask(
1942 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1944 base::MessageLoop::current()->Run();
1946 // The sync point shouldn't have happened since the context was lost.
1947 EXPECT_EQ(0, sync_point_callback_count
);
1948 EXPECT_EQ(1, other_callback_count
);
1951 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1952 int sync_point_callback_count
= 0;
1953 int other_callback_count
= 0;
1955 gpu::gles2::GLES2Interface
* gl
=
1956 output_surface_
->context_provider()->ContextGL();
1957 gpu::ContextSupport
* context_support
=
1958 output_surface_
->context_provider()->ContextSupport();
1960 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1962 context_support
->SignalSyncPoint(
1963 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1964 EXPECT_EQ(0, sync_point_callback_count
);
1965 EXPECT_EQ(0, other_callback_count
);
1967 // Make the sync point happen.
1969 // Post a task after the sync point.
1970 base::MessageLoop::current()->PostTask(
1971 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1973 base::MessageLoop::current()->Run();
1975 // The sync point should have happened.
1976 EXPECT_EQ(1, sync_point_callback_count
);
1977 EXPECT_EQ(1, other_callback_count
);
1979 #endif // OS_ANDROID