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 // Explicitly named to be a friend in GLRenderer for shader access.
59 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
62 ASSERT_FALSE(renderer()->IsContextLost());
63 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
64 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
65 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
66 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
67 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium
);
68 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh
);
69 ASSERT_FALSE(renderer()->IsContextLost());
72 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision
) {
73 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision
));
74 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision
));
75 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision
));
76 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision
));
78 renderer()->GetRenderPassColorMatrixProgram(precision
));
80 renderer()->GetRenderPassMaskColorMatrixProgramAA(precision
));
82 renderer()->GetRenderPassColorMatrixProgramAA(precision
));
84 renderer()->GetRenderPassMaskColorMatrixProgram(precision
));
85 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
));
87 renderer()->GetNonPremultipliedTextureProgram(precision
));
88 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision
));
90 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
));
91 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
92 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
));
93 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
));
94 // This is unlikely to be ever true in tests due to usage of osmesa.
95 if (renderer()->Capabilities().using_egl_image
)
96 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
98 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
99 TestShadersWithSamplerType(precision
, SamplerType2D
);
100 TestShadersWithSamplerType(precision
, SamplerType2DRect
);
101 // This is unlikely to be ever true in tests due to usage of osmesa.
102 if (renderer()->Capabilities().using_egl_image
)
103 TestShadersWithSamplerType(precision
, SamplerTypeExternalOES
);
106 void TestShadersWithSamplerType(TexCoordPrecision precision
,
107 SamplerType sampler
) {
108 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
109 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
110 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
111 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
112 EXPECT_PROGRAM_VALID(
113 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
114 EXPECT_PROGRAM_VALID(
115 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
121 #if !defined(OS_ANDROID)
122 TEST_F(GLRendererShaderPixelTest
, AllShadersCompile
) { TestShaders(); }
125 class FakeRendererGL
: public GLRenderer
{
127 FakeRendererGL(RendererClient
* client
,
128 const LayerTreeSettings
* settings
,
129 OutputSurface
* output_surface
,
130 ResourceProvider
* resource_provider
)
138 // GLRenderer methods.
140 // Changing visibility to public.
141 using GLRenderer::IsBackbufferDiscarded
;
142 using GLRenderer::DoDrawQuad
;
143 using GLRenderer::BeginDrawingFrame
;
144 using GLRenderer::FinishDrawingQuadList
;
145 using GLRenderer::stencil_enabled
;
148 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
150 GLRendererWithDefaultHarnessTest() {
152 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
153 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
155 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
157 ResourceProvider::Create(
158 output_surface_
.get(), shared_bitmap_manager_
.get(), 0, false, 1,
160 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
162 output_surface_
.get(),
163 resource_provider_
.get()));
166 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
168 LayerTreeSettings settings_
;
169 FakeOutputSurfaceClient output_surface_client_
;
170 scoped_ptr
<FakeOutputSurface
> output_surface_
;
171 FakeRendererClient renderer_client_
;
172 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
173 scoped_ptr
<ResourceProvider
> resource_provider_
;
174 scoped_ptr
<FakeRendererGL
> renderer_
;
177 // Closing the namespace here so that GLRendererShaderTest can take advantage
178 // of the friend relationship with GLRenderer and all of the mock classes
179 // declared above it.
182 class GLRendererShaderTest
: public GLRendererTest
{
184 GLRendererShaderTest() {
185 output_surface_
= FakeOutputSurface::Create3d().Pass();
186 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
188 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
190 ResourceProvider::Create(
191 output_surface_
.get(), shared_bitmap_manager_
.get(), 0, false, 1,
193 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
195 output_surface_
.get(),
196 resource_provider_
.get()));
199 void TestRenderPassProgram(TexCoordPrecision precision
) {
200 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_program_
[precision
]);
201 EXPECT_EQ(renderer_
->render_pass_program_
[precision
].program(),
202 renderer_
->program_shadow_
);
205 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
) {
206 EXPECT_PROGRAM_VALID(
207 &renderer_
->render_pass_color_matrix_program_
[precision
]);
208 EXPECT_EQ(renderer_
->render_pass_color_matrix_program_
[precision
].program(),
209 renderer_
->program_shadow_
);
212 void TestRenderPassMaskProgram(TexCoordPrecision precision
) {
213 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_program_
[precision
]);
214 EXPECT_EQ(renderer_
->render_pass_mask_program_
[precision
].program(),
215 renderer_
->program_shadow_
);
218 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
) {
219 EXPECT_PROGRAM_VALID(
220 &renderer_
->render_pass_mask_color_matrix_program_
[precision
]);
222 renderer_
->render_pass_mask_color_matrix_program_
[precision
].program(),
223 renderer_
->program_shadow_
);
226 void TestRenderPassProgramAA(TexCoordPrecision precision
) {
227 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_program_aa_
[precision
]);
228 EXPECT_EQ(renderer_
->render_pass_program_aa_
[precision
].program(),
229 renderer_
->program_shadow_
);
232 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
) {
233 EXPECT_PROGRAM_VALID(
234 &renderer_
->render_pass_color_matrix_program_aa_
[precision
]);
236 renderer_
->render_pass_color_matrix_program_aa_
[precision
].program(),
237 renderer_
->program_shadow_
);
240 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
) {
241 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_program_aa_
[precision
]);
242 EXPECT_EQ(renderer_
->render_pass_mask_program_aa_
[precision
].program(),
243 renderer_
->program_shadow_
);
246 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
) {
247 EXPECT_PROGRAM_VALID(
248 &renderer_
->render_pass_mask_color_matrix_program_aa_
[precision
]);
249 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
[precision
]
251 renderer_
->program_shadow_
);
254 void TestSolidColorProgramAA() {
255 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
256 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
257 renderer_
->program_shadow_
);
260 LayerTreeSettings settings_
;
261 FakeOutputSurfaceClient output_surface_client_
;
262 scoped_ptr
<FakeOutputSurface
> output_surface_
;
263 FakeRendererClient renderer_client_
;
264 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
265 scoped_ptr
<ResourceProvider
> resource_provider_
;
266 scoped_ptr
<FakeRendererGL
> renderer_
;
271 // Test GLRenderer DiscardBackbuffer functionality:
272 // Suggest discarding framebuffer when one exists and the renderer is not
274 // Expected: it is discarded and damage tracker is reset.
276 GLRendererWithDefaultHarnessTest
,
277 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
278 renderer_
->SetVisible(false);
279 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
280 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
283 // Test GLRenderer DiscardBackbuffer functionality:
284 // Suggest discarding framebuffer when one exists and the renderer is visible.
285 // Expected: the allocation is ignored.
286 TEST_F(GLRendererWithDefaultHarnessTest
,
287 SuggestBackbufferNoDoNothingWhenVisible
) {
288 renderer_
->SetVisible(true);
289 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
290 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
293 // Test GLRenderer DiscardBackbuffer functionality:
294 // Suggest discarding framebuffer when one does not exist.
295 // Expected: it does nothing.
296 TEST_F(GLRendererWithDefaultHarnessTest
,
297 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
298 renderer_
->SetVisible(false);
299 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
300 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
302 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
303 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
306 // Test GLRenderer DiscardBackbuffer functionality:
307 // Begin drawing a frame while a framebuffer is discarded.
308 // Expected: will recreate framebuffer.
309 TEST_F(GLRendererWithDefaultHarnessTest
,
310 DiscardedBackbufferIsRecreatedForScopeDuration
) {
311 gfx::Rect
viewport_rect(1, 1);
312 renderer_
->SetVisible(false);
313 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
314 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
316 AddRenderPass(&render_passes_in_draw_order_
,
321 renderer_
->SetVisible(true);
322 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
327 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
330 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
333 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
334 gfx::Rect
viewport_rect(1, 1);
335 EXPECT_FALSE(renderer_
->stencil_enabled());
337 output_surface_
->set_has_external_stencil_test(true);
339 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
343 root_pass
->has_transparent_background
= false;
345 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
350 EXPECT_TRUE(renderer_
->stencil_enabled());
353 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
355 ForbidSynchronousCallContext() {}
357 virtual void getAttachedShaders(GLuint program
,
360 GLuint
* shaders
) OVERRIDE
{
363 virtual GLint
getAttribLocation(GLuint program
, const GLchar
* name
) OVERRIDE
{
367 virtual void getBooleanv(GLenum pname
, GLboolean
* value
) OVERRIDE
{
370 virtual void getBufferParameteriv(GLenum target
,
372 GLint
* value
) OVERRIDE
{
375 virtual GLenum
getError() OVERRIDE
{
379 virtual void getFloatv(GLenum pname
, GLfloat
* value
) OVERRIDE
{
382 virtual void getFramebufferAttachmentParameteriv(GLenum target
,
385 GLint
* value
) OVERRIDE
{
388 virtual void getIntegerv(GLenum pname
, GLint
* value
) OVERRIDE
{
389 if (pname
== GL_MAX_TEXTURE_SIZE
) {
390 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
397 // We allow querying the shader compilation and program link status in debug
398 // mode, but not release.
399 virtual void getProgramiv(GLuint program
,
401 GLint
* value
) OVERRIDE
{
409 virtual void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) OVERRIDE
{
417 virtual void getRenderbufferParameteriv(GLenum target
,
419 GLint
* value
) OVERRIDE
{
423 virtual void getShaderPrecisionFormat(GLenum shadertype
,
424 GLenum precisiontype
,
426 GLint
* precision
) OVERRIDE
{
429 virtual void getTexParameterfv(GLenum target
,
431 GLfloat
* value
) OVERRIDE
{
434 virtual void getTexParameteriv(GLenum target
,
436 GLint
* value
) OVERRIDE
{
439 virtual void getUniformfv(GLuint program
,
441 GLfloat
* value
) OVERRIDE
{
444 virtual void getUniformiv(GLuint program
,
446 GLint
* value
) OVERRIDE
{
449 virtual GLint
getUniformLocation(GLuint program
,
450 const GLchar
* name
) OVERRIDE
{
454 virtual void getVertexAttribfv(GLuint index
,
456 GLfloat
* value
) OVERRIDE
{
459 virtual void getVertexAttribiv(GLuint index
,
461 GLint
* value
) OVERRIDE
{
464 virtual GLsizeiptr
getVertexAttribOffset(GLuint index
,
465 GLenum pname
) OVERRIDE
{
470 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
471 FakeOutputSurfaceClient output_surface_client
;
472 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
473 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
474 CHECK(output_surface
->BindToClient(&output_surface_client
));
476 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
477 new TestSharedBitmapManager());
478 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
479 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
481 LayerTreeSettings settings
;
482 FakeRendererClient renderer_client
;
483 FakeRendererGL
renderer(&renderer_client
,
485 output_surface
.get(),
486 resource_provider
.get());
489 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
491 LoseContextOnFirstGetContext() {}
493 virtual void getProgramiv(GLuint program
,
495 GLint
* value
) OVERRIDE
{
496 context_lost_
= true;
500 virtual void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) OVERRIDE
{
501 context_lost_
= true;
506 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
507 FakeOutputSurfaceClient output_surface_client
;
508 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
509 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
510 CHECK(output_surface
->BindToClient(&output_surface_client
));
512 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
513 new TestSharedBitmapManager());
514 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
515 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
517 LayerTreeSettings settings
;
518 FakeRendererClient renderer_client
;
519 FakeRendererGL
renderer(&renderer_client
,
521 output_surface
.get(),
522 resource_provider
.get());
525 class ClearCountingContext
: public TestWebGraphicsContext3D
{
527 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
529 MOCK_METHOD3(discardFramebufferEXT
,
531 GLsizei numAttachments
,
532 const GLenum
* attachments
));
533 MOCK_METHOD1(clear
, void(GLbitfield mask
));
536 TEST_F(GLRendererTest
, OpaqueBackground
) {
537 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
538 ClearCountingContext
* context
= context_owned
.get();
540 FakeOutputSurfaceClient output_surface_client
;
541 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
542 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
543 CHECK(output_surface
->BindToClient(&output_surface_client
));
545 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
546 new TestSharedBitmapManager());
547 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
548 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
550 LayerTreeSettings settings
;
551 FakeRendererClient renderer_client
;
552 FakeRendererGL
renderer(&renderer_client
,
554 output_surface
.get(),
555 resource_provider
.get());
557 gfx::Rect
viewport_rect(1, 1);
558 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
562 root_pass
->has_transparent_background
= false;
564 // On DEBUG builds, render passes with opaque background clear to blue to
565 // easily see regions that were not drawn on the screen.
566 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
567 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
570 EXPECT_CALL(*context
, clear(_
)).Times(0);
572 EXPECT_CALL(*context
, clear(_
)).Times(1);
574 renderer
.DrawFrame(&render_passes_in_draw_order_
,
579 Mock::VerifyAndClearExpectations(context
);
582 TEST_F(GLRendererTest
, TransparentBackground
) {
583 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
584 ClearCountingContext
* context
= context_owned
.get();
586 FakeOutputSurfaceClient output_surface_client
;
587 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
588 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
589 CHECK(output_surface
->BindToClient(&output_surface_client
));
591 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
592 new TestSharedBitmapManager());
593 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
594 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
596 LayerTreeSettings settings
;
597 FakeRendererClient renderer_client
;
598 FakeRendererGL
renderer(&renderer_client
,
600 output_surface
.get(),
601 resource_provider
.get());
603 gfx::Rect
viewport_rect(1, 1);
604 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
608 root_pass
->has_transparent_background
= true;
610 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
611 EXPECT_CALL(*context
, clear(_
)).Times(1);
612 renderer
.DrawFrame(&render_passes_in_draw_order_
,
618 Mock::VerifyAndClearExpectations(context
);
621 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
622 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
623 ClearCountingContext
* context
= context_owned
.get();
625 FakeOutputSurfaceClient output_surface_client
;
626 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::CreateOffscreen(
627 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
628 CHECK(output_surface
->BindToClient(&output_surface_client
));
630 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
631 new TestSharedBitmapManager());
632 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
633 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
635 LayerTreeSettings settings
;
636 FakeRendererClient renderer_client
;
637 FakeRendererGL
renderer(&renderer_client
,
639 output_surface
.get(),
640 resource_provider
.get());
642 gfx::Rect
viewport_rect(1, 1);
643 AddRenderPass(&render_passes_in_draw_order_
,
648 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
649 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
651 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
652 renderer
.DrawFrame(&render_passes_in_draw_order_
,
657 Mock::VerifyAndClearExpectations(context
);
660 class VisibilityChangeIsLastCallTrackingContext
661 : public TestWebGraphicsContext3D
{
663 VisibilityChangeIsLastCallTrackingContext()
664 : last_call_was_set_visibility_(false) {}
666 // TestWebGraphicsContext3D methods.
667 virtual void flush() OVERRIDE
{ last_call_was_set_visibility_
= false; }
668 virtual void deleteTexture(GLuint
) OVERRIDE
{
669 last_call_was_set_visibility_
= false;
671 virtual void deleteFramebuffer(GLuint
) OVERRIDE
{
672 last_call_was_set_visibility_
= false;
674 virtual void deleteQueryEXT(GLuint
) OVERRIDE
{
675 last_call_was_set_visibility_
= false;
677 virtual void deleteRenderbuffer(GLuint
) OVERRIDE
{
678 last_call_was_set_visibility_
= false;
681 // Methods added for test.
682 void set_last_call_was_visibility(bool visible
) {
683 DCHECK(last_call_was_set_visibility_
== false);
684 last_call_was_set_visibility_
= true;
686 bool last_call_was_set_visibility() const {
687 return last_call_was_set_visibility_
;
691 bool last_call_was_set_visibility_
;
694 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
695 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
696 new VisibilityChangeIsLastCallTrackingContext
);
697 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
699 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create(
700 context_owned
.PassAs
<TestWebGraphicsContext3D
>());
702 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
703 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
704 base::Unretained(context
)));
706 FakeOutputSurfaceClient output_surface_client
;
707 scoped_ptr
<OutputSurface
> output_surface(
708 FakeOutputSurface::Create3d(provider
));
709 CHECK(output_surface
->BindToClient(&output_surface_client
));
711 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
712 new TestSharedBitmapManager());
713 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
714 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
716 LayerTreeSettings settings
;
717 FakeRendererClient renderer_client
;
718 FakeRendererGL
renderer(&renderer_client
,
720 output_surface
.get(),
721 resource_provider
.get());
723 gfx::Rect
viewport_rect(1, 1);
724 AddRenderPass(&render_passes_in_draw_order_
,
729 // Ensure that the call to SetSurfaceVisible is the last call issue to the
730 // GPU process, after glFlush is called, and after the RendererClient's
731 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
732 // RenderClient and the Context by giving them both a pointer to a variable on
734 renderer
.SetVisible(true);
735 renderer
.DrawFrame(&render_passes_in_draw_order_
,
740 renderer
.SetVisible(false);
741 EXPECT_TRUE(context
->last_call_was_set_visibility());
744 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
746 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
747 test_capabilities_
.gpu
.egl_image_external
= true;
750 MOCK_METHOD1(waitSyncPoint
, void(unsigned sync_point
));
751 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
752 MOCK_METHOD4(drawElements
,
753 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
755 virtual void activeTexture(GLenum texture
) {
756 EXPECT_NE(texture
, active_texture_
);
757 active_texture_
= texture
;
760 GLenum
active_texture() const { return active_texture_
; }
763 GLenum active_texture_
;
766 TEST_F(GLRendererTest
, ActiveTextureState
) {
767 scoped_ptr
<TextureStateTrackingContext
> context_owned(
768 new TextureStateTrackingContext
);
769 TextureStateTrackingContext
* context
= context_owned
.get();
771 FakeOutputSurfaceClient output_surface_client
;
772 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
773 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
774 CHECK(output_surface
->BindToClient(&output_surface_client
));
776 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
777 new TestSharedBitmapManager());
778 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
779 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
781 LayerTreeSettings settings
;
782 FakeRendererClient renderer_client
;
783 FakeRendererGL
renderer(&renderer_client
,
785 output_surface
.get(),
786 resource_provider
.get());
788 // During initialization we are allowed to set any texture parameters.
789 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
791 RenderPassId
id(1, 1);
792 TestRenderPass
* root_pass
= AddRenderPass(
793 &render_passes_in_draw_order_
, id
, gfx::Rect(100, 100), gfx::Transform());
794 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
797 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
799 // Set up expected texture filter state transitions that match the quads
800 // created in AppendOneOfEveryQuadType().
801 Mock::VerifyAndClearExpectations(context
);
805 // The sync points for all quads are waited on first. This sync point is
806 // for a texture quad drawn later in the frame.
807 EXPECT_CALL(*context
,
808 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad
))
811 // yuv_quad is drawn with the default linear filter.
812 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
814 // tile_quad is drawn with GL_NEAREST because it is not transformed or
818 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
821 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
822 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
824 // transformed_tile_quad uses GL_LINEAR.
825 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
827 // scaled_tile_quad also uses GL_LINEAR.
828 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
830 // The remaining quads also use GL_LINEAR because nearest neighbor
831 // filtering is currently only used with tile quads.
832 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(7);
835 gfx::Rect
viewport_rect(100, 100);
836 renderer
.DrawFrame(&render_passes_in_draw_order_
,
841 Mock::VerifyAndClearExpectations(context
);
844 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
846 MOCK_METHOD1(clear
, void(GLbitfield mask
));
847 MOCK_METHOD4(drawElements
,
848 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
851 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
852 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
853 new NoClearRootRenderPassMockContext
);
854 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
856 FakeOutputSurfaceClient output_surface_client
;
857 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
858 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
859 CHECK(output_surface
->BindToClient(&output_surface_client
));
861 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
862 new TestSharedBitmapManager());
863 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
864 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
866 LayerTreeSettings settings
;
867 settings
.should_clear_root_render_pass
= false;
869 FakeRendererClient renderer_client
;
870 FakeRendererGL
renderer(&renderer_client
,
872 output_surface
.get(),
873 resource_provider
.get());
875 gfx::Rect
viewport_rect(10, 10);
877 RenderPassId
root_pass_id(1, 0);
878 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
882 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
884 RenderPassId
child_pass_id(2, 0);
885 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
889 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
891 AddRenderPassQuad(root_pass
, child_pass
);
894 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
896 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
899 // First render pass is not the root one, clearing should happen.
900 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
902 Expectation first_render_pass
=
903 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
905 // The second render pass is the root one, clearing should be prevented.
906 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
909 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
912 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
913 renderer
.DrawFrame(&render_passes_in_draw_order_
,
919 // In multiple render passes all but the root pass should clear the
921 Mock::VerifyAndClearExpectations(&mock_context
);
924 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
926 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
928 virtual void clear(GLbitfield
) OVERRIDE
{ EXPECT_FALSE(scissor_enabled_
); }
930 virtual void enable(GLenum cap
) OVERRIDE
{
931 if (cap
== GL_SCISSOR_TEST
)
932 scissor_enabled_
= true;
935 virtual void disable(GLenum cap
) OVERRIDE
{
936 if (cap
== GL_SCISSOR_TEST
)
937 scissor_enabled_
= false;
941 bool scissor_enabled_
;
944 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
945 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
946 new ScissorTestOnClearCheckingContext
);
948 FakeOutputSurfaceClient output_surface_client
;
949 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
950 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
951 CHECK(output_surface
->BindToClient(&output_surface_client
));
953 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
954 new TestSharedBitmapManager());
955 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
956 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
958 LayerTreeSettings settings
;
959 FakeRendererClient renderer_client
;
960 FakeRendererGL
renderer(&renderer_client
,
962 output_surface
.get(),
963 resource_provider
.get());
964 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
966 gfx::Rect
viewport_rect(1, 1);
968 gfx::Rect
grand_child_rect(25, 25);
969 RenderPassId
grand_child_pass_id(3, 0);
970 TestRenderPass
* grand_child_pass
=
971 AddRenderPass(&render_passes_in_draw_order_
,
975 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
977 gfx::Rect
child_rect(50, 50);
978 RenderPassId
child_pass_id(2, 0);
979 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
983 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
985 RenderPassId
root_pass_id(1, 0);
986 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
990 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
992 AddRenderPassQuad(root_pass
, child_pass
);
993 AddRenderPassQuad(child_pass
, grand_child_pass
);
995 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
996 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1003 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1005 DiscardCheckingContext() : discarded_(0) {
1006 set_have_post_sub_buffer(true);
1007 set_have_discard_framebuffer(true);
1010 virtual void discardFramebufferEXT(GLenum target
,
1011 GLsizei numAttachments
,
1012 const GLenum
* attachments
) OVERRIDE
{
1016 int discarded() const { return discarded_
; }
1017 void reset() { discarded_
= 0; }
1023 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1025 explicit NonReshapableOutputSurface(
1026 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1027 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1029 surface_size_
= gfx::Size(500, 500);
1031 virtual void Reshape(const gfx::Size
& size
, float scale_factor
) OVERRIDE
{}
1032 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1035 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1036 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1037 DiscardCheckingContext
* context
= context_owned
.get();
1039 FakeOutputSurfaceClient output_surface_client
;
1040 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1041 new NonReshapableOutputSurface(
1042 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
1043 CHECK(output_surface
->BindToClient(&output_surface_client
));
1044 output_surface
->set_fixed_size(gfx::Size(100, 100));
1046 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1047 new TestSharedBitmapManager());
1048 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1049 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
1051 LayerTreeSettings settings
;
1052 settings
.partial_swap_enabled
= true;
1053 FakeRendererClient renderer_client
;
1054 FakeRendererGL
renderer(&renderer_client
,
1056 output_surface
.get(),
1057 resource_provider
.get());
1058 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1060 gfx::Rect
viewport_rect(100, 100);
1061 gfx::Rect
clip_rect(100, 100);
1064 // Partial frame, should not discard.
1065 RenderPassId
root_pass_id(1, 0);
1066 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1070 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1071 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1073 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1074 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1079 EXPECT_EQ(0, context
->discarded());
1083 // Full frame, should discard.
1084 RenderPassId
root_pass_id(1, 0);
1085 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1089 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1090 root_pass
->damage_rect
= root_pass
->output_rect
;
1092 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1093 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1098 EXPECT_EQ(1, context
->discarded());
1102 // Full frame, external scissor is set, should not discard.
1103 output_surface
->set_has_external_stencil_test(true);
1104 RenderPassId
root_pass_id(1, 0);
1105 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1109 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1110 root_pass
->damage_rect
= root_pass
->output_rect
;
1111 root_pass
->has_transparent_background
= false;
1113 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1114 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1119 EXPECT_EQ(0, context
->discarded());
1121 output_surface
->set_has_external_stencil_test(false);
1124 // Full frame, clipped, should not discard.
1125 clip_rect
= gfx::Rect(10, 10, 10, 10);
1126 RenderPassId
root_pass_id(1, 0);
1127 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1131 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1132 root_pass
->damage_rect
= root_pass
->output_rect
;
1134 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1135 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1140 EXPECT_EQ(0, context
->discarded());
1144 // Full frame, doesn't cover the surface, should not discard.
1145 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1146 RenderPassId
root_pass_id(1, 0);
1147 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1151 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1152 root_pass
->damage_rect
= root_pass
->output_rect
;
1154 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1155 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1160 EXPECT_EQ(0, context
->discarded());
1164 // Full frame, doesn't cover the surface (no offset), should not discard.
1165 clip_rect
= gfx::Rect(100, 100);
1166 viewport_rect
= gfx::Rect(50, 50);
1167 RenderPassId
root_pass_id(1, 0);
1168 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1172 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1173 root_pass
->damage_rect
= root_pass
->output_rect
;
1175 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1176 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1181 EXPECT_EQ(0, context
->discarded());
1186 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1188 FlippedScissorAndViewportContext()
1189 : did_call_viewport_(false), did_call_scissor_(false) {}
1190 virtual ~FlippedScissorAndViewportContext() {
1191 EXPECT_TRUE(did_call_viewport_
);
1192 EXPECT_TRUE(did_call_scissor_
);
1195 virtual void viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1199 EXPECT_EQ(100, width
);
1200 EXPECT_EQ(100, height
);
1201 did_call_viewport_
= true;
1204 virtual void scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1208 EXPECT_EQ(20, width
);
1209 EXPECT_EQ(20, height
);
1210 did_call_scissor_
= true;
1214 bool did_call_viewport_
;
1215 bool did_call_scissor_
;
1218 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1219 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1220 // and maintains a fixed size. This test verifies that glViewport and
1221 // glScissor's Y coordinate is flipped correctly in this environment, and that
1222 // the glViewport can be at a nonzero origin within the surface.
1223 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1224 new FlippedScissorAndViewportContext
);
1226 FakeOutputSurfaceClient output_surface_client
;
1227 scoped_ptr
<OutputSurface
> output_surface(new NonReshapableOutputSurface(
1228 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
1229 CHECK(output_surface
->BindToClient(&output_surface_client
));
1231 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1232 new TestSharedBitmapManager());
1233 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1234 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1, false));
1236 LayerTreeSettings settings
;
1237 FakeRendererClient renderer_client
;
1238 FakeRendererGL
renderer(&renderer_client
,
1240 output_surface
.get(),
1241 resource_provider
.get());
1242 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1244 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1245 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1246 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1248 RenderPassId
root_pass_id(1, 0);
1249 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1253 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1255 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1256 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1258 device_viewport_rect
,
1259 device_viewport_rect
,
1263 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1264 gfx::Rect
viewport_rect(1, 1);
1266 gfx::Rect
child_rect(50, 50);
1267 RenderPassId
child_pass_id(2, 0);
1268 TestRenderPass
* child_pass
;
1270 RenderPassId
root_pass_id(1, 0);
1271 TestRenderPass
* root_pass
;
1273 ResourceProvider::ResourceId mask
= resource_provider_
->CreateResource(
1276 ResourceProvider::TextureHintImmutable
,
1277 resource_provider_
->best_texture_format());
1278 resource_provider_
->AllocateForTesting(mask
);
1280 SkScalar matrix
[20];
1281 float amount
= 0.5f
;
1282 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1283 matrix
[1] = 0.715f
- 0.715f
* amount
;
1284 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1285 matrix
[3] = matrix
[4] = 0;
1286 matrix
[5] = 0.213f
- 0.213f
* amount
;
1287 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1288 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1289 matrix
[8] = matrix
[9] = 0;
1290 matrix
[10] = 0.213f
- 0.213f
* amount
;
1291 matrix
[11] = 0.715f
- 0.715f
* amount
;
1292 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1293 matrix
[13] = matrix
[14] = 0;
1294 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1296 skia::RefPtr
<SkColorFilter
> color_filter(
1297 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1298 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1299 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1300 FilterOperations filters
;
1301 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1303 gfx::Transform transform_causing_aa
;
1304 transform_causing_aa
.Rotate(20.0);
1306 // RenderPassProgram
1307 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1312 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1318 root_pass
, child_pass
, 0, FilterOperations(), gfx::Transform());
1320 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1321 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1326 TestRenderPassProgram(TexCoordPrecisionMedium
);
1328 // RenderPassColorMatrixProgram
1329 render_passes_in_draw_order_
.clear();
1331 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1334 transform_causing_aa
);
1336 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1341 AddRenderPassQuad(root_pass
, child_pass
, 0, filters
, gfx::Transform());
1343 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1344 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1349 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium
);
1351 // RenderPassMaskProgram
1352 render_passes_in_draw_order_
.clear();
1354 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1359 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1365 root_pass
, child_pass
, mask
, FilterOperations(), gfx::Transform());
1367 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1368 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1373 TestRenderPassMaskProgram(TexCoordPrecisionMedium
);
1375 // RenderPassMaskColorMatrixProgram
1376 render_passes_in_draw_order_
.clear();
1378 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1383 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1388 AddRenderPassQuad(root_pass
, child_pass
, mask
, filters
, gfx::Transform());
1390 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1391 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1396 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium
);
1398 // RenderPassProgramAA
1399 render_passes_in_draw_order_
.clear();
1401 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1404 transform_causing_aa
);
1406 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1412 root_pass
, child_pass
, 0, FilterOperations(), transform_causing_aa
);
1414 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1415 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1420 TestRenderPassProgramAA(TexCoordPrecisionMedium
);
1422 // RenderPassColorMatrixProgramAA
1423 render_passes_in_draw_order_
.clear();
1425 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1428 transform_causing_aa
);
1430 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1435 AddRenderPassQuad(root_pass
, child_pass
, 0, filters
, transform_causing_aa
);
1437 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1438 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1443 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium
);
1445 // RenderPassMaskProgramAA
1446 render_passes_in_draw_order_
.clear();
1448 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1451 transform_causing_aa
);
1453 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1459 root_pass
, child_pass
, mask
, FilterOperations(), transform_causing_aa
);
1461 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1462 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1467 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium
);
1469 // RenderPassMaskColorMatrixProgramAA
1470 render_passes_in_draw_order_
.clear();
1472 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1475 transform_causing_aa
);
1477 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1480 transform_causing_aa
);
1482 AddRenderPassQuad(root_pass
, child_pass
, mask
, filters
, transform_causing_aa
);
1484 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1485 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1490 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium
);
1493 // At this time, the AA code path cannot be taken if the surface's rect would
1494 // project incorrectly by the given transform, because of w<0 clipping.
1495 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1496 gfx::Rect
child_rect(50, 50);
1497 RenderPassId
child_pass_id(2, 0);
1498 TestRenderPass
* child_pass
;
1500 gfx::Rect
viewport_rect(1, 1);
1501 RenderPassId
root_pass_id(1, 0);
1502 TestRenderPass
* root_pass
;
1504 gfx::Transform transform_preventing_aa
;
1505 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1506 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1507 transform_preventing_aa
.Scale(30.0, 1.0);
1509 // Verify that the test transform and test rect actually do cause the clipped
1510 // flag to trigger. Otherwise we are not testing the intended scenario.
1511 bool clipped
= false;
1512 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1513 ASSERT_TRUE(clipped
);
1515 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1518 transform_preventing_aa
);
1520 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1526 root_pass
, child_pass
, 0, FilterOperations(), transform_preventing_aa
);
1528 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1529 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1535 // If use_aa incorrectly ignores clipping, it will use the
1536 // RenderPassProgramAA shader instead of the RenderPassProgram.
1537 TestRenderPassProgram(TexCoordPrecisionMedium
);
1540 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1541 gfx::Rect
viewport_rect(1, 1);
1542 RenderPassId
root_pass_id(1, 0);
1543 TestRenderPass
* root_pass
;
1545 gfx::Transform pixel_aligned_transform_causing_aa
;
1546 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1547 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1549 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1553 AddTransformedQuad(root_pass
,
1556 pixel_aligned_transform_causing_aa
);
1558 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1559 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1565 TestSolidColorProgramAA();
1568 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1570 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1572 // Specifically override methods even if they are unused (used in conjunction
1573 // with StrictMock). We need to make sure that GLRenderer does not issue
1574 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1575 // through the OutputSurface abstraction.
1576 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1577 MOCK_METHOD3(reshapeWithScaleFactor
,
1578 void(int width
, int height
, float scale_factor
));
1579 MOCK_METHOD4(drawElements
,
1580 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1583 class MockOutputSurface
: public OutputSurface
{
1587 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1588 new StrictMock
<OutputSurfaceMockContext
>))) {
1589 surface_size_
= gfx::Size(100, 100);
1591 virtual ~MockOutputSurface() {}
1593 MOCK_METHOD0(EnsureBackbuffer
, void());
1594 MOCK_METHOD0(DiscardBackbuffer
, void());
1595 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1596 MOCK_METHOD0(BindFramebuffer
, void());
1597 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1600 class MockOutputSurfaceTest
: public GLRendererTest
{
1602 virtual void SetUp() {
1603 FakeOutputSurfaceClient output_surface_client_
;
1604 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1606 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1607 resource_provider_
=
1608 ResourceProvider::Create(
1609 &output_surface_
, shared_bitmap_manager_
.get(), 0, false, 1, false)
1612 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1615 resource_provider_
.get()));
1618 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1620 void DrawFrame(float device_scale_factor
,
1621 const gfx::Rect
& device_viewport_rect
) {
1622 RenderPassId
render_pass_id(1, 0);
1623 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1625 device_viewport_rect
,
1627 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1629 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1631 EXPECT_CALL(output_surface_
,
1632 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1635 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1637 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1639 renderer_
->DecideRenderPassAllocationsForFrame(
1640 render_passes_in_draw_order_
);
1641 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1642 device_scale_factor
,
1643 device_viewport_rect
,
1644 device_viewport_rect
,
1648 OutputSurfaceMockContext
* Context() {
1649 return static_cast<OutputSurfaceMockContext
*>(
1650 static_cast<TestContextProvider
*>(
1651 output_surface_
.context_provider().get())->TestContext3d());
1654 LayerTreeSettings settings_
;
1655 FakeOutputSurfaceClient output_surface_client_
;
1656 StrictMock
<MockOutputSurface
> output_surface_
;
1657 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1658 scoped_ptr
<ResourceProvider
> resource_provider_
;
1659 FakeRendererClient renderer_client_
;
1660 scoped_ptr
<FakeRendererGL
> renderer_
;
1663 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1664 gfx::Rect
device_viewport_rect(1, 1);
1665 DrawFrame(1.f
, device_viewport_rect
);
1667 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1668 renderer_
->SwapBuffers(CompositorFrameMetadata());
1671 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1672 gfx::Rect
device_viewport_rect(1, 1);
1674 DrawFrame(1.f
, device_viewport_rect
);
1675 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1676 renderer_
->SwapBuffers(CompositorFrameMetadata());
1678 device_viewport_rect
= gfx::Rect(2, 2);
1680 DrawFrame(2.f
, device_viewport_rect
);
1681 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1682 renderer_
->SwapBuffers(CompositorFrameMetadata());
1684 DrawFrame(2.f
, device_viewport_rect
);
1685 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1686 renderer_
->SwapBuffers(CompositorFrameMetadata());
1688 device_viewport_rect
= gfx::Rect(1, 1);
1690 DrawFrame(1.f
, device_viewport_rect
);
1691 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1692 renderer_
->SwapBuffers(CompositorFrameMetadata());
1695 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1697 static void SyncPointCallback(int* callback_count
) {
1698 ++(*callback_count
);
1699 base::MessageLoop::current()->QuitWhenIdle();
1702 static void OtherCallback(int* callback_count
) {
1703 ++(*callback_count
);
1704 base::MessageLoop::current()->QuitWhenIdle();
1708 #if !defined(OS_ANDROID)
1709 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1710 int sync_point_callback_count
= 0;
1711 int other_callback_count
= 0;
1712 gpu::gles2::GLES2Interface
* gl
=
1713 output_surface_
->context_provider()->ContextGL();
1714 gpu::ContextSupport
* context_support
=
1715 output_surface_
->context_provider()->ContextSupport();
1717 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1719 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1720 GL_INNOCENT_CONTEXT_RESET_ARB
);
1722 context_support
->SignalSyncPoint(
1723 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1724 EXPECT_EQ(0, sync_point_callback_count
);
1725 EXPECT_EQ(0, other_callback_count
);
1727 // Make the sync point happen.
1729 // Post a task after the sync point.
1730 base::MessageLoop::current()->PostTask(
1731 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1733 base::MessageLoop::current()->Run();
1735 // The sync point shouldn't have happened since the context was lost.
1736 EXPECT_EQ(0, sync_point_callback_count
);
1737 EXPECT_EQ(1, other_callback_count
);
1740 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1741 int sync_point_callback_count
= 0;
1742 int other_callback_count
= 0;
1744 gpu::gles2::GLES2Interface
* gl
=
1745 output_surface_
->context_provider()->ContextGL();
1746 gpu::ContextSupport
* context_support
=
1747 output_surface_
->context_provider()->ContextSupport();
1749 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1751 context_support
->SignalSyncPoint(
1752 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1753 EXPECT_EQ(0, sync_point_callback_count
);
1754 EXPECT_EQ(0, other_callback_count
);
1756 // Make the sync point happen.
1758 // Post a task after the sync point.
1759 base::MessageLoop::current()->PostTask(
1760 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1762 base::MessageLoop::current()->Run();
1764 // The sync point should have happened.
1765 EXPECT_EQ(1, sync_point_callback_count
);
1766 EXPECT_EQ(1, other_callback_count
);
1768 #endif // OS_ANDROID