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/fake_renderer_client.h"
18 #include "cc/test/mock_quad_culler.h"
19 #include "cc/test/pixel_test.h"
20 #include "cc/test/render_pass_test_common.h"
21 #include "cc/test/render_pass_test_utils.h"
22 #include "cc/test/test_shared_bitmap_manager.h"
23 #include "cc/test/test_web_graphics_context_3d.h"
24 #include "gpu/GLES2/gl2extchromium.h"
25 #include "gpu/command_buffer/client/context_support.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/khronos/GLES2/gl2.h"
29 #include "third_party/skia/include/core/SkImageFilter.h"
30 #include "third_party/skia/include/core/SkMatrix.h"
31 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
32 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
33 #include "ui/gfx/transform.h"
36 using testing::AnyNumber;
38 using testing::AtLeast;
39 using testing::ElementsAre;
40 using testing::Expectation;
41 using testing::InSequence;
43 using testing::Return;
44 using testing::StrictMock;
48 class GLRendererTest : public testing::Test {
50 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
52 RenderPassList render_passes_in_draw_order_;
55 #define EXPECT_PROGRAM_VALID(program_binding) \
57 EXPECT_TRUE((program_binding)->program()); \
58 EXPECT_TRUE((program_binding)->initialized()); \
61 // Explicitly named to be a friend in GLRenderer for shader access.
62 class GLRendererShaderPixelTest : public GLRendererPixelTest {
65 ASSERT_FALSE(renderer()->IsContextLost());
66 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
67 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
68 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
69 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
70 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium);
71 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh);
72 ASSERT_FALSE(renderer()->IsContextLost());
75 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision) {
76 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision));
77 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision));
78 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision));
79 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision));
81 renderer()->GetRenderPassColorMatrixProgram(precision));
83 renderer()->GetRenderPassMaskColorMatrixProgramAA(precision));
85 renderer()->GetRenderPassColorMatrixProgramAA(precision));
87 renderer()->GetRenderPassMaskColorMatrixProgram(precision));
88 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
90 renderer()->GetNonPremultipliedTextureProgram(precision));
91 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision));
93 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision));
94 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
95 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision));
96 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision));
97 // This is unlikely to be ever true in tests due to usage of osmesa.
98 if (renderer()->Capabilities().using_egl_image)
99 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
101 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
102 TestShadersWithSamplerType(precision, SamplerType2D);
103 TestShadersWithSamplerType(precision, SamplerType2DRect);
104 // This is unlikely to be ever true in tests due to usage of osmesa.
105 if (renderer()->Capabilities().using_egl_image)
106 TestShadersWithSamplerType(precision, SamplerTypeExternalOES);
109 void TestShadersWithSamplerType(TexCoordPrecision precision,
110 SamplerType sampler) {
111 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
112 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
113 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
114 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
115 EXPECT_PROGRAM_VALID(
116 renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
117 EXPECT_PROGRAM_VALID(
118 renderer()->GetTileProgramSwizzleAA(precision, sampler));
124 #if !defined(OS_ANDROID)
125 TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); }
128 class FakeRendererGL : public GLRenderer {
130 FakeRendererGL(RendererClient* client,
131 const LayerTreeSettings* settings,
132 OutputSurface* output_surface,
133 ResourceProvider* resource_provider)
141 // GLRenderer methods.
143 // Changing visibility to public.
144 using GLRenderer::IsBackbufferDiscarded;
145 using GLRenderer::DoDrawQuad;
146 using GLRenderer::BeginDrawingFrame;
147 using GLRenderer::FinishDrawingQuadList;
148 using GLRenderer::stencil_enabled;
151 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
153 GLRendererWithDefaultHarnessTest() {
155 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
156 CHECK(output_surface_->BindToClient(&output_surface_client_));
158 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
160 ResourceProvider::Create(
161 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
163 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
165 output_surface_.get(),
166 resource_provider_.get()));
169 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
171 LayerTreeSettings settings_;
172 FakeOutputSurfaceClient output_surface_client_;
173 scoped_ptr<FakeOutputSurface> output_surface_;
174 FakeRendererClient renderer_client_;
175 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
176 scoped_ptr<ResourceProvider> resource_provider_;
177 scoped_ptr<FakeRendererGL> renderer_;
180 // Closing the namespace here so that GLRendererShaderTest can take advantage
181 // of the friend relationship with GLRenderer and all of the mock classes
182 // declared above it.
185 class GLRendererShaderTest : public GLRendererTest {
187 GLRendererShaderTest() {
188 output_surface_ = FakeOutputSurface::Create3d().Pass();
189 CHECK(output_surface_->BindToClient(&output_surface_client_));
191 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
193 ResourceProvider::Create(
194 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
196 renderer_.reset(new FakeRendererGL(&renderer_client_,
198 output_surface_.get(),
199 resource_provider_.get()));
202 void TestRenderPassProgram(TexCoordPrecision precision) {
203 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_[precision]);
204 EXPECT_EQ(renderer_->render_pass_program_[precision].program(),
205 renderer_->program_shadow_);
208 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision) {
209 EXPECT_PROGRAM_VALID(
210 &renderer_->render_pass_color_matrix_program_[precision]);
211 EXPECT_EQ(renderer_->render_pass_color_matrix_program_[precision].program(),
212 renderer_->program_shadow_);
215 void TestRenderPassMaskProgram(TexCoordPrecision precision) {
216 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_[precision]);
217 EXPECT_EQ(renderer_->render_pass_mask_program_[precision].program(),
218 renderer_->program_shadow_);
221 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
222 EXPECT_PROGRAM_VALID(
223 &renderer_->render_pass_mask_color_matrix_program_[precision]);
225 renderer_->render_pass_mask_color_matrix_program_[precision].program(),
226 renderer_->program_shadow_);
229 void TestRenderPassProgramAA(TexCoordPrecision precision) {
230 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_aa_[precision]);
231 EXPECT_EQ(renderer_->render_pass_program_aa_[precision].program(),
232 renderer_->program_shadow_);
235 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
236 EXPECT_PROGRAM_VALID(
237 &renderer_->render_pass_color_matrix_program_aa_[precision]);
239 renderer_->render_pass_color_matrix_program_aa_[precision].program(),
240 renderer_->program_shadow_);
243 void TestRenderPassMaskProgramAA(TexCoordPrecision precision) {
244 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_aa_[precision]);
245 EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision].program(),
246 renderer_->program_shadow_);
249 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
250 EXPECT_PROGRAM_VALID(
251 &renderer_->render_pass_mask_color_matrix_program_aa_[precision]);
252 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_[precision]
254 renderer_->program_shadow_);
257 void TestSolidColorProgramAA() {
258 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
259 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
260 renderer_->program_shadow_);
263 LayerTreeSettings settings_;
264 FakeOutputSurfaceClient output_surface_client_;
265 scoped_ptr<FakeOutputSurface> output_surface_;
266 FakeRendererClient renderer_client_;
267 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
268 scoped_ptr<ResourceProvider> resource_provider_;
269 scoped_ptr<FakeRendererGL> renderer_;
274 // Test GLRenderer DiscardBackbuffer functionality:
275 // Suggest discarding framebuffer when one exists and the renderer is not
277 // Expected: it is discarded and damage tracker is reset.
279 GLRendererWithDefaultHarnessTest,
280 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
281 renderer_->SetVisible(false);
282 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
283 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
286 // Test GLRenderer DiscardBackbuffer functionality:
287 // Suggest discarding framebuffer when one exists and the renderer is visible.
288 // Expected: the allocation is ignored.
289 TEST_F(GLRendererWithDefaultHarnessTest,
290 SuggestBackbufferNoDoNothingWhenVisible) {
291 renderer_->SetVisible(true);
292 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
293 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
296 // Test GLRenderer DiscardBackbuffer functionality:
297 // Suggest discarding framebuffer when one does not exist.
298 // Expected: it does nothing.
299 TEST_F(GLRendererWithDefaultHarnessTest,
300 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
301 renderer_->SetVisible(false);
302 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
303 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
305 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
306 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
309 // Test GLRenderer DiscardBackbuffer functionality:
310 // Begin drawing a frame while a framebuffer is discarded.
311 // Expected: will recreate framebuffer.
312 TEST_F(GLRendererWithDefaultHarnessTest,
313 DiscardedBackbufferIsRecreatedForScopeDuration) {
314 gfx::Rect viewport_rect(1, 1);
315 renderer_->SetVisible(false);
316 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
317 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
319 AddRenderPass(&render_passes_in_draw_order_,
320 RenderPass::Id(1, 0),
324 renderer_->SetVisible(true);
325 renderer_->DrawFrame(&render_passes_in_draw_order_,
330 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
333 EXPECT_EQ(1u, output_surface_->num_sent_frames());
336 TEST_F(GLRendererWithDefaultHarnessTest,
337 FramebufferDiscardedAfterReadbackWhenNotVisible) {
338 gfx::Rect viewport_rect(1, 1);
339 renderer_->SetVisible(false);
340 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
341 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
343 AddRenderPass(&render_passes_in_draw_order_,
344 RenderPass::Id(1, 0),
349 renderer_->DrawFrame(&render_passes_in_draw_order_,
354 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
356 renderer_->GetFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1));
357 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
358 EXPECT_EQ(2, renderer_client_.set_full_root_layer_damage_count());
361 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
362 gfx::Rect viewport_rect(1, 1);
363 EXPECT_FALSE(renderer_->stencil_enabled());
365 output_surface_->set_has_external_stencil_test(true);
367 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
368 RenderPass::Id(1, 0),
371 root_pass->has_transparent_background = false;
373 renderer_->DrawFrame(&render_passes_in_draw_order_,
378 EXPECT_TRUE(renderer_->stencil_enabled());
381 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
383 ForbidSynchronousCallContext() {}
385 virtual void getAttachedShaders(GLuint program,
388 GLuint* shaders) OVERRIDE {
391 virtual GLint getAttribLocation(GLuint program, const GLchar* name) OVERRIDE {
395 virtual void getBooleanv(GLenum pname, GLboolean* value) OVERRIDE {
398 virtual void getBufferParameteriv(GLenum target,
400 GLint* value) OVERRIDE {
403 virtual GLenum getError() OVERRIDE {
407 virtual void getFloatv(GLenum pname, GLfloat* value) OVERRIDE {
410 virtual void getFramebufferAttachmentParameteriv(GLenum target,
413 GLint* value) OVERRIDE {
416 virtual void getIntegerv(GLenum pname, GLint* value) OVERRIDE {
417 if (pname == GL_MAX_TEXTURE_SIZE) {
418 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
425 // We allow querying the shader compilation and program link status in debug
426 // mode, but not release.
427 virtual void getProgramiv(GLuint program,
429 GLint* value) OVERRIDE {
437 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
445 virtual void getRenderbufferParameteriv(GLenum target,
447 GLint* value) OVERRIDE {
451 virtual void getShaderPrecisionFormat(GLenum shadertype,
452 GLenum precisiontype,
454 GLint* precision) OVERRIDE {
457 virtual void getTexParameterfv(GLenum target,
459 GLfloat* value) OVERRIDE {
462 virtual void getTexParameteriv(GLenum target,
464 GLint* value) OVERRIDE {
467 virtual void getUniformfv(GLuint program,
469 GLfloat* value) OVERRIDE {
472 virtual void getUniformiv(GLuint program,
474 GLint* value) OVERRIDE {
477 virtual GLint getUniformLocation(GLuint program,
478 const GLchar* name) OVERRIDE {
482 virtual void getVertexAttribfv(GLuint index,
484 GLfloat* value) OVERRIDE {
487 virtual void getVertexAttribiv(GLuint index,
489 GLint* value) OVERRIDE {
492 virtual GLsizeiptr getVertexAttribOffset(GLuint index,
493 GLenum pname) OVERRIDE {
498 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
499 FakeOutputSurfaceClient output_surface_client;
500 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
501 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
502 CHECK(output_surface->BindToClient(&output_surface_client));
504 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
505 new TestSharedBitmapManager());
506 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
507 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
509 LayerTreeSettings settings;
510 FakeRendererClient renderer_client;
511 FakeRendererGL renderer(&renderer_client,
513 output_surface.get(),
514 resource_provider.get());
517 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
519 LoseContextOnFirstGetContext() {}
521 virtual void getProgramiv(GLuint program,
523 GLint* value) OVERRIDE {
524 context_lost_ = true;
528 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
529 context_lost_ = true;
534 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
535 FakeOutputSurfaceClient output_surface_client;
536 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
537 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
538 CHECK(output_surface->BindToClient(&output_surface_client));
540 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
541 new TestSharedBitmapManager());
542 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
543 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
545 LayerTreeSettings settings;
546 FakeRendererClient renderer_client;
547 FakeRendererGL renderer(&renderer_client,
549 output_surface.get(),
550 resource_provider.get());
553 class ClearCountingContext : public TestWebGraphicsContext3D {
555 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
557 MOCK_METHOD3(discardFramebufferEXT,
559 GLsizei numAttachments,
560 const GLenum* attachments));
561 MOCK_METHOD1(clear, void(GLbitfield mask));
564 TEST_F(GLRendererTest, OpaqueBackground) {
565 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
566 ClearCountingContext* context = context_owned.get();
568 FakeOutputSurfaceClient output_surface_client;
569 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
570 context_owned.PassAs<TestWebGraphicsContext3D>()));
571 CHECK(output_surface->BindToClient(&output_surface_client));
573 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
574 new TestSharedBitmapManager());
575 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
576 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
578 LayerTreeSettings settings;
579 FakeRendererClient renderer_client;
580 FakeRendererGL renderer(&renderer_client,
582 output_surface.get(),
583 resource_provider.get());
585 gfx::Rect viewport_rect(1, 1);
586 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
587 RenderPass::Id(1, 0),
590 root_pass->has_transparent_background = false;
592 // On DEBUG builds, render passes with opaque background clear to blue to
593 // easily see regions that were not drawn on the screen.
594 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
595 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
598 EXPECT_CALL(*context, clear(_)).Times(0);
600 EXPECT_CALL(*context, clear(_)).Times(1);
602 renderer.DrawFrame(&render_passes_in_draw_order_,
607 Mock::VerifyAndClearExpectations(context);
610 TEST_F(GLRendererTest, TransparentBackground) {
611 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
612 ClearCountingContext* context = context_owned.get();
614 FakeOutputSurfaceClient output_surface_client;
615 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
616 context_owned.PassAs<TestWebGraphicsContext3D>()));
617 CHECK(output_surface->BindToClient(&output_surface_client));
619 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
620 new TestSharedBitmapManager());
621 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
622 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
624 LayerTreeSettings settings;
625 FakeRendererClient renderer_client;
626 FakeRendererGL renderer(&renderer_client,
628 output_surface.get(),
629 resource_provider.get());
631 gfx::Rect viewport_rect(1, 1);
632 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
633 RenderPass::Id(1, 0),
636 root_pass->has_transparent_background = true;
638 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
639 EXPECT_CALL(*context, clear(_)).Times(1);
640 renderer.DrawFrame(&render_passes_in_draw_order_,
646 Mock::VerifyAndClearExpectations(context);
649 TEST_F(GLRendererTest, OffscreenOutputSurface) {
650 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
651 ClearCountingContext* context = context_owned.get();
653 FakeOutputSurfaceClient output_surface_client;
654 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateOffscreen(
655 context_owned.PassAs<TestWebGraphicsContext3D>()));
656 CHECK(output_surface->BindToClient(&output_surface_client));
658 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
659 new TestSharedBitmapManager());
660 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
661 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
663 LayerTreeSettings settings;
664 FakeRendererClient renderer_client;
665 FakeRendererGL renderer(&renderer_client,
667 output_surface.get(),
668 resource_provider.get());
670 gfx::Rect viewport_rect(1, 1);
671 AddRenderPass(&render_passes_in_draw_order_,
672 RenderPass::Id(1, 0),
676 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
677 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
679 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
680 renderer.DrawFrame(&render_passes_in_draw_order_,
685 Mock::VerifyAndClearExpectations(context);
688 class VisibilityChangeIsLastCallTrackingContext
689 : public TestWebGraphicsContext3D {
691 VisibilityChangeIsLastCallTrackingContext()
692 : last_call_was_set_visibility_(false) {}
694 // TestWebGraphicsContext3D methods.
695 virtual void flush() OVERRIDE { last_call_was_set_visibility_ = false; }
696 virtual void deleteTexture(GLuint) OVERRIDE {
697 last_call_was_set_visibility_ = false;
699 virtual void deleteFramebuffer(GLuint) OVERRIDE {
700 last_call_was_set_visibility_ = false;
702 virtual void deleteQueryEXT(GLuint) OVERRIDE {
703 last_call_was_set_visibility_ = false;
705 virtual void deleteRenderbuffer(GLuint) OVERRIDE {
706 last_call_was_set_visibility_ = false;
709 // Methods added for test.
710 void set_last_call_was_visibility(bool visible) {
711 DCHECK(last_call_was_set_visibility_ == false);
712 last_call_was_set_visibility_ = true;
714 bool last_call_was_set_visibility() const {
715 return last_call_was_set_visibility_;
719 bool last_call_was_set_visibility_;
722 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
723 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
724 new VisibilityChangeIsLastCallTrackingContext);
725 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
727 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(
728 context_owned.PassAs<TestWebGraphicsContext3D>());
730 provider->support()->SetSurfaceVisibleCallback(base::Bind(
731 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
732 base::Unretained(context)));
734 FakeOutputSurfaceClient output_surface_client;
735 scoped_ptr<OutputSurface> output_surface(
736 FakeOutputSurface::Create3d(provider));
737 CHECK(output_surface->BindToClient(&output_surface_client));
739 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
740 new TestSharedBitmapManager());
741 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
742 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
744 LayerTreeSettings settings;
745 FakeRendererClient renderer_client;
746 FakeRendererGL renderer(&renderer_client,
748 output_surface.get(),
749 resource_provider.get());
751 gfx::Rect viewport_rect(1, 1);
752 AddRenderPass(&render_passes_in_draw_order_,
753 RenderPass::Id(1, 0),
757 // Ensure that the call to SetSurfaceVisible is the last call issue to the
758 // GPU process, after glFlush is called, and after the RendererClient's
759 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
760 // RenderClient and the Context by giving them both a pointer to a variable on
762 renderer.SetVisible(true);
763 renderer.DrawFrame(&render_passes_in_draw_order_,
768 renderer.SetVisible(false);
769 EXPECT_TRUE(context->last_call_was_set_visibility());
772 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
774 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
775 test_capabilities_.gpu.egl_image_external = true;
778 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
779 MOCK_METHOD4(drawElements,
780 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
782 virtual void activeTexture(GLenum texture) {
783 EXPECT_NE(texture, active_texture_);
784 active_texture_ = texture;
787 GLenum active_texture() const { return active_texture_; }
790 GLenum active_texture_;
793 TEST_F(GLRendererTest, ActiveTextureState) {
794 scoped_ptr<TextureStateTrackingContext> context_owned(
795 new TextureStateTrackingContext);
796 TextureStateTrackingContext* context = context_owned.get();
798 FakeOutputSurfaceClient output_surface_client;
799 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
800 context_owned.PassAs<TestWebGraphicsContext3D>()));
801 CHECK(output_surface->BindToClient(&output_surface_client));
803 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
804 new TestSharedBitmapManager());
805 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
806 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
808 LayerTreeSettings settings;
809 FakeRendererClient renderer_client;
810 FakeRendererGL renderer(&renderer_client,
812 output_surface.get(),
813 resource_provider.get());
815 // During initialization we are allowed to set any texture parameters.
816 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
818 RenderPass::Id id(1, 1);
819 TestRenderPass* root_pass = AddRenderPass(
820 &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
821 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
822 RenderPass::Id(2, 1));
824 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
826 // Set up expected texture filter state transitions that match the quads
827 // created in AppendOneOfEveryQuadType().
828 Mock::VerifyAndClearExpectations(context);
832 // yuv_quad is drawn with the default linear filter.
833 EXPECT_CALL(*context, drawElements(_, _, _, _));
835 // tile_quad is drawn with GL_NEAREST because it is not transformed or
839 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
842 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
843 EXPECT_CALL(*context, drawElements(_, _, _, _));
845 // transformed_tile_quad uses GL_LINEAR.
846 EXPECT_CALL(*context, drawElements(_, _, _, _));
848 // scaled_tile_quad also uses GL_LINEAR.
849 EXPECT_CALL(*context, drawElements(_, _, _, _));
851 // The remaining quads also use GL_LINEAR because nearest neighbor
852 // filtering is currently only used with tile quads.
853 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6);
856 gfx::Rect viewport_rect(100, 100);
857 renderer.DrawFrame(&render_passes_in_draw_order_,
862 Mock::VerifyAndClearExpectations(context);
865 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
867 MOCK_METHOD1(clear, void(GLbitfield mask));
868 MOCK_METHOD4(drawElements,
869 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
872 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
873 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
874 new NoClearRootRenderPassMockContext);
875 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
877 FakeOutputSurfaceClient output_surface_client;
878 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
879 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
880 CHECK(output_surface->BindToClient(&output_surface_client));
882 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
883 new TestSharedBitmapManager());
884 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
885 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
887 LayerTreeSettings settings;
888 settings.should_clear_root_render_pass = false;
890 FakeRendererClient renderer_client;
891 FakeRendererGL renderer(&renderer_client,
893 output_surface.get(),
894 resource_provider.get());
896 gfx::Rect viewport_rect(10, 10);
898 RenderPass::Id root_pass_id(1, 0);
899 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
903 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
905 RenderPass::Id child_pass_id(2, 0);
906 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
910 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
912 AddRenderPassQuad(root_pass, child_pass);
915 GLint clear_bits = GL_COLOR_BUFFER_BIT;
917 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
920 // First render pass is not the root one, clearing should happen.
921 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
923 Expectation first_render_pass =
924 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
926 // The second render pass is the root one, clearing should be prevented.
927 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
930 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
933 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
934 renderer.DrawFrame(&render_passes_in_draw_order_,
940 // In multiple render passes all but the root pass should clear the
942 Mock::VerifyAndClearExpectations(&mock_context);
945 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
947 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
949 virtual void clear(GLbitfield) OVERRIDE { EXPECT_FALSE(scissor_enabled_); }
951 virtual void enable(GLenum cap) OVERRIDE {
952 if (cap == GL_SCISSOR_TEST)
953 scissor_enabled_ = true;
956 virtual void disable(GLenum cap) OVERRIDE {
957 if (cap == GL_SCISSOR_TEST)
958 scissor_enabled_ = false;
962 bool scissor_enabled_;
965 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
966 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
967 new ScissorTestOnClearCheckingContext);
969 FakeOutputSurfaceClient output_surface_client;
970 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
971 context_owned.PassAs<TestWebGraphicsContext3D>()));
972 CHECK(output_surface->BindToClient(&output_surface_client));
974 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
975 new TestSharedBitmapManager());
976 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
977 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
979 LayerTreeSettings settings;
980 FakeRendererClient renderer_client;
981 FakeRendererGL renderer(&renderer_client,
983 output_surface.get(),
984 resource_provider.get());
985 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
987 gfx::Rect viewport_rect(1, 1);
989 gfx::Rect grand_child_rect(25, 25);
990 RenderPass::Id grand_child_pass_id(3, 0);
991 TestRenderPass* grand_child_pass =
992 AddRenderPass(&render_passes_in_draw_order_,
996 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
998 gfx::Rect child_rect(50, 50);
999 RenderPass::Id child_pass_id(2, 0);
1000 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
1004 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1006 RenderPass::Id root_pass_id(1, 0);
1007 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1011 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1013 AddRenderPassQuad(root_pass, child_pass);
1014 AddRenderPassQuad(child_pass, grand_child_pass);
1016 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1017 renderer.DrawFrame(&render_passes_in_draw_order_,
1024 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1026 DiscardCheckingContext() : discarded_(0) {
1027 set_have_post_sub_buffer(true);
1028 set_have_discard_framebuffer(true);
1031 virtual void discardFramebufferEXT(GLenum target,
1032 GLsizei numAttachments,
1033 const GLenum* attachments) OVERRIDE {
1037 int discarded() const { return discarded_; }
1038 void reset() { discarded_ = 0; }
1044 class NonReshapableOutputSurface : public FakeOutputSurface {
1046 explicit NonReshapableOutputSurface(
1047 scoped_ptr<TestWebGraphicsContext3D> context3d)
1048 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1050 surface_size_ = gfx::Size(500, 500);
1052 virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {}
1053 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1056 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1057 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1058 DiscardCheckingContext* context = context_owned.get();
1060 FakeOutputSurfaceClient output_surface_client;
1061 scoped_ptr<NonReshapableOutputSurface> output_surface(
1062 new NonReshapableOutputSurface(
1063 context_owned.PassAs<TestWebGraphicsContext3D>()));
1064 CHECK(output_surface->BindToClient(&output_surface_client));
1065 output_surface->set_fixed_size(gfx::Size(100, 100));
1067 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1068 new TestSharedBitmapManager());
1069 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1070 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
1072 LayerTreeSettings settings;
1073 settings.partial_swap_enabled = true;
1074 FakeRendererClient renderer_client;
1075 FakeRendererGL renderer(&renderer_client,
1077 output_surface.get(),
1078 resource_provider.get());
1079 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1081 gfx::Rect viewport_rect(100, 100);
1082 gfx::Rect clip_rect(100, 100);
1085 // Partial frame, should not discard.
1086 RenderPass::Id root_pass_id(1, 0);
1087 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1091 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1092 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1094 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1095 renderer.DrawFrame(&render_passes_in_draw_order_,
1100 EXPECT_EQ(0, context->discarded());
1104 // Full frame, should discard.
1105 RenderPass::Id root_pass_id(1, 0);
1106 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1110 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1111 root_pass->damage_rect = root_pass->output_rect;
1113 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1114 renderer.DrawFrame(&render_passes_in_draw_order_,
1119 EXPECT_EQ(1, context->discarded());
1123 // Full frame, external scissor is set, should not discard.
1124 output_surface->set_has_external_stencil_test(true);
1125 RenderPass::Id root_pass_id(1, 0);
1126 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1130 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1131 root_pass->damage_rect = root_pass->output_rect;
1132 root_pass->has_transparent_background = false;
1134 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1135 renderer.DrawFrame(&render_passes_in_draw_order_,
1140 EXPECT_EQ(0, context->discarded());
1142 output_surface->set_has_external_stencil_test(false);
1145 // Full frame, clipped, should not discard.
1146 clip_rect = gfx::Rect(10, 10, 10, 10);
1147 RenderPass::Id root_pass_id(1, 0);
1148 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1152 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1153 root_pass->damage_rect = root_pass->output_rect;
1155 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1156 renderer.DrawFrame(&render_passes_in_draw_order_,
1161 EXPECT_EQ(0, context->discarded());
1165 // Full frame, doesn't cover the surface, should not discard.
1166 viewport_rect = gfx::Rect(10, 10, 10, 10);
1167 RenderPass::Id 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());
1185 // Full frame, doesn't cover the surface (no offset), should not discard.
1186 clip_rect = gfx::Rect(100, 100);
1187 viewport_rect = gfx::Rect(50, 50);
1188 RenderPass::Id root_pass_id(1, 0);
1189 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1193 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1194 root_pass->damage_rect = root_pass->output_rect;
1196 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1197 renderer.DrawFrame(&render_passes_in_draw_order_,
1202 EXPECT_EQ(0, context->discarded());
1207 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1209 FlippedScissorAndViewportContext()
1210 : did_call_viewport_(false), did_call_scissor_(false) {}
1211 virtual ~FlippedScissorAndViewportContext() {
1212 EXPECT_TRUE(did_call_viewport_);
1213 EXPECT_TRUE(did_call_scissor_);
1216 virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1220 EXPECT_EQ(100, width);
1221 EXPECT_EQ(100, height);
1222 did_call_viewport_ = true;
1225 virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1229 EXPECT_EQ(20, width);
1230 EXPECT_EQ(20, height);
1231 did_call_scissor_ = true;
1235 bool did_call_viewport_;
1236 bool did_call_scissor_;
1239 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1240 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1241 // and maintains a fixed size. This test verifies that glViewport and
1242 // glScissor's Y coordinate is flipped correctly in this environment, and that
1243 // the glViewport can be at a nonzero origin within the surface.
1244 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1245 new FlippedScissorAndViewportContext);
1247 FakeOutputSurfaceClient output_surface_client;
1248 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface(
1249 context_owned.PassAs<TestWebGraphicsContext3D>()));
1250 CHECK(output_surface->BindToClient(&output_surface_client));
1252 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1253 new TestSharedBitmapManager());
1254 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1255 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
1257 LayerTreeSettings settings;
1258 FakeRendererClient renderer_client;
1259 FakeRendererGL renderer(&renderer_client,
1261 output_surface.get(),
1262 resource_provider.get());
1263 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1265 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1266 gfx::Rect viewport_rect(device_viewport_rect.size());
1267 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1269 RenderPass::Id root_pass_id(1, 0);
1270 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1274 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1276 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1277 renderer.DrawFrame(&render_passes_in_draw_order_,
1279 device_viewport_rect,
1280 device_viewport_rect,
1284 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1285 gfx::Rect viewport_rect(1, 1);
1287 gfx::Rect child_rect(50, 50);
1288 RenderPass::Id child_pass_id(2, 0);
1289 TestRenderPass* child_pass;
1291 RenderPass::Id root_pass_id(1, 0);
1292 TestRenderPass* root_pass;
1294 ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
1297 ResourceProvider::TextureUsageAny,
1298 resource_provider_->best_texture_format());
1299 resource_provider_->AllocateForTesting(mask);
1301 SkScalar matrix[20];
1302 float amount = 0.5f;
1303 matrix[0] = 0.213f + 0.787f * amount;
1304 matrix[1] = 0.715f - 0.715f * amount;
1305 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1306 matrix[3] = matrix[4] = 0;
1307 matrix[5] = 0.213f - 0.213f * amount;
1308 matrix[6] = 0.715f + 0.285f * amount;
1309 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1310 matrix[8] = matrix[9] = 0;
1311 matrix[10] = 0.213f - 0.213f * amount;
1312 matrix[11] = 0.715f - 0.715f * amount;
1313 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1314 matrix[13] = matrix[14] = 0;
1315 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1317 skia::RefPtr<SkColorFilter> color_filter(
1318 skia::AdoptRef(new SkColorMatrixFilter(matrix)));
1319 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1320 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1321 FilterOperations filters;
1322 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1324 gfx::Transform transform_causing_aa;
1325 transform_causing_aa.Rotate(20.0);
1327 // RenderPassProgram
1328 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1333 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1339 root_pass, child_pass, 0, FilterOperations(), gfx::Transform());
1341 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1342 renderer_->DrawFrame(&render_passes_in_draw_order_,
1347 TestRenderPassProgram(TexCoordPrecisionMedium);
1349 // RenderPassColorMatrixProgram
1350 render_passes_in_draw_order_.clear();
1352 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1355 transform_causing_aa);
1357 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1362 AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform());
1364 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1365 renderer_->DrawFrame(&render_passes_in_draw_order_,
1370 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium);
1372 // RenderPassMaskProgram
1373 render_passes_in_draw_order_.clear();
1375 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1380 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1386 root_pass, child_pass, mask, FilterOperations(), gfx::Transform());
1388 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1389 renderer_->DrawFrame(&render_passes_in_draw_order_,
1394 TestRenderPassMaskProgram(TexCoordPrecisionMedium);
1396 // RenderPassMaskColorMatrixProgram
1397 render_passes_in_draw_order_.clear();
1399 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1404 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1409 AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform());
1411 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1412 renderer_->DrawFrame(&render_passes_in_draw_order_,
1417 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium);
1419 // RenderPassProgramAA
1420 render_passes_in_draw_order_.clear();
1422 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1425 transform_causing_aa);
1427 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1433 root_pass, child_pass, 0, FilterOperations(), transform_causing_aa);
1435 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1436 renderer_->DrawFrame(&render_passes_in_draw_order_,
1441 TestRenderPassProgramAA(TexCoordPrecisionMedium);
1443 // RenderPassColorMatrixProgramAA
1444 render_passes_in_draw_order_.clear();
1446 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1449 transform_causing_aa);
1451 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1456 AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa);
1458 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1459 renderer_->DrawFrame(&render_passes_in_draw_order_,
1464 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium);
1466 // RenderPassMaskProgramAA
1467 render_passes_in_draw_order_.clear();
1469 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1472 transform_causing_aa);
1474 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1480 root_pass, child_pass, mask, FilterOperations(), transform_causing_aa);
1482 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1483 renderer_->DrawFrame(&render_passes_in_draw_order_,
1488 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium);
1490 // RenderPassMaskColorMatrixProgramAA
1491 render_passes_in_draw_order_.clear();
1493 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1496 transform_causing_aa);
1498 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1501 transform_causing_aa);
1503 AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa);
1505 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1506 renderer_->DrawFrame(&render_passes_in_draw_order_,
1511 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium);
1514 // At this time, the AA code path cannot be taken if the surface's rect would
1515 // project incorrectly by the given transform, because of w<0 clipping.
1516 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1517 gfx::Rect child_rect(50, 50);
1518 RenderPass::Id child_pass_id(2, 0);
1519 TestRenderPass* child_pass;
1521 gfx::Rect viewport_rect(1, 1);
1522 RenderPass::Id root_pass_id(1, 0);
1523 TestRenderPass* root_pass;
1525 gfx::Transform transform_preventing_aa;
1526 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1527 transform_preventing_aa.RotateAboutYAxis(-20.0);
1528 transform_preventing_aa.Scale(30.0, 1.0);
1530 // Verify that the test transform and test rect actually do cause the clipped
1531 // flag to trigger. Otherwise we are not testing the intended scenario.
1532 bool clipped = false;
1533 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1534 ASSERT_TRUE(clipped);
1536 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1539 transform_preventing_aa);
1541 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1547 root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa);
1549 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1550 renderer_->DrawFrame(&render_passes_in_draw_order_,
1556 // If use_aa incorrectly ignores clipping, it will use the
1557 // RenderPassProgramAA shader instead of the RenderPassProgram.
1558 TestRenderPassProgram(TexCoordPrecisionMedium);
1561 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1562 gfx::Rect viewport_rect(1, 1);
1563 RenderPass::Id root_pass_id(1, 0);
1564 TestRenderPass* root_pass;
1566 gfx::Transform pixel_aligned_transform_causing_aa;
1567 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1568 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1570 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1574 AddTransformedQuad(root_pass,
1577 pixel_aligned_transform_causing_aa);
1579 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1580 renderer_->DrawFrame(&render_passes_in_draw_order_,
1586 TestSolidColorProgramAA();
1589 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1591 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1593 // Specifically override methods even if they are unused (used in conjunction
1594 // with StrictMock). We need to make sure that GLRenderer does not issue
1595 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1596 // through the OutputSurface abstraction.
1597 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1598 MOCK_METHOD3(reshapeWithScaleFactor,
1599 void(int width, int height, float scale_factor));
1600 MOCK_METHOD4(drawElements,
1601 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1604 class MockOutputSurface : public OutputSurface {
1608 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1609 new StrictMock<OutputSurfaceMockContext>))) {
1610 surface_size_ = gfx::Size(100, 100);
1612 virtual ~MockOutputSurface() {}
1614 MOCK_METHOD0(EnsureBackbuffer, void());
1615 MOCK_METHOD0(DiscardBackbuffer, void());
1616 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1617 MOCK_METHOD0(BindFramebuffer, void());
1618 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1621 class MockOutputSurfaceTest : public GLRendererTest {
1623 virtual void SetUp() {
1624 FakeOutputSurfaceClient output_surface_client_;
1625 CHECK(output_surface_.BindToClient(&output_surface_client_));
1627 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1628 resource_provider_ =
1629 ResourceProvider::Create(
1630 &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false)
1633 renderer_.reset(new FakeRendererGL(&renderer_client_,
1636 resource_provider_.get()));
1639 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1641 void DrawFrame(float device_scale_factor,
1642 const gfx::Rect& device_viewport_rect) {
1643 RenderPass::Id render_pass_id(1, 0);
1644 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1646 device_viewport_rect,
1648 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1650 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1652 EXPECT_CALL(output_surface_,
1653 Reshape(device_viewport_rect.size(), device_scale_factor))
1656 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1658 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1660 renderer_->DecideRenderPassAllocationsForFrame(
1661 render_passes_in_draw_order_);
1662 renderer_->DrawFrame(&render_passes_in_draw_order_,
1663 device_scale_factor,
1664 device_viewport_rect,
1665 device_viewport_rect,
1669 OutputSurfaceMockContext* Context() {
1670 return static_cast<OutputSurfaceMockContext*>(
1671 static_cast<TestContextProvider*>(
1672 output_surface_.context_provider().get())->TestContext3d());
1675 LayerTreeSettings settings_;
1676 FakeOutputSurfaceClient output_surface_client_;
1677 StrictMock<MockOutputSurface> output_surface_;
1678 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1679 scoped_ptr<ResourceProvider> resource_provider_;
1680 FakeRendererClient renderer_client_;
1681 scoped_ptr<FakeRendererGL> renderer_;
1684 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1685 gfx::Rect device_viewport_rect(1, 1);
1686 DrawFrame(1.f, device_viewport_rect);
1688 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1689 renderer_->SwapBuffers(CompositorFrameMetadata());
1692 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1693 gfx::Rect device_viewport_rect(1, 1);
1695 DrawFrame(1.f, device_viewport_rect);
1696 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1697 renderer_->SwapBuffers(CompositorFrameMetadata());
1699 device_viewport_rect = gfx::Rect(2, 2);
1701 DrawFrame(2.f, device_viewport_rect);
1702 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1703 renderer_->SwapBuffers(CompositorFrameMetadata());
1705 DrawFrame(2.f, device_viewport_rect);
1706 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1707 renderer_->SwapBuffers(CompositorFrameMetadata());
1709 device_viewport_rect = gfx::Rect(1, 1);
1711 DrawFrame(1.f, device_viewport_rect);
1712 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1713 renderer_->SwapBuffers(CompositorFrameMetadata());
1716 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1718 static void SyncPointCallback(int* callback_count) {
1719 ++(*callback_count);
1720 base::MessageLoop::current()->QuitWhenIdle();
1723 static void OtherCallback(int* callback_count) {
1724 ++(*callback_count);
1725 base::MessageLoop::current()->QuitWhenIdle();
1729 #if !defined(OS_ANDROID)
1730 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1731 int sync_point_callback_count = 0;
1732 int other_callback_count = 0;
1733 gpu::gles2::GLES2Interface* gl =
1734 output_surface_->context_provider()->ContextGL();
1735 gpu::ContextSupport* context_support =
1736 output_surface_->context_provider()->ContextSupport();
1738 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1740 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1741 GL_INNOCENT_CONTEXT_RESET_ARB);
1743 context_support->SignalSyncPoint(
1744 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1745 EXPECT_EQ(0, sync_point_callback_count);
1746 EXPECT_EQ(0, other_callback_count);
1748 // Make the sync point happen.
1750 // Post a task after the sync point.
1751 base::MessageLoop::current()->PostTask(
1752 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1754 base::MessageLoop::current()->Run();
1756 // The sync point shouldn't have happened since the context was lost.
1757 EXPECT_EQ(0, sync_point_callback_count);
1758 EXPECT_EQ(1, other_callback_count);
1761 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1762 int sync_point_callback_count = 0;
1763 int other_callback_count = 0;
1765 gpu::gles2::GLES2Interface* gl =
1766 output_surface_->context_provider()->ContextGL();
1767 gpu::ContextSupport* context_support =
1768 output_surface_->context_provider()->ContextSupport();
1770 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1772 context_support->SignalSyncPoint(
1773 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1774 EXPECT_EQ(0, sync_point_callback_count);
1775 EXPECT_EQ(0, other_callback_count);
1777 // Make the sync point happen.
1779 // Post a task after the sync point.
1780 base::MessageLoop::current()->PostTask(
1781 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1783 base::MessageLoop::current()->Run();
1785 // The sync point should have happened.
1786 EXPECT_EQ(1, sync_point_callback_count);
1787 EXPECT_EQ(1, other_callback_count);
1789 #endif // OS_ANDROID