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/prioritized_resource_manager.h"
12 #include "cc/resources/resource_provider.h"
13 #include "cc/test/fake_impl_proxy.h"
14 #include "cc/test/fake_layer_tree_host_impl.h"
15 #include "cc/test/fake_output_surface.h"
16 #include "cc/test/fake_output_surface_client.h"
17 #include "cc/test/mock_quad_culler.h"
18 #include "cc/test/pixel_test.h"
19 #include "cc/test/render_pass_test_common.h"
20 #include "cc/test/render_pass_test_utils.h"
21 #include "cc/test/test_shared_bitmap_manager.h"
22 #include "cc/test/test_web_graphics_context_3d.h"
23 #include "gpu/GLES2/gl2extchromium.h"
24 #include "gpu/command_buffer/client/context_support.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "third_party/khronos/GLES2/gl2.h"
28 #include "third_party/skia/include/core/SkImageFilter.h"
29 #include "third_party/skia/include/core/SkMatrix.h"
30 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
31 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
32 #include "ui/gfx/transform.h"
35 using testing::AnyNumber
;
37 using testing::AtLeast
;
38 using testing::ElementsAre
;
39 using testing::Expectation
;
40 using testing::InSequence
;
42 using testing::Return
;
43 using testing::StrictMock
;
47 class GLRendererTest
: public testing::Test
{
49 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
51 RenderPassList render_passes_in_draw_order_
;
54 #define EXPECT_PROGRAM_VALID(program_binding) \
56 EXPECT_TRUE((program_binding)->program()); \
57 EXPECT_TRUE((program_binding)->initialized()); \
60 // Explicitly named to be a friend in GLRenderer for shader access.
61 class GLRendererShaderPixelTest
: public GLRendererPixelTest
{
64 ASSERT_FALSE(renderer()->IsContextLost());
65 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
66 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
67 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
68 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
69 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium
);
70 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh
);
71 ASSERT_FALSE(renderer()->IsContextLost());
74 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision
) {
75 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision
));
76 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision
));
77 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision
));
78 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision
));
80 renderer()->GetRenderPassColorMatrixProgram(precision
));
82 renderer()->GetRenderPassMaskColorMatrixProgramAA(precision
));
84 renderer()->GetRenderPassColorMatrixProgramAA(precision
));
86 renderer()->GetRenderPassMaskColorMatrixProgram(precision
));
87 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision
));
89 renderer()->GetNonPremultipliedTextureProgram(precision
));
90 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision
));
92 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision
));
93 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision
));
94 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision
));
95 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision
));
96 // This is unlikely to be ever true in tests due to usage of osmesa.
97 if (renderer()->Capabilities().using_egl_image
)
98 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision
));
100 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision
));
101 TestShadersWithSamplerType(precision
, SamplerType2D
);
102 TestShadersWithSamplerType(precision
, SamplerType2DRect
);
103 // This is unlikely to be ever true in tests due to usage of osmesa.
104 if (renderer()->Capabilities().using_egl_image
)
105 TestShadersWithSamplerType(precision
, SamplerTypeExternalOES
);
108 void TestShadersWithSamplerType(TexCoordPrecision precision
,
109 SamplerType sampler
) {
110 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision
, sampler
));
111 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision
, sampler
));
112 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision
, sampler
));
113 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision
, sampler
));
114 EXPECT_PROGRAM_VALID(
115 renderer()->GetTileProgramSwizzleOpaque(precision
, sampler
));
116 EXPECT_PROGRAM_VALID(
117 renderer()->GetTileProgramSwizzleAA(precision
, sampler
));
123 #if !defined(OS_ANDROID)
124 TEST_F(GLRendererShaderPixelTest
, AllShadersCompile
) { TestShaders(); }
127 class FakeRendererClient
: public RendererClient
{
129 FakeRendererClient() : set_full_root_layer_damage_count_(0) {}
131 // RendererClient methods.
132 virtual void SetFullRootLayerDamage() OVERRIDE
{
133 set_full_root_layer_damage_count_
++;
136 // Methods added for test.
137 int set_full_root_layer_damage_count() const {
138 return set_full_root_layer_damage_count_
;
142 int set_full_root_layer_damage_count_
;
145 class FakeRendererGL
: public GLRenderer
{
147 FakeRendererGL(RendererClient
* client
,
148 const LayerTreeSettings
* settings
,
149 OutputSurface
* output_surface
,
150 ResourceProvider
* resource_provider
)
158 // GLRenderer methods.
160 // Changing visibility to public.
161 using GLRenderer::IsBackbufferDiscarded
;
162 using GLRenderer::DoDrawQuad
;
163 using GLRenderer::BeginDrawingFrame
;
164 using GLRenderer::FinishDrawingQuadList
;
165 using GLRenderer::stencil_enabled
;
168 class GLRendererWithDefaultHarnessTest
: public GLRendererTest
{
170 GLRendererWithDefaultHarnessTest() {
172 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
173 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
175 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
177 ResourceProvider::Create(
178 output_surface_
.get(), shared_bitmap_manager_
.get(), 0, false, 1)
180 renderer_
= make_scoped_ptr(new FakeRendererGL(&renderer_client_
,
182 output_surface_
.get(),
183 resource_provider_
.get()));
186 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
188 LayerTreeSettings settings_
;
189 FakeOutputSurfaceClient output_surface_client_
;
190 scoped_ptr
<FakeOutputSurface
> output_surface_
;
191 FakeRendererClient renderer_client_
;
192 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
193 scoped_ptr
<ResourceProvider
> resource_provider_
;
194 scoped_ptr
<FakeRendererGL
> renderer_
;
197 // Closing the namespace here so that GLRendererShaderTest can take advantage
198 // of the friend relationship with GLRenderer and all of the mock classes
199 // declared above it.
202 class GLRendererShaderTest
: public GLRendererTest
{
204 GLRendererShaderTest() {
205 output_surface_
= FakeOutputSurface::Create3d().Pass();
206 CHECK(output_surface_
->BindToClient(&output_surface_client_
));
208 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
210 ResourceProvider::Create(
211 output_surface_
.get(), shared_bitmap_manager_
.get(), 0, false, 1)
213 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
215 output_surface_
.get(),
216 resource_provider_
.get()));
219 void TestRenderPassProgram(TexCoordPrecision precision
) {
220 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_program_
[precision
]);
221 EXPECT_EQ(renderer_
->render_pass_program_
[precision
].program(),
222 renderer_
->program_shadow_
);
225 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision
) {
226 EXPECT_PROGRAM_VALID(
227 &renderer_
->render_pass_color_matrix_program_
[precision
]);
228 EXPECT_EQ(renderer_
->render_pass_color_matrix_program_
[precision
].program(),
229 renderer_
->program_shadow_
);
232 void TestRenderPassMaskProgram(TexCoordPrecision precision
) {
233 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_program_
[precision
]);
234 EXPECT_EQ(renderer_
->render_pass_mask_program_
[precision
].program(),
235 renderer_
->program_shadow_
);
238 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision
) {
239 EXPECT_PROGRAM_VALID(
240 &renderer_
->render_pass_mask_color_matrix_program_
[precision
]);
242 renderer_
->render_pass_mask_color_matrix_program_
[precision
].program(),
243 renderer_
->program_shadow_
);
246 void TestRenderPassProgramAA(TexCoordPrecision precision
) {
247 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_program_aa_
[precision
]);
248 EXPECT_EQ(renderer_
->render_pass_program_aa_
[precision
].program(),
249 renderer_
->program_shadow_
);
252 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision
) {
253 EXPECT_PROGRAM_VALID(
254 &renderer_
->render_pass_color_matrix_program_aa_
[precision
]);
256 renderer_
->render_pass_color_matrix_program_aa_
[precision
].program(),
257 renderer_
->program_shadow_
);
260 void TestRenderPassMaskProgramAA(TexCoordPrecision precision
) {
261 EXPECT_PROGRAM_VALID(&renderer_
->render_pass_mask_program_aa_
[precision
]);
262 EXPECT_EQ(renderer_
->render_pass_mask_program_aa_
[precision
].program(),
263 renderer_
->program_shadow_
);
266 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision
) {
267 EXPECT_PROGRAM_VALID(
268 &renderer_
->render_pass_mask_color_matrix_program_aa_
[precision
]);
269 EXPECT_EQ(renderer_
->render_pass_mask_color_matrix_program_aa_
[precision
]
271 renderer_
->program_shadow_
);
274 void TestSolidColorProgramAA() {
275 EXPECT_PROGRAM_VALID(&renderer_
->solid_color_program_aa_
);
276 EXPECT_EQ(renderer_
->solid_color_program_aa_
.program(),
277 renderer_
->program_shadow_
);
280 LayerTreeSettings settings_
;
281 FakeOutputSurfaceClient output_surface_client_
;
282 scoped_ptr
<FakeOutputSurface
> output_surface_
;
283 FakeRendererClient renderer_client_
;
284 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
285 scoped_ptr
<ResourceProvider
> resource_provider_
;
286 scoped_ptr
<FakeRendererGL
> renderer_
;
291 // Test GLRenderer DiscardBackbuffer functionality:
292 // Suggest discarding framebuffer when one exists and the renderer is not
294 // Expected: it is discarded and damage tracker is reset.
296 GLRendererWithDefaultHarnessTest
,
297 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
298 renderer_
->SetVisible(false);
299 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
300 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
303 // Test GLRenderer DiscardBackbuffer functionality:
304 // Suggest discarding framebuffer when one exists and the renderer is visible.
305 // Expected: the allocation is ignored.
306 TEST_F(GLRendererWithDefaultHarnessTest
,
307 SuggestBackbufferNoDoNothingWhenVisible
) {
308 renderer_
->SetVisible(true);
309 EXPECT_EQ(0, renderer_client_
.set_full_root_layer_damage_count());
310 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
313 // Test GLRenderer DiscardBackbuffer functionality:
314 // Suggest discarding framebuffer when one does not exist.
315 // Expected: it does nothing.
316 TEST_F(GLRendererWithDefaultHarnessTest
,
317 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
318 renderer_
->SetVisible(false);
319 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
320 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
322 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
323 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
326 // Test GLRenderer DiscardBackbuffer functionality:
327 // Begin drawing a frame while a framebuffer is discarded.
328 // Expected: will recreate framebuffer.
329 TEST_F(GLRendererWithDefaultHarnessTest
,
330 DiscardedBackbufferIsRecreatedForScopeDuration
) {
331 gfx::Rect
viewport_rect(1, 1);
332 renderer_
->SetVisible(false);
333 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
334 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
336 AddRenderPass(&render_passes_in_draw_order_
,
337 RenderPass::Id(1, 0),
341 renderer_
->SetVisible(true);
342 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
348 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
351 EXPECT_EQ(1u, output_surface_
->num_sent_frames());
354 TEST_F(GLRendererWithDefaultHarnessTest
,
355 FramebufferDiscardedAfterReadbackWhenNotVisible
) {
356 gfx::Rect
viewport_rect(1, 1);
357 renderer_
->SetVisible(false);
358 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
359 EXPECT_EQ(1, renderer_client_
.set_full_root_layer_damage_count());
361 AddRenderPass(&render_passes_in_draw_order_
,
362 RenderPass::Id(1, 0),
367 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
373 EXPECT_FALSE(renderer_
->IsBackbufferDiscarded());
375 renderer_
->GetFramebufferPixels(pixels
, gfx::Rect(0, 0, 1, 1));
376 EXPECT_TRUE(renderer_
->IsBackbufferDiscarded());
377 EXPECT_EQ(2, renderer_client_
.set_full_root_layer_damage_count());
380 TEST_F(GLRendererWithDefaultHarnessTest
, ExternalStencil
) {
381 gfx::Rect
viewport_rect(1, 1);
382 EXPECT_FALSE(renderer_
->stencil_enabled());
384 output_surface_
->set_has_external_stencil_test(true);
386 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
387 RenderPass::Id(1, 0),
390 root_pass
->has_transparent_background
= false;
392 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
398 EXPECT_TRUE(renderer_
->stencil_enabled());
401 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
403 ForbidSynchronousCallContext() {}
405 virtual void getAttachedShaders(GLuint program
,
408 GLuint
* shaders
) OVERRIDE
{
411 virtual GLint
getAttribLocation(GLuint program
, const GLchar
* name
) OVERRIDE
{
415 virtual void getBooleanv(GLenum pname
, GLboolean
* value
) OVERRIDE
{
418 virtual void getBufferParameteriv(GLenum target
,
420 GLint
* value
) OVERRIDE
{
423 virtual GLenum
getError() OVERRIDE
{
427 virtual void getFloatv(GLenum pname
, GLfloat
* value
) OVERRIDE
{
430 virtual void getFramebufferAttachmentParameteriv(GLenum target
,
433 GLint
* value
) OVERRIDE
{
436 virtual void getIntegerv(GLenum pname
, GLint
* value
) OVERRIDE
{
437 if (pname
== GL_MAX_TEXTURE_SIZE
) {
438 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
445 // We allow querying the shader compilation and program link status in debug
446 // mode, but not release.
447 virtual void getProgramiv(GLuint program
,
449 GLint
* value
) OVERRIDE
{
457 virtual void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) OVERRIDE
{
465 virtual void getRenderbufferParameteriv(GLenum target
,
467 GLint
* value
) OVERRIDE
{
471 virtual void getShaderPrecisionFormat(GLenum shadertype
,
472 GLenum precisiontype
,
474 GLint
* precision
) OVERRIDE
{
477 virtual void getTexParameterfv(GLenum target
,
479 GLfloat
* value
) OVERRIDE
{
482 virtual void getTexParameteriv(GLenum target
,
484 GLint
* value
) OVERRIDE
{
487 virtual void getUniformfv(GLuint program
,
489 GLfloat
* value
) OVERRIDE
{
492 virtual void getUniformiv(GLuint program
,
494 GLint
* value
) OVERRIDE
{
497 virtual GLint
getUniformLocation(GLuint program
,
498 const GLchar
* name
) OVERRIDE
{
502 virtual void getVertexAttribfv(GLuint index
,
504 GLfloat
* value
) OVERRIDE
{
507 virtual void getVertexAttribiv(GLuint index
,
509 GLint
* value
) OVERRIDE
{
512 virtual GLsizeiptr
getVertexAttribOffset(GLuint index
,
513 GLenum pname
) OVERRIDE
{
518 TEST_F(GLRendererTest
, InitializationDoesNotMakeSynchronousCalls
) {
519 FakeOutputSurfaceClient output_surface_client
;
520 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
521 scoped_ptr
<TestWebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
522 CHECK(output_surface
->BindToClient(&output_surface_client
));
524 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
525 new TestSharedBitmapManager());
526 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
527 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
529 LayerTreeSettings settings
;
530 FakeRendererClient renderer_client
;
531 FakeRendererGL
renderer(&renderer_client
,
533 output_surface
.get(),
534 resource_provider
.get());
537 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
539 LoseContextOnFirstGetContext() {}
541 virtual void getProgramiv(GLuint program
,
543 GLint
* value
) OVERRIDE
{
544 context_lost_
= true;
548 virtual void getShaderiv(GLuint shader
, GLenum pname
, GLint
* value
) OVERRIDE
{
549 context_lost_
= true;
554 TEST_F(GLRendererTest
, InitializationWithQuicklyLostContextDoesNotAssert
) {
555 FakeOutputSurfaceClient output_surface_client
;
556 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
557 scoped_ptr
<TestWebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
558 CHECK(output_surface
->BindToClient(&output_surface_client
));
560 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
561 new TestSharedBitmapManager());
562 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
563 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
565 LayerTreeSettings settings
;
566 FakeRendererClient renderer_client
;
567 FakeRendererGL
renderer(&renderer_client
,
569 output_surface
.get(),
570 resource_provider
.get());
573 class ClearCountingContext
: public TestWebGraphicsContext3D
{
575 ClearCountingContext() { test_capabilities_
.gpu
.discard_framebuffer
= true; }
577 MOCK_METHOD3(discardFramebufferEXT
,
579 GLsizei numAttachments
,
580 const GLenum
* attachments
));
581 MOCK_METHOD1(clear
, void(GLbitfield mask
));
584 TEST_F(GLRendererTest
, OpaqueBackground
) {
585 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
586 ClearCountingContext
* context
= context_owned
.get();
588 FakeOutputSurfaceClient output_surface_client
;
589 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
590 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
591 CHECK(output_surface
->BindToClient(&output_surface_client
));
593 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
594 new TestSharedBitmapManager());
595 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
596 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
598 LayerTreeSettings settings
;
599 FakeRendererClient renderer_client
;
600 FakeRendererGL
renderer(&renderer_client
,
602 output_surface
.get(),
603 resource_provider
.get());
605 gfx::Rect
viewport_rect(1, 1);
606 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
607 RenderPass::Id(1, 0),
610 root_pass
->has_transparent_background
= false;
612 // On DEBUG builds, render passes with opaque background clear to blue to
613 // easily see regions that were not drawn on the screen.
614 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
615 .With(Args
<2, 1>(ElementsAre(GL_COLOR_EXT
)))
618 EXPECT_CALL(*context
, clear(_
)).Times(0);
620 EXPECT_CALL(*context
, clear(_
)).Times(1);
622 renderer
.DrawFrame(&render_passes_in_draw_order_
,
628 Mock::VerifyAndClearExpectations(context
);
631 TEST_F(GLRendererTest
, TransparentBackground
) {
632 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
633 ClearCountingContext
* context
= context_owned
.get();
635 FakeOutputSurfaceClient output_surface_client
;
636 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
637 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
638 CHECK(output_surface
->BindToClient(&output_surface_client
));
640 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
641 new TestSharedBitmapManager());
642 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
643 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
645 LayerTreeSettings settings
;
646 FakeRendererClient renderer_client
;
647 FakeRendererGL
renderer(&renderer_client
,
649 output_surface
.get(),
650 resource_provider
.get());
652 gfx::Rect
viewport_rect(1, 1);
653 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
654 RenderPass::Id(1, 0),
657 root_pass
->has_transparent_background
= true;
659 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, 1, _
)).Times(1);
660 EXPECT_CALL(*context
, clear(_
)).Times(1);
661 renderer
.DrawFrame(&render_passes_in_draw_order_
,
668 Mock::VerifyAndClearExpectations(context
);
671 TEST_F(GLRendererTest
, OffscreenOutputSurface
) {
672 scoped_ptr
<ClearCountingContext
> context_owned(new ClearCountingContext
);
673 ClearCountingContext
* context
= context_owned
.get();
675 FakeOutputSurfaceClient output_surface_client
;
676 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::CreateOffscreen(
677 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
678 CHECK(output_surface
->BindToClient(&output_surface_client
));
680 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
681 new TestSharedBitmapManager());
682 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
683 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
685 LayerTreeSettings settings
;
686 FakeRendererClient renderer_client
;
687 FakeRendererGL
renderer(&renderer_client
,
689 output_surface
.get(),
690 resource_provider
.get());
692 gfx::Rect
viewport_rect(1, 1);
693 AddRenderPass(&render_passes_in_draw_order_
,
694 RenderPass::Id(1, 0),
698 EXPECT_CALL(*context
, discardFramebufferEXT(GL_FRAMEBUFFER
, _
, _
))
699 .With(Args
<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0
)))
701 EXPECT_CALL(*context
, clear(_
)).Times(AnyNumber());
702 renderer
.DrawFrame(&render_passes_in_draw_order_
,
708 Mock::VerifyAndClearExpectations(context
);
711 class VisibilityChangeIsLastCallTrackingContext
712 : public TestWebGraphicsContext3D
{
714 VisibilityChangeIsLastCallTrackingContext()
715 : last_call_was_set_visibility_(false) {}
717 // TestWebGraphicsContext3D methods.
718 virtual void flush() OVERRIDE
{ last_call_was_set_visibility_
= false; }
719 virtual void deleteTexture(GLuint
) OVERRIDE
{
720 last_call_was_set_visibility_
= false;
722 virtual void deleteFramebuffer(GLuint
) OVERRIDE
{
723 last_call_was_set_visibility_
= false;
725 virtual void deleteQueryEXT(GLuint
) OVERRIDE
{
726 last_call_was_set_visibility_
= false;
728 virtual void deleteRenderbuffer(GLuint
) OVERRIDE
{
729 last_call_was_set_visibility_
= false;
732 // Methods added for test.
733 void set_last_call_was_visibility(bool visible
) {
734 DCHECK(last_call_was_set_visibility_
== false);
735 last_call_was_set_visibility_
= true;
737 bool last_call_was_set_visibility() const {
738 return last_call_was_set_visibility_
;
742 bool last_call_was_set_visibility_
;
745 TEST_F(GLRendererTest
, VisibilityChangeIsLastCall
) {
746 scoped_ptr
<VisibilityChangeIsLastCallTrackingContext
> context_owned(
747 new VisibilityChangeIsLastCallTrackingContext
);
748 VisibilityChangeIsLastCallTrackingContext
* context
= context_owned
.get();
750 scoped_refptr
<TestContextProvider
> provider
= TestContextProvider::Create(
751 context_owned
.PassAs
<TestWebGraphicsContext3D
>());
753 provider
->support()->SetSurfaceVisibleCallback(base::Bind(
754 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility
,
755 base::Unretained(context
)));
757 FakeOutputSurfaceClient output_surface_client
;
758 scoped_ptr
<OutputSurface
> output_surface(
759 FakeOutputSurface::Create3d(provider
));
760 CHECK(output_surface
->BindToClient(&output_surface_client
));
762 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
763 new TestSharedBitmapManager());
764 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
765 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
767 LayerTreeSettings settings
;
768 FakeRendererClient renderer_client
;
769 FakeRendererGL
renderer(&renderer_client
,
771 output_surface
.get(),
772 resource_provider
.get());
774 gfx::Rect
viewport_rect(1, 1);
775 AddRenderPass(&render_passes_in_draw_order_
,
776 RenderPass::Id(1, 0),
780 // Ensure that the call to SetSurfaceVisible is the last call issue to the
781 // GPU process, after glFlush is called, and after the RendererClient's
782 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
783 // RenderClient and the Context by giving them both a pointer to a variable on
785 renderer
.SetVisible(true);
786 renderer
.DrawFrame(&render_passes_in_draw_order_
,
792 renderer
.SetVisible(false);
793 EXPECT_TRUE(context
->last_call_was_set_visibility());
796 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
798 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {
799 test_capabilities_
.gpu
.egl_image_external
= true;
802 MOCK_METHOD3(texParameteri
, void(GLenum target
, GLenum pname
, GLint param
));
803 MOCK_METHOD4(drawElements
,
804 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
806 virtual void activeTexture(GLenum texture
) {
807 EXPECT_NE(texture
, active_texture_
);
808 active_texture_
= texture
;
811 GLenum
active_texture() const { return active_texture_
; }
814 GLenum active_texture_
;
817 TEST_F(GLRendererTest
, ActiveTextureState
) {
818 scoped_ptr
<TextureStateTrackingContext
> context_owned(
819 new TextureStateTrackingContext
);
820 TextureStateTrackingContext
* context
= context_owned
.get();
822 FakeOutputSurfaceClient output_surface_client
;
823 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
824 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
825 CHECK(output_surface
->BindToClient(&output_surface_client
));
827 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
828 new TestSharedBitmapManager());
829 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
830 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
832 LayerTreeSettings settings
;
833 FakeRendererClient renderer_client
;
834 FakeRendererGL
renderer(&renderer_client
,
836 output_surface
.get(),
837 resource_provider
.get());
839 // During initialization we are allowed to set any texture parameters.
840 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
842 RenderPass::Id
id(1, 1);
843 TestRenderPass
* root_pass
= AddRenderPass(
844 &render_passes_in_draw_order_
, id
, gfx::Rect(100, 100), gfx::Transform());
845 root_pass
->AppendOneOfEveryQuadType(resource_provider
.get(),
846 RenderPass::Id(2, 1));
848 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
850 // Set up expected texture filter state transitions that match the quads
851 // created in AppendOneOfEveryQuadType().
852 Mock::VerifyAndClearExpectations(context
);
856 // yuv_quad is drawn with the default linear filter.
857 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
859 // tile_quad is drawn with GL_NEAREST because it is not transformed or
863 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
866 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
867 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
869 // transformed_tile_quad uses GL_LINEAR.
870 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
872 // scaled_tile_quad also uses GL_LINEAR.
873 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
875 // The remaining quads also use GL_LINEAR because nearest neighbor
876 // filtering is currently only used with tile quads.
877 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(6);
880 gfx::Rect
viewport_rect(100, 100);
881 renderer
.DrawFrame(&render_passes_in_draw_order_
,
887 Mock::VerifyAndClearExpectations(context
);
890 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
892 MOCK_METHOD1(clear
, void(GLbitfield mask
));
893 MOCK_METHOD4(drawElements
,
894 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
897 TEST_F(GLRendererTest
, ShouldClearRootRenderPass
) {
898 scoped_ptr
<NoClearRootRenderPassMockContext
> mock_context_owned(
899 new NoClearRootRenderPassMockContext
);
900 NoClearRootRenderPassMockContext
* mock_context
= mock_context_owned
.get();
902 FakeOutputSurfaceClient output_surface_client
;
903 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
904 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
905 CHECK(output_surface
->BindToClient(&output_surface_client
));
907 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
908 new TestSharedBitmapManager());
909 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
910 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
912 LayerTreeSettings settings
;
913 settings
.should_clear_root_render_pass
= false;
915 FakeRendererClient renderer_client
;
916 FakeRendererGL
renderer(&renderer_client
,
918 output_surface
.get(),
919 resource_provider
.get());
921 gfx::Rect
viewport_rect(10, 10);
923 RenderPass::Id
root_pass_id(1, 0);
924 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
928 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
930 RenderPass::Id
child_pass_id(2, 0);
931 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
935 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
937 AddRenderPassQuad(root_pass
, child_pass
);
940 GLint clear_bits
= GL_COLOR_BUFFER_BIT
;
942 GLint clear_bits
= GL_COLOR_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
945 // First render pass is not the root one, clearing should happen.
946 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(AtLeast(1));
948 Expectation first_render_pass
=
949 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
951 // The second render pass is the root one, clearing should be prevented.
952 EXPECT_CALL(*mock_context
, clear(clear_bits
)).Times(0).After(
955 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber()).After(
958 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
959 renderer
.DrawFrame(&render_passes_in_draw_order_
,
966 // In multiple render passes all but the root pass should clear the
968 Mock::VerifyAndClearExpectations(&mock_context
);
971 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
973 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
975 virtual void clear(GLbitfield
) OVERRIDE
{ EXPECT_FALSE(scissor_enabled_
); }
977 virtual void enable(GLenum cap
) OVERRIDE
{
978 if (cap
== GL_SCISSOR_TEST
)
979 scissor_enabled_
= true;
982 virtual void disable(GLenum cap
) OVERRIDE
{
983 if (cap
== GL_SCISSOR_TEST
)
984 scissor_enabled_
= false;
988 bool scissor_enabled_
;
991 TEST_F(GLRendererTest
, ScissorTestWhenClearing
) {
992 scoped_ptr
<ScissorTestOnClearCheckingContext
> context_owned(
993 new ScissorTestOnClearCheckingContext
);
995 FakeOutputSurfaceClient output_surface_client
;
996 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
997 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
998 CHECK(output_surface
->BindToClient(&output_surface_client
));
1000 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1001 new TestSharedBitmapManager());
1002 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1003 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
1005 LayerTreeSettings settings
;
1006 FakeRendererClient renderer_client
;
1007 FakeRendererGL
renderer(&renderer_client
,
1009 output_surface
.get(),
1010 resource_provider
.get());
1011 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1013 gfx::Rect
viewport_rect(1, 1);
1015 gfx::Rect
grand_child_rect(25, 25);
1016 RenderPass::Id
grand_child_pass_id(3, 0);
1017 TestRenderPass
* grand_child_pass
=
1018 AddRenderPass(&render_passes_in_draw_order_
,
1019 grand_child_pass_id
,
1022 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1024 gfx::Rect
child_rect(50, 50);
1025 RenderPass::Id
child_pass_id(2, 0);
1026 TestRenderPass
* child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1030 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1032 RenderPass::Id
root_pass_id(1, 0);
1033 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1037 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1039 AddRenderPassQuad(root_pass
, child_pass
);
1040 AddRenderPassQuad(child_pass
, grand_child_pass
);
1042 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1043 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1051 class DiscardCheckingContext
: public TestWebGraphicsContext3D
{
1053 DiscardCheckingContext() : discarded_(0) {
1054 set_have_post_sub_buffer(true);
1055 set_have_discard_framebuffer(true);
1058 virtual void discardFramebufferEXT(GLenum target
,
1059 GLsizei numAttachments
,
1060 const GLenum
* attachments
) OVERRIDE
{
1064 int discarded() const { return discarded_
; }
1065 void reset() { discarded_
= 0; }
1071 class NonReshapableOutputSurface
: public FakeOutputSurface
{
1073 explicit NonReshapableOutputSurface(
1074 scoped_ptr
<TestWebGraphicsContext3D
> context3d
)
1075 : FakeOutputSurface(TestContextProvider::Create(context3d
.Pass()),
1077 surface_size_
= gfx::Size(500, 500);
1079 virtual void Reshape(const gfx::Size
& size
, float scale_factor
) OVERRIDE
{}
1080 void set_fixed_size(const gfx::Size
& size
) { surface_size_
= size
; }
1083 TEST_F(GLRendererTest
, NoDiscardOnPartialUpdates
) {
1084 scoped_ptr
<DiscardCheckingContext
> context_owned(new DiscardCheckingContext
);
1085 DiscardCheckingContext
* context
= context_owned
.get();
1087 FakeOutputSurfaceClient output_surface_client
;
1088 scoped_ptr
<NonReshapableOutputSurface
> output_surface(
1089 new NonReshapableOutputSurface(
1090 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
1091 CHECK(output_surface
->BindToClient(&output_surface_client
));
1092 output_surface
->set_fixed_size(gfx::Size(100, 100));
1094 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1095 new TestSharedBitmapManager());
1096 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1097 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
1099 LayerTreeSettings settings
;
1100 settings
.partial_swap_enabled
= true;
1101 FakeRendererClient renderer_client
;
1102 FakeRendererGL
renderer(&renderer_client
,
1104 output_surface
.get(),
1105 resource_provider
.get());
1106 EXPECT_TRUE(renderer
.Capabilities().using_partial_swap
);
1108 gfx::Rect
viewport_rect(100, 100);
1109 gfx::Rect
clip_rect(100, 100);
1112 // Partial frame, should not discard.
1113 RenderPass::Id
root_pass_id(1, 0);
1114 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1118 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1119 root_pass
->damage_rect
= gfx::Rect(2, 2, 3, 3);
1121 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1122 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1128 EXPECT_EQ(0, context
->discarded());
1132 // Full frame, should discard.
1133 RenderPass::Id
root_pass_id(1, 0);
1134 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1138 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1139 root_pass
->damage_rect
= root_pass
->output_rect
;
1141 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1142 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1148 EXPECT_EQ(1, context
->discarded());
1152 // Full frame, external scissor is set, should not discard.
1153 output_surface
->set_has_external_stencil_test(true);
1154 RenderPass::Id
root_pass_id(1, 0);
1155 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1159 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1160 root_pass
->damage_rect
= root_pass
->output_rect
;
1161 root_pass
->has_transparent_background
= false;
1163 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1164 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1170 EXPECT_EQ(0, context
->discarded());
1172 output_surface
->set_has_external_stencil_test(false);
1175 // Full frame, clipped, should not discard.
1176 clip_rect
= gfx::Rect(10, 10, 10, 10);
1177 RenderPass::Id
root_pass_id(1, 0);
1178 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1182 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1183 root_pass
->damage_rect
= root_pass
->output_rect
;
1185 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1186 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1192 EXPECT_EQ(0, context
->discarded());
1196 // Full frame, doesn't cover the surface, should not discard.
1197 viewport_rect
= gfx::Rect(10, 10, 10, 10);
1198 RenderPass::Id
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_
,
1213 EXPECT_EQ(0, context
->discarded());
1217 // Full frame, doesn't cover the surface (no offset), should not discard.
1218 clip_rect
= gfx::Rect(100, 100);
1219 viewport_rect
= gfx::Rect(50, 50);
1220 RenderPass::Id
root_pass_id(1, 0);
1221 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1225 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1226 root_pass
->damage_rect
= root_pass
->output_rect
;
1228 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1229 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1235 EXPECT_EQ(0, context
->discarded());
1240 class FlippedScissorAndViewportContext
: public TestWebGraphicsContext3D
{
1242 FlippedScissorAndViewportContext()
1243 : did_call_viewport_(false), did_call_scissor_(false) {}
1244 virtual ~FlippedScissorAndViewportContext() {
1245 EXPECT_TRUE(did_call_viewport_
);
1246 EXPECT_TRUE(did_call_scissor_
);
1249 virtual void viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1253 EXPECT_EQ(100, width
);
1254 EXPECT_EQ(100, height
);
1255 did_call_viewport_
= true;
1258 virtual void scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
)
1262 EXPECT_EQ(20, width
);
1263 EXPECT_EQ(20, height
);
1264 did_call_scissor_
= true;
1268 bool did_call_viewport_
;
1269 bool did_call_scissor_
;
1272 TEST_F(GLRendererTest
, ScissorAndViewportWithinNonreshapableSurface
) {
1273 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1274 // and maintains a fixed size. This test verifies that glViewport and
1275 // glScissor's Y coordinate is flipped correctly in this environment, and that
1276 // the glViewport can be at a nonzero origin within the surface.
1277 scoped_ptr
<FlippedScissorAndViewportContext
> context_owned(
1278 new FlippedScissorAndViewportContext
);
1280 FakeOutputSurfaceClient output_surface_client
;
1281 scoped_ptr
<OutputSurface
> output_surface(new NonReshapableOutputSurface(
1282 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
1283 CHECK(output_surface
->BindToClient(&output_surface_client
));
1285 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
1286 new TestSharedBitmapManager());
1287 scoped_ptr
<ResourceProvider
> resource_provider(ResourceProvider::Create(
1288 output_surface
.get(), shared_bitmap_manager
.get(), 0, false, 1));
1290 LayerTreeSettings settings
;
1291 FakeRendererClient renderer_client
;
1292 FakeRendererGL
renderer(&renderer_client
,
1294 output_surface
.get(),
1295 resource_provider
.get());
1296 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
1298 gfx::Rect
device_viewport_rect(10, 10, 100, 100);
1299 gfx::Rect
viewport_rect(device_viewport_rect
.size());
1300 gfx::Rect quad_rect
= gfx::Rect(20, 20, 20, 20);
1302 RenderPass::Id
root_pass_id(1, 0);
1303 TestRenderPass
* root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1307 AddClippedQuad(root_pass
, quad_rect
, SK_ColorGREEN
);
1309 renderer
.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1310 renderer
.DrawFrame(&render_passes_in_draw_order_
,
1313 device_viewport_rect
,
1314 device_viewport_rect
,
1318 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1319 gfx::Rect
viewport_rect(1, 1);
1321 gfx::Rect
child_rect(50, 50);
1322 RenderPass::Id
child_pass_id(2, 0);
1323 TestRenderPass
* child_pass
;
1325 RenderPass::Id
root_pass_id(1, 0);
1326 TestRenderPass
* root_pass
;
1328 ResourceProvider::ResourceId mask
= resource_provider_
->CreateResource(
1331 ResourceProvider::TextureUsageAny
,
1332 resource_provider_
->best_texture_format());
1333 resource_provider_
->AllocateForTesting(mask
);
1335 SkScalar matrix
[20];
1336 float amount
= 0.5f
;
1337 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1338 matrix
[1] = 0.715f
- 0.715f
* amount
;
1339 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1340 matrix
[3] = matrix
[4] = 0;
1341 matrix
[5] = 0.213f
- 0.213f
* amount
;
1342 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1343 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1344 matrix
[8] = matrix
[9] = 0;
1345 matrix
[10] = 0.213f
- 0.213f
* amount
;
1346 matrix
[11] = 0.715f
- 0.715f
* amount
;
1347 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1348 matrix
[13] = matrix
[14] = 0;
1349 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1351 skia::RefPtr
<SkColorFilter
> color_filter(
1352 skia::AdoptRef(new SkColorMatrixFilter(matrix
)));
1353 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1354 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1355 FilterOperations filters
;
1356 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1358 gfx::Transform transform_causing_aa
;
1359 transform_causing_aa
.Rotate(20.0);
1361 // RenderPassProgram
1362 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1367 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1373 root_pass
, child_pass
, 0, FilterOperations(), gfx::Transform());
1375 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1376 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1382 TestRenderPassProgram(TexCoordPrecisionMedium
);
1384 // RenderPassColorMatrixProgram
1385 render_passes_in_draw_order_
.clear();
1387 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1390 transform_causing_aa
);
1392 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1397 AddRenderPassQuad(root_pass
, child_pass
, 0, filters
, gfx::Transform());
1399 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1400 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1406 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium
);
1408 // RenderPassMaskProgram
1409 render_passes_in_draw_order_
.clear();
1411 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1416 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1422 root_pass
, child_pass
, mask
, FilterOperations(), gfx::Transform());
1424 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1425 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1431 TestRenderPassMaskProgram(TexCoordPrecisionMedium
);
1433 // RenderPassMaskColorMatrixProgram
1434 render_passes_in_draw_order_
.clear();
1436 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1441 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1446 AddRenderPassQuad(root_pass
, child_pass
, mask
, filters
, gfx::Transform());
1448 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1449 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1455 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium
);
1457 // RenderPassProgramAA
1458 render_passes_in_draw_order_
.clear();
1460 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1463 transform_causing_aa
);
1465 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1471 root_pass
, child_pass
, 0, FilterOperations(), transform_causing_aa
);
1473 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1474 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1480 TestRenderPassProgramAA(TexCoordPrecisionMedium
);
1482 // RenderPassColorMatrixProgramAA
1483 render_passes_in_draw_order_
.clear();
1485 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1488 transform_causing_aa
);
1490 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1495 AddRenderPassQuad(root_pass
, child_pass
, 0, filters
, transform_causing_aa
);
1497 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1498 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1504 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium
);
1506 // RenderPassMaskProgramAA
1507 render_passes_in_draw_order_
.clear();
1509 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1512 transform_causing_aa
);
1514 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1520 root_pass
, child_pass
, mask
, FilterOperations(), transform_causing_aa
);
1522 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1523 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1529 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium
);
1531 // RenderPassMaskColorMatrixProgramAA
1532 render_passes_in_draw_order_
.clear();
1534 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1537 transform_causing_aa
);
1539 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1542 transform_causing_aa
);
1544 AddRenderPassQuad(root_pass
, child_pass
, mask
, filters
, transform_causing_aa
);
1546 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1547 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1553 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium
);
1556 // At this time, the AA code path cannot be taken if the surface's rect would
1557 // project incorrectly by the given transform, because of w<0 clipping.
1558 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadSkipsAAForClippingTransform
) {
1559 gfx::Rect
child_rect(50, 50);
1560 RenderPass::Id
child_pass_id(2, 0);
1561 TestRenderPass
* child_pass
;
1563 gfx::Rect
viewport_rect(1, 1);
1564 RenderPass::Id
root_pass_id(1, 0);
1565 TestRenderPass
* root_pass
;
1567 gfx::Transform transform_preventing_aa
;
1568 transform_preventing_aa
.ApplyPerspectiveDepth(40.0);
1569 transform_preventing_aa
.RotateAboutYAxis(-20.0);
1570 transform_preventing_aa
.Scale(30.0, 1.0);
1572 // Verify that the test transform and test rect actually do cause the clipped
1573 // flag to trigger. Otherwise we are not testing the intended scenario.
1574 bool clipped
= false;
1575 MathUtil::MapQuad(transform_preventing_aa
, gfx::QuadF(child_rect
), &clipped
);
1576 ASSERT_TRUE(clipped
);
1578 child_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1581 transform_preventing_aa
);
1583 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1589 root_pass
, child_pass
, 0, FilterOperations(), transform_preventing_aa
);
1591 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1592 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1599 // If use_aa incorrectly ignores clipping, it will use the
1600 // RenderPassProgramAA shader instead of the RenderPassProgram.
1601 TestRenderPassProgram(TexCoordPrecisionMedium
);
1604 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1605 gfx::Rect
viewport_rect(1, 1);
1606 RenderPass::Id
root_pass_id(1, 0);
1607 TestRenderPass
* root_pass
;
1609 gfx::Transform pixel_aligned_transform_causing_aa
;
1610 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1611 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1613 root_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1617 AddTransformedQuad(root_pass
,
1620 pixel_aligned_transform_causing_aa
);
1622 renderer_
->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_
);
1623 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1630 TestSolidColorProgramAA();
1633 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1635 OutputSurfaceMockContext() { test_capabilities_
.gpu
.post_sub_buffer
= true; }
1637 // Specifically override methods even if they are unused (used in conjunction
1638 // with StrictMock). We need to make sure that GLRenderer does not issue
1639 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1640 // through the OutputSurface abstraction.
1641 MOCK_METHOD2(bindFramebuffer
, void(GLenum target
, GLuint framebuffer
));
1642 MOCK_METHOD3(reshapeWithScaleFactor
,
1643 void(int width
, int height
, float scale_factor
));
1644 MOCK_METHOD4(drawElements
,
1645 void(GLenum mode
, GLsizei count
, GLenum type
, GLintptr offset
));
1648 class MockOutputSurface
: public OutputSurface
{
1652 TestContextProvider::Create(scoped_ptr
<TestWebGraphicsContext3D
>(
1653 new StrictMock
<OutputSurfaceMockContext
>))) {
1654 surface_size_
= gfx::Size(100, 100);
1656 virtual ~MockOutputSurface() {}
1658 MOCK_METHOD0(EnsureBackbuffer
, void());
1659 MOCK_METHOD0(DiscardBackbuffer
, void());
1660 MOCK_METHOD2(Reshape
, void(const gfx::Size
& size
, float scale_factor
));
1661 MOCK_METHOD0(BindFramebuffer
, void());
1662 MOCK_METHOD1(SwapBuffers
, void(CompositorFrame
* frame
));
1665 class MockOutputSurfaceTest
: public GLRendererTest
{
1667 virtual void SetUp() {
1668 FakeOutputSurfaceClient output_surface_client_
;
1669 CHECK(output_surface_
.BindToClient(&output_surface_client_
));
1671 shared_bitmap_manager_
.reset(new TestSharedBitmapManager());
1672 resource_provider_
=
1673 ResourceProvider::Create(
1674 &output_surface_
, shared_bitmap_manager_
.get(), 0, false, 1).Pass();
1676 renderer_
.reset(new FakeRendererGL(&renderer_client_
,
1679 resource_provider_
.get()));
1682 void SwapBuffers() { renderer_
->SwapBuffers(CompositorFrameMetadata()); }
1684 void DrawFrame(float device_scale_factor
,
1685 const gfx::Rect
& device_viewport_rect
) {
1686 RenderPass::Id
render_pass_id(1, 0);
1687 TestRenderPass
* render_pass
= AddRenderPass(&render_passes_in_draw_order_
,
1689 device_viewport_rect
,
1691 AddQuad(render_pass
, device_viewport_rect
, SK_ColorGREEN
);
1693 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1695 EXPECT_CALL(output_surface_
,
1696 Reshape(device_viewport_rect
.size(), device_scale_factor
))
1699 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1701 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1703 renderer_
->DecideRenderPassAllocationsForFrame(
1704 render_passes_in_draw_order_
);
1705 renderer_
->DrawFrame(&render_passes_in_draw_order_
,
1707 device_scale_factor
,
1708 device_viewport_rect
,
1709 device_viewport_rect
,
1713 OutputSurfaceMockContext
* Context() {
1714 return static_cast<OutputSurfaceMockContext
*>(
1715 static_cast<TestContextProvider
*>(
1716 output_surface_
.context_provider().get())->TestContext3d());
1719 LayerTreeSettings settings_
;
1720 FakeOutputSurfaceClient output_surface_client_
;
1721 StrictMock
<MockOutputSurface
> output_surface_
;
1722 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
1723 scoped_ptr
<ResourceProvider
> resource_provider_
;
1724 FakeRendererClient renderer_client_
;
1725 scoped_ptr
<FakeRendererGL
> renderer_
;
1728 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1729 gfx::Rect
device_viewport_rect(1, 1);
1730 DrawFrame(1.f
, device_viewport_rect
);
1732 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1733 renderer_
->SwapBuffers(CompositorFrameMetadata());
1736 TEST_F(MockOutputSurfaceTest
, DrawFrameAndResizeAndSwap
) {
1737 gfx::Rect
device_viewport_rect(1, 1);
1739 DrawFrame(1.f
, device_viewport_rect
);
1740 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1741 renderer_
->SwapBuffers(CompositorFrameMetadata());
1743 device_viewport_rect
= gfx::Rect(2, 2);
1745 DrawFrame(2.f
, device_viewport_rect
);
1746 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1747 renderer_
->SwapBuffers(CompositorFrameMetadata());
1749 DrawFrame(2.f
, device_viewport_rect
);
1750 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1751 renderer_
->SwapBuffers(CompositorFrameMetadata());
1753 device_viewport_rect
= gfx::Rect(1, 1);
1755 DrawFrame(1.f
, device_viewport_rect
);
1756 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1757 renderer_
->SwapBuffers(CompositorFrameMetadata());
1760 class GLRendererTestSyncPoint
: public GLRendererPixelTest
{
1762 static void SyncPointCallback(int* callback_count
) {
1763 ++(*callback_count
);
1764 base::MessageLoop::current()->QuitWhenIdle();
1767 static void OtherCallback(int* callback_count
) {
1768 ++(*callback_count
);
1769 base::MessageLoop::current()->QuitWhenIdle();
1773 #if !defined(OS_ANDROID)
1774 TEST_F(GLRendererTestSyncPoint
, SignalSyncPointOnLostContext
) {
1775 int sync_point_callback_count
= 0;
1776 int other_callback_count
= 0;
1777 gpu::gles2::GLES2Interface
* gl
=
1778 output_surface_
->context_provider()->ContextGL();
1779 gpu::ContextSupport
* context_support
=
1780 output_surface_
->context_provider()->ContextSupport();
1782 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1784 gl
->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB
,
1785 GL_INNOCENT_CONTEXT_RESET_ARB
);
1787 context_support
->SignalSyncPoint(
1788 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1789 EXPECT_EQ(0, sync_point_callback_count
);
1790 EXPECT_EQ(0, other_callback_count
);
1792 // Make the sync point happen.
1794 // Post a task after the sync point.
1795 base::MessageLoop::current()->PostTask(
1796 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1798 base::MessageLoop::current()->Run();
1800 // The sync point shouldn't have happened since the context was lost.
1801 EXPECT_EQ(0, sync_point_callback_count
);
1802 EXPECT_EQ(1, other_callback_count
);
1805 TEST_F(GLRendererTestSyncPoint
, SignalSyncPoint
) {
1806 int sync_point_callback_count
= 0;
1807 int other_callback_count
= 0;
1809 gpu::gles2::GLES2Interface
* gl
=
1810 output_surface_
->context_provider()->ContextGL();
1811 gpu::ContextSupport
* context_support
=
1812 output_surface_
->context_provider()->ContextSupport();
1814 uint32 sync_point
= gl
->InsertSyncPointCHROMIUM();
1816 context_support
->SignalSyncPoint(
1817 sync_point
, base::Bind(&SyncPointCallback
, &sync_point_callback_count
));
1818 EXPECT_EQ(0, sync_point_callback_count
);
1819 EXPECT_EQ(0, other_callback_count
);
1821 // Make the sync point happen.
1823 // Post a task after the sync point.
1824 base::MessageLoop::current()->PostTask(
1825 FROM_HERE
, base::Bind(&OtherCallback
, &other_callback_count
));
1827 base::MessageLoop::current()->Run();
1829 // The sync point should have happened.
1830 EXPECT_EQ(1, sync_point_callback_count
);
1831 EXPECT_EQ(1, other_callback_count
);
1833 #endif // OS_ANDROID