1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/gl_renderer.h"
9 #include "cc/base/math_util.h"
10 #include "cc/output/compositor_frame_metadata.h"
11 #include "cc/resources/resource_provider.h"
12 #include "cc/test/fake_impl_proxy.h"
13 #include "cc/test/fake_layer_tree_host_impl.h"
14 #include "cc/test/fake_output_surface.h"
15 #include "cc/test/fake_output_surface_client.h"
16 #include "cc/test/fake_renderer_client.h"
17 #include "cc/test/pixel_test.h"
18 #include "cc/test/render_pass_test_common.h"
19 #include "cc/test/render_pass_test_utils.h"
20 #include "cc/test/test_shared_bitmap_manager.h"
21 #include "cc/test/test_web_graphics_context_3d.h"
22 #include "gpu/GLES2/gl2extchromium.h"
23 #include "gpu/command_buffer/client/context_support.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/skia/include/core/SkImageFilter.h"
27 #include "third_party/skia/include/core/SkMatrix.h"
28 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
29 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
30 #include "ui/gfx/transform.h"
33 using testing::AnyNumber;
35 using testing::AtLeast;
36 using testing::ElementsAre;
37 using testing::Expectation;
38 using testing::InSequence;
40 using testing::Return;
41 using testing::StrictMock;
45 class GLRendererTest : public testing::Test {
47 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
49 RenderPassList render_passes_in_draw_order_;
52 #define EXPECT_PROGRAM_VALID(program_binding) \
54 EXPECT_TRUE((program_binding)->program()); \
55 EXPECT_TRUE((program_binding)->initialized()); \
58 // Explicitly named to be a friend in GLRenderer for shader access.
59 class GLRendererShaderPixelTest : public GLRendererPixelTest {
62 ASSERT_FALSE(renderer()->IsContextLost());
63 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
64 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
65 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
66 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
67 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium);
68 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh);
69 ASSERT_FALSE(renderer()->IsContextLost());
72 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision) {
73 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision));
74 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision));
75 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision));
76 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision));
78 renderer()->GetRenderPassColorMatrixProgram(precision));
80 renderer()->GetRenderPassMaskColorMatrixProgramAA(precision));
82 renderer()->GetRenderPassColorMatrixProgramAA(precision));
84 renderer()->GetRenderPassMaskColorMatrixProgram(precision));
85 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
87 renderer()->GetNonPremultipliedTextureProgram(precision));
88 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision));
90 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision));
91 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
92 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision));
93 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision));
94 // This is unlikely to be ever true in tests due to usage of osmesa.
95 if (renderer()->Capabilities().using_egl_image)
96 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
98 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
99 TestShadersWithSamplerType(precision, SamplerType2D);
100 TestShadersWithSamplerType(precision, SamplerType2DRect);
101 // This is unlikely to be ever true in tests due to usage of osmesa.
102 if (renderer()->Capabilities().using_egl_image)
103 TestShadersWithSamplerType(precision, SamplerTypeExternalOES);
106 void TestShadersWithSamplerType(TexCoordPrecision precision,
107 SamplerType sampler) {
108 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
109 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
110 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
111 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
112 EXPECT_PROGRAM_VALID(
113 renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
114 EXPECT_PROGRAM_VALID(
115 renderer()->GetTileProgramSwizzleAA(precision, sampler));
121 #if !defined(OS_ANDROID)
122 TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); }
125 class FakeRendererGL : public GLRenderer {
127 FakeRendererGL(RendererClient* client,
128 const LayerTreeSettings* settings,
129 OutputSurface* output_surface,
130 ResourceProvider* resource_provider)
138 // GLRenderer methods.
140 // Changing visibility to public.
141 using GLRenderer::IsBackbufferDiscarded;
142 using GLRenderer::DoDrawQuad;
143 using GLRenderer::BeginDrawingFrame;
144 using GLRenderer::FinishDrawingQuadList;
145 using GLRenderer::stencil_enabled;
148 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
150 GLRendererWithDefaultHarnessTest() {
152 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
153 CHECK(output_surface_->BindToClient(&output_surface_client_));
155 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
156 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
157 shared_bitmap_manager_.get(),
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());
192 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
193 shared_bitmap_manager_.get(),
199 renderer_.reset(new FakeRendererGL(&renderer_client_,
201 output_surface_.get(),
202 resource_provider_.get()));
205 void TestRenderPassProgram(TexCoordPrecision precision) {
206 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_[precision]);
207 EXPECT_EQ(renderer_->render_pass_program_[precision].program(),
208 renderer_->program_shadow_);
211 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision) {
212 EXPECT_PROGRAM_VALID(
213 &renderer_->render_pass_color_matrix_program_[precision]);
214 EXPECT_EQ(renderer_->render_pass_color_matrix_program_[precision].program(),
215 renderer_->program_shadow_);
218 void TestRenderPassMaskProgram(TexCoordPrecision precision) {
219 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_[precision]);
220 EXPECT_EQ(renderer_->render_pass_mask_program_[precision].program(),
221 renderer_->program_shadow_);
224 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
225 EXPECT_PROGRAM_VALID(
226 &renderer_->render_pass_mask_color_matrix_program_[precision]);
228 renderer_->render_pass_mask_color_matrix_program_[precision].program(),
229 renderer_->program_shadow_);
232 void TestRenderPassProgramAA(TexCoordPrecision precision) {
233 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_aa_[precision]);
234 EXPECT_EQ(renderer_->render_pass_program_aa_[precision].program(),
235 renderer_->program_shadow_);
238 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
239 EXPECT_PROGRAM_VALID(
240 &renderer_->render_pass_color_matrix_program_aa_[precision]);
242 renderer_->render_pass_color_matrix_program_aa_[precision].program(),
243 renderer_->program_shadow_);
246 void TestRenderPassMaskProgramAA(TexCoordPrecision precision) {
247 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_aa_[precision]);
248 EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision].program(),
249 renderer_->program_shadow_);
252 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
253 EXPECT_PROGRAM_VALID(
254 &renderer_->render_pass_mask_color_matrix_program_aa_[precision]);
255 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_[precision]
257 renderer_->program_shadow_);
260 void TestSolidColorProgramAA() {
261 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
262 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
263 renderer_->program_shadow_);
266 LayerTreeSettings settings_;
267 FakeOutputSurfaceClient output_surface_client_;
268 scoped_ptr<FakeOutputSurface> output_surface_;
269 FakeRendererClient renderer_client_;
270 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
271 scoped_ptr<ResourceProvider> resource_provider_;
272 scoped_ptr<FakeRendererGL> renderer_;
277 // Test GLRenderer DiscardBackbuffer functionality:
278 // Suggest discarding framebuffer when one exists and the renderer is not
280 // Expected: it is discarded and damage tracker is reset.
282 GLRendererWithDefaultHarnessTest,
283 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
284 renderer_->SetVisible(false);
285 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
286 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
289 // Test GLRenderer DiscardBackbuffer functionality:
290 // Suggest discarding framebuffer when one exists and the renderer is visible.
291 // Expected: the allocation is ignored.
292 TEST_F(GLRendererWithDefaultHarnessTest,
293 SuggestBackbufferNoDoNothingWhenVisible) {
294 renderer_->SetVisible(true);
295 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
296 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
299 // Test GLRenderer DiscardBackbuffer functionality:
300 // Suggest discarding framebuffer when one does not exist.
301 // Expected: it does nothing.
302 TEST_F(GLRendererWithDefaultHarnessTest,
303 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
304 renderer_->SetVisible(false);
305 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
306 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
308 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
309 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
312 // Test GLRenderer DiscardBackbuffer functionality:
313 // Begin drawing a frame while a framebuffer is discarded.
314 // Expected: will recreate framebuffer.
315 TEST_F(GLRendererWithDefaultHarnessTest,
316 DiscardedBackbufferIsRecreatedForScopeDuration) {
317 gfx::Rect viewport_rect(1, 1);
318 renderer_->SetVisible(false);
319 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
320 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
322 AddRenderPass(&render_passes_in_draw_order_,
327 renderer_->SetVisible(true);
328 renderer_->DrawFrame(&render_passes_in_draw_order_,
333 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
336 EXPECT_EQ(1u, output_surface_->num_sent_frames());
339 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
340 gfx::Rect viewport_rect(1, 1);
341 EXPECT_FALSE(renderer_->stencil_enabled());
343 output_surface_->set_has_external_stencil_test(true);
345 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
349 root_pass->has_transparent_background = false;
351 renderer_->DrawFrame(&render_passes_in_draw_order_,
356 EXPECT_TRUE(renderer_->stencil_enabled());
359 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
361 ForbidSynchronousCallContext() {}
363 virtual void getAttachedShaders(GLuint program,
366 GLuint* shaders) OVERRIDE {
369 virtual GLint getAttribLocation(GLuint program, const GLchar* name) OVERRIDE {
373 virtual void getBooleanv(GLenum pname, GLboolean* value) OVERRIDE {
376 virtual void getBufferParameteriv(GLenum target,
378 GLint* value) OVERRIDE {
381 virtual GLenum getError() OVERRIDE {
385 virtual void getFloatv(GLenum pname, GLfloat* value) OVERRIDE {
388 virtual void getFramebufferAttachmentParameteriv(GLenum target,
391 GLint* value) OVERRIDE {
394 virtual void getIntegerv(GLenum pname, GLint* value) OVERRIDE {
395 if (pname == GL_MAX_TEXTURE_SIZE) {
396 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
403 // We allow querying the shader compilation and program link status in debug
404 // mode, but not release.
405 virtual void getProgramiv(GLuint program,
407 GLint* value) OVERRIDE {
415 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
423 virtual void getRenderbufferParameteriv(GLenum target,
425 GLint* value) OVERRIDE {
429 virtual void getShaderPrecisionFormat(GLenum shadertype,
430 GLenum precisiontype,
432 GLint* precision) OVERRIDE {
435 virtual void getTexParameterfv(GLenum target,
437 GLfloat* value) OVERRIDE {
440 virtual void getTexParameteriv(GLenum target,
442 GLint* value) OVERRIDE {
445 virtual void getUniformfv(GLuint program,
447 GLfloat* value) OVERRIDE {
450 virtual void getUniformiv(GLuint program,
452 GLint* value) OVERRIDE {
455 virtual GLint getUniformLocation(GLuint program,
456 const GLchar* name) OVERRIDE {
460 virtual void getVertexAttribfv(GLuint index,
462 GLfloat* value) OVERRIDE {
465 virtual void getVertexAttribiv(GLuint index,
467 GLint* value) OVERRIDE {
470 virtual GLsizeiptr getVertexAttribOffset(GLuint index,
471 GLenum pname) OVERRIDE {
476 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
477 FakeOutputSurfaceClient output_surface_client;
478 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
479 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
480 CHECK(output_surface->BindToClient(&output_surface_client));
482 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
483 new TestSharedBitmapManager());
484 scoped_ptr<ResourceProvider> resource_provider(
485 ResourceProvider::Create(output_surface.get(),
486 shared_bitmap_manager.get(),
493 LayerTreeSettings settings;
494 FakeRendererClient renderer_client;
495 FakeRendererGL renderer(&renderer_client,
497 output_surface.get(),
498 resource_provider.get());
501 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
503 LoseContextOnFirstGetContext() {}
505 virtual void getProgramiv(GLuint program,
507 GLint* value) OVERRIDE {
508 context_lost_ = true;
512 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
513 context_lost_ = true;
518 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
519 FakeOutputSurfaceClient output_surface_client;
520 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
521 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
522 CHECK(output_surface->BindToClient(&output_surface_client));
524 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
525 new TestSharedBitmapManager());
526 scoped_ptr<ResourceProvider> resource_provider(
527 ResourceProvider::Create(output_surface.get(),
528 shared_bitmap_manager.get(),
535 LayerTreeSettings settings;
536 FakeRendererClient renderer_client;
537 FakeRendererGL renderer(&renderer_client,
539 output_surface.get(),
540 resource_provider.get());
543 class ClearCountingContext : public TestWebGraphicsContext3D {
545 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
547 MOCK_METHOD3(discardFramebufferEXT,
549 GLsizei numAttachments,
550 const GLenum* attachments));
551 MOCK_METHOD1(clear, void(GLbitfield mask));
554 TEST_F(GLRendererTest, OpaqueBackground) {
555 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
556 ClearCountingContext* context = context_owned.get();
558 FakeOutputSurfaceClient output_surface_client;
559 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
560 context_owned.PassAs<TestWebGraphicsContext3D>()));
561 CHECK(output_surface->BindToClient(&output_surface_client));
563 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
564 new TestSharedBitmapManager());
565 scoped_ptr<ResourceProvider> resource_provider(
566 ResourceProvider::Create(output_surface.get(),
567 shared_bitmap_manager.get(),
574 LayerTreeSettings settings;
575 FakeRendererClient renderer_client;
576 FakeRendererGL renderer(&renderer_client,
578 output_surface.get(),
579 resource_provider.get());
581 gfx::Rect viewport_rect(1, 1);
582 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
586 root_pass->has_transparent_background = false;
588 // On DEBUG builds, render passes with opaque background clear to blue to
589 // easily see regions that were not drawn on the screen.
590 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
591 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
594 EXPECT_CALL(*context, clear(_)).Times(0);
596 EXPECT_CALL(*context, clear(_)).Times(1);
598 renderer.DrawFrame(&render_passes_in_draw_order_,
603 Mock::VerifyAndClearExpectations(context);
606 TEST_F(GLRendererTest, TransparentBackground) {
607 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
608 ClearCountingContext* context = context_owned.get();
610 FakeOutputSurfaceClient output_surface_client;
611 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
612 context_owned.PassAs<TestWebGraphicsContext3D>()));
613 CHECK(output_surface->BindToClient(&output_surface_client));
615 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
616 new TestSharedBitmapManager());
617 scoped_ptr<ResourceProvider> resource_provider(
618 ResourceProvider::Create(output_surface.get(),
619 shared_bitmap_manager.get(),
626 LayerTreeSettings settings;
627 FakeRendererClient renderer_client;
628 FakeRendererGL renderer(&renderer_client,
630 output_surface.get(),
631 resource_provider.get());
633 gfx::Rect viewport_rect(1, 1);
634 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
638 root_pass->has_transparent_background = true;
640 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
641 EXPECT_CALL(*context, clear(_)).Times(1);
642 renderer.DrawFrame(&render_passes_in_draw_order_,
648 Mock::VerifyAndClearExpectations(context);
651 TEST_F(GLRendererTest, OffscreenOutputSurface) {
652 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
653 ClearCountingContext* context = context_owned.get();
655 FakeOutputSurfaceClient output_surface_client;
656 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateOffscreen(
657 context_owned.PassAs<TestWebGraphicsContext3D>()));
658 CHECK(output_surface->BindToClient(&output_surface_client));
660 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
661 new TestSharedBitmapManager());
662 scoped_ptr<ResourceProvider> resource_provider(
663 ResourceProvider::Create(output_surface.get(),
664 shared_bitmap_manager.get(),
671 LayerTreeSettings settings;
672 FakeRendererClient renderer_client;
673 FakeRendererGL renderer(&renderer_client,
675 output_surface.get(),
676 resource_provider.get());
678 gfx::Rect viewport_rect(1, 1);
679 AddRenderPass(&render_passes_in_draw_order_,
684 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
685 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
687 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
688 renderer.DrawFrame(&render_passes_in_draw_order_,
693 Mock::VerifyAndClearExpectations(context);
696 class VisibilityChangeIsLastCallTrackingContext
697 : public TestWebGraphicsContext3D {
699 VisibilityChangeIsLastCallTrackingContext()
700 : last_call_was_set_visibility_(false) {}
702 // TestWebGraphicsContext3D methods.
703 virtual void flush() OVERRIDE { last_call_was_set_visibility_ = false; }
704 virtual void deleteTexture(GLuint) OVERRIDE {
705 last_call_was_set_visibility_ = false;
707 virtual void deleteFramebuffer(GLuint) OVERRIDE {
708 last_call_was_set_visibility_ = false;
710 virtual void deleteQueryEXT(GLuint) OVERRIDE {
711 last_call_was_set_visibility_ = false;
713 virtual void deleteRenderbuffer(GLuint) OVERRIDE {
714 last_call_was_set_visibility_ = false;
717 // Methods added for test.
718 void set_last_call_was_visibility(bool visible) {
719 DCHECK(last_call_was_set_visibility_ == false);
720 last_call_was_set_visibility_ = true;
722 bool last_call_was_set_visibility() const {
723 return last_call_was_set_visibility_;
727 bool last_call_was_set_visibility_;
730 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
731 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
732 new VisibilityChangeIsLastCallTrackingContext);
733 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
735 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(
736 context_owned.PassAs<TestWebGraphicsContext3D>());
738 provider->support()->SetSurfaceVisibleCallback(base::Bind(
739 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
740 base::Unretained(context)));
742 FakeOutputSurfaceClient output_surface_client;
743 scoped_ptr<OutputSurface> output_surface(
744 FakeOutputSurface::Create3d(provider));
745 CHECK(output_surface->BindToClient(&output_surface_client));
747 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
748 new TestSharedBitmapManager());
749 scoped_ptr<ResourceProvider> resource_provider(
750 ResourceProvider::Create(output_surface.get(),
751 shared_bitmap_manager.get(),
758 LayerTreeSettings settings;
759 FakeRendererClient renderer_client;
760 FakeRendererGL renderer(&renderer_client,
762 output_surface.get(),
763 resource_provider.get());
765 gfx::Rect viewport_rect(1, 1);
766 AddRenderPass(&render_passes_in_draw_order_,
771 // Ensure that the call to SetSurfaceVisible is the last call issue to the
772 // GPU process, after glFlush is called, and after the RendererClient's
773 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
774 // RenderClient and the Context by giving them both a pointer to a variable on
776 renderer.SetVisible(true);
777 renderer.DrawFrame(&render_passes_in_draw_order_,
782 renderer.SetVisible(false);
783 EXPECT_TRUE(context->last_call_was_set_visibility());
786 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
788 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
789 test_capabilities_.gpu.egl_image_external = true;
792 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
793 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
794 MOCK_METHOD4(drawElements,
795 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
797 virtual void activeTexture(GLenum texture) {
798 EXPECT_NE(texture, active_texture_);
799 active_texture_ = texture;
802 GLenum active_texture() const { return active_texture_; }
805 GLenum active_texture_;
808 TEST_F(GLRendererTest, ActiveTextureState) {
809 scoped_ptr<TextureStateTrackingContext> context_owned(
810 new TextureStateTrackingContext);
811 TextureStateTrackingContext* context = context_owned.get();
813 FakeOutputSurfaceClient output_surface_client;
814 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
815 context_owned.PassAs<TestWebGraphicsContext3D>()));
816 CHECK(output_surface->BindToClient(&output_surface_client));
818 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
819 new TestSharedBitmapManager());
820 scoped_ptr<ResourceProvider> resource_provider(
821 ResourceProvider::Create(output_surface.get(),
822 shared_bitmap_manager.get(),
829 LayerTreeSettings settings;
830 FakeRendererClient renderer_client;
831 FakeRendererGL renderer(&renderer_client,
833 output_surface.get(),
834 resource_provider.get());
836 // During initialization we are allowed to set any texture parameters.
837 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
839 RenderPassId id(1, 1);
840 TestRenderPass* root_pass = AddRenderPass(
841 &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
842 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
845 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
847 // Set up expected texture filter state transitions that match the quads
848 // created in AppendOneOfEveryQuadType().
849 Mock::VerifyAndClearExpectations(context);
853 // The sync points for all quads are waited on first. This sync point is
854 // for a texture quad drawn later in the frame.
855 EXPECT_CALL(*context,
856 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
859 // yuv_quad is drawn with the default linear filter.
860 EXPECT_CALL(*context, drawElements(_, _, _, _));
862 // tile_quad is drawn with GL_NEAREST because it is not transformed or
866 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
869 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
870 EXPECT_CALL(*context, drawElements(_, _, _, _));
872 // transformed_tile_quad uses GL_LINEAR.
873 EXPECT_CALL(*context, drawElements(_, _, _, _));
875 // scaled_tile_quad also uses GL_LINEAR.
876 EXPECT_CALL(*context, drawElements(_, _, _, _));
878 // The remaining quads also use GL_LINEAR because nearest neighbor
879 // filtering is currently only used with tile quads.
880 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(7);
883 gfx::Rect viewport_rect(100, 100);
884 renderer.DrawFrame(&render_passes_in_draw_order_,
889 Mock::VerifyAndClearExpectations(context);
892 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
894 MOCK_METHOD1(clear, void(GLbitfield mask));
895 MOCK_METHOD4(drawElements,
896 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
899 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
900 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
901 new NoClearRootRenderPassMockContext);
902 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
904 FakeOutputSurfaceClient output_surface_client;
905 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
906 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
907 CHECK(output_surface->BindToClient(&output_surface_client));
909 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
910 new TestSharedBitmapManager());
911 scoped_ptr<ResourceProvider> resource_provider(
912 ResourceProvider::Create(output_surface.get(),
913 shared_bitmap_manager.get(),
920 LayerTreeSettings settings;
921 settings.should_clear_root_render_pass = false;
923 FakeRendererClient renderer_client;
924 FakeRendererGL renderer(&renderer_client,
926 output_surface.get(),
927 resource_provider.get());
929 gfx::Rect viewport_rect(10, 10);
931 RenderPassId root_pass_id(1, 0);
932 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
936 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
938 RenderPassId child_pass_id(2, 0);
939 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
943 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
945 AddRenderPassQuad(root_pass, child_pass);
948 GLint clear_bits = GL_COLOR_BUFFER_BIT;
950 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
953 // First render pass is not the root one, clearing should happen.
954 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
956 Expectation first_render_pass =
957 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
959 // The second render pass is the root one, clearing should be prevented.
960 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
963 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
966 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
967 renderer.DrawFrame(&render_passes_in_draw_order_,
973 // In multiple render passes all but the root pass should clear the
975 Mock::VerifyAndClearExpectations(&mock_context);
978 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
980 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
982 virtual void clear(GLbitfield) OVERRIDE { EXPECT_FALSE(scissor_enabled_); }
984 virtual void enable(GLenum cap) OVERRIDE {
985 if (cap == GL_SCISSOR_TEST)
986 scissor_enabled_ = true;
989 virtual void disable(GLenum cap) OVERRIDE {
990 if (cap == GL_SCISSOR_TEST)
991 scissor_enabled_ = false;
995 bool scissor_enabled_;
998 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
999 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
1000 new ScissorTestOnClearCheckingContext);
1002 FakeOutputSurfaceClient output_surface_client;
1003 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
1004 context_owned.PassAs<TestWebGraphicsContext3D>()));
1005 CHECK(output_surface->BindToClient(&output_surface_client));
1007 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1008 new TestSharedBitmapManager());
1009 scoped_ptr<ResourceProvider> resource_provider(
1010 ResourceProvider::Create(output_surface.get(),
1011 shared_bitmap_manager.get(),
1018 LayerTreeSettings settings;
1019 FakeRendererClient renderer_client;
1020 FakeRendererGL renderer(&renderer_client,
1022 output_surface.get(),
1023 resource_provider.get());
1024 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1026 gfx::Rect viewport_rect(1, 1);
1028 gfx::Rect grand_child_rect(25, 25);
1029 RenderPassId grand_child_pass_id(3, 0);
1030 TestRenderPass* grand_child_pass =
1031 AddRenderPass(&render_passes_in_draw_order_,
1032 grand_child_pass_id,
1035 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
1037 gfx::Rect child_rect(50, 50);
1038 RenderPassId child_pass_id(2, 0);
1039 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
1043 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1045 RenderPassId root_pass_id(1, 0);
1046 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1050 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1052 AddRenderPassQuad(root_pass, child_pass);
1053 AddRenderPassQuad(child_pass, grand_child_pass);
1055 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1056 renderer.DrawFrame(&render_passes_in_draw_order_,
1063 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1065 DiscardCheckingContext() : discarded_(0) {
1066 set_have_post_sub_buffer(true);
1067 set_have_discard_framebuffer(true);
1070 virtual void discardFramebufferEXT(GLenum target,
1071 GLsizei numAttachments,
1072 const GLenum* attachments) OVERRIDE {
1076 int discarded() const { return discarded_; }
1077 void reset() { discarded_ = 0; }
1083 class NonReshapableOutputSurface : public FakeOutputSurface {
1085 explicit NonReshapableOutputSurface(
1086 scoped_ptr<TestWebGraphicsContext3D> context3d)
1087 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1089 surface_size_ = gfx::Size(500, 500);
1091 virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {}
1092 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1095 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1096 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1097 DiscardCheckingContext* context = context_owned.get();
1099 FakeOutputSurfaceClient output_surface_client;
1100 scoped_ptr<NonReshapableOutputSurface> output_surface(
1101 new NonReshapableOutputSurface(
1102 context_owned.PassAs<TestWebGraphicsContext3D>()));
1103 CHECK(output_surface->BindToClient(&output_surface_client));
1104 output_surface->set_fixed_size(gfx::Size(100, 100));
1106 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1107 new TestSharedBitmapManager());
1108 scoped_ptr<ResourceProvider> resource_provider(
1109 ResourceProvider::Create(output_surface.get(),
1110 shared_bitmap_manager.get(),
1117 LayerTreeSettings settings;
1118 settings.partial_swap_enabled = true;
1119 FakeRendererClient renderer_client;
1120 FakeRendererGL renderer(&renderer_client,
1122 output_surface.get(),
1123 resource_provider.get());
1124 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1126 gfx::Rect viewport_rect(100, 100);
1127 gfx::Rect clip_rect(100, 100);
1130 // Partial frame, should not discard.
1131 RenderPassId root_pass_id(1, 0);
1132 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1136 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1137 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1139 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1140 renderer.DrawFrame(&render_passes_in_draw_order_,
1145 EXPECT_EQ(0, context->discarded());
1149 // Full frame, should discard.
1150 RenderPassId root_pass_id(1, 0);
1151 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1155 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1156 root_pass->damage_rect = root_pass->output_rect;
1158 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1159 renderer.DrawFrame(&render_passes_in_draw_order_,
1164 EXPECT_EQ(1, context->discarded());
1168 // Full frame, external scissor is set, should not discard.
1169 output_surface->set_has_external_stencil_test(true);
1170 RenderPassId root_pass_id(1, 0);
1171 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1175 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1176 root_pass->damage_rect = root_pass->output_rect;
1177 root_pass->has_transparent_background = false;
1179 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1180 renderer.DrawFrame(&render_passes_in_draw_order_,
1185 EXPECT_EQ(0, context->discarded());
1187 output_surface->set_has_external_stencil_test(false);
1190 // Full frame, clipped, should not discard.
1191 clip_rect = gfx::Rect(10, 10, 10, 10);
1192 RenderPassId root_pass_id(1, 0);
1193 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1197 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1198 root_pass->damage_rect = root_pass->output_rect;
1200 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1201 renderer.DrawFrame(&render_passes_in_draw_order_,
1206 EXPECT_EQ(0, context->discarded());
1210 // Full frame, doesn't cover the surface, should not discard.
1211 viewport_rect = gfx::Rect(10, 10, 10, 10);
1212 RenderPassId root_pass_id(1, 0);
1213 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1217 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1218 root_pass->damage_rect = root_pass->output_rect;
1220 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1221 renderer.DrawFrame(&render_passes_in_draw_order_,
1226 EXPECT_EQ(0, context->discarded());
1230 // Full frame, doesn't cover the surface (no offset), should not discard.
1231 clip_rect = gfx::Rect(100, 100);
1232 viewport_rect = gfx::Rect(50, 50);
1233 RenderPassId root_pass_id(1, 0);
1234 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1238 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1239 root_pass->damage_rect = root_pass->output_rect;
1241 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1242 renderer.DrawFrame(&render_passes_in_draw_order_,
1247 EXPECT_EQ(0, context->discarded());
1252 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1254 FlippedScissorAndViewportContext()
1255 : did_call_viewport_(false), did_call_scissor_(false) {}
1256 virtual ~FlippedScissorAndViewportContext() {
1257 EXPECT_TRUE(did_call_viewport_);
1258 EXPECT_TRUE(did_call_scissor_);
1261 virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1265 EXPECT_EQ(100, width);
1266 EXPECT_EQ(100, height);
1267 did_call_viewport_ = true;
1270 virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1274 EXPECT_EQ(20, width);
1275 EXPECT_EQ(20, height);
1276 did_call_scissor_ = true;
1280 bool did_call_viewport_;
1281 bool did_call_scissor_;
1284 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1285 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1286 // and maintains a fixed size. This test verifies that glViewport and
1287 // glScissor's Y coordinate is flipped correctly in this environment, and that
1288 // the glViewport can be at a nonzero origin within the surface.
1289 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1290 new FlippedScissorAndViewportContext);
1292 FakeOutputSurfaceClient output_surface_client;
1293 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface(
1294 context_owned.PassAs<TestWebGraphicsContext3D>()));
1295 CHECK(output_surface->BindToClient(&output_surface_client));
1297 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1298 new TestSharedBitmapManager());
1299 scoped_ptr<ResourceProvider> resource_provider(
1300 ResourceProvider::Create(output_surface.get(),
1301 shared_bitmap_manager.get(),
1308 LayerTreeSettings settings;
1309 FakeRendererClient renderer_client;
1310 FakeRendererGL renderer(&renderer_client,
1312 output_surface.get(),
1313 resource_provider.get());
1314 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1316 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1317 gfx::Rect viewport_rect(device_viewport_rect.size());
1318 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1320 RenderPassId root_pass_id(1, 0);
1321 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1325 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1327 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1328 renderer.DrawFrame(&render_passes_in_draw_order_,
1330 device_viewport_rect,
1331 device_viewport_rect,
1335 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1336 gfx::Rect viewport_rect(1, 1);
1338 gfx::Rect child_rect(50, 50);
1339 RenderPassId child_pass_id(2, 0);
1340 TestRenderPass* child_pass;
1342 RenderPassId root_pass_id(1, 0);
1343 TestRenderPass* root_pass;
1345 ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
1348 ResourceProvider::TextureHintImmutable,
1349 resource_provider_->best_texture_format());
1350 resource_provider_->AllocateForTesting(mask);
1352 SkScalar matrix[20];
1353 float amount = 0.5f;
1354 matrix[0] = 0.213f + 0.787f * amount;
1355 matrix[1] = 0.715f - 0.715f * amount;
1356 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1357 matrix[3] = matrix[4] = 0;
1358 matrix[5] = 0.213f - 0.213f * amount;
1359 matrix[6] = 0.715f + 0.285f * amount;
1360 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1361 matrix[8] = matrix[9] = 0;
1362 matrix[10] = 0.213f - 0.213f * amount;
1363 matrix[11] = 0.715f - 0.715f * amount;
1364 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1365 matrix[13] = matrix[14] = 0;
1366 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1368 skia::RefPtr<SkColorFilter> color_filter(
1369 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1370 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1371 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1372 FilterOperations filters;
1373 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1375 gfx::Transform transform_causing_aa;
1376 transform_causing_aa.Rotate(20.0);
1378 // RenderPassProgram
1379 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1384 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1390 root_pass, child_pass, 0, FilterOperations(), gfx::Transform());
1392 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1393 renderer_->DrawFrame(&render_passes_in_draw_order_,
1398 TestRenderPassProgram(TexCoordPrecisionMedium);
1400 // RenderPassColorMatrixProgram
1401 render_passes_in_draw_order_.clear();
1403 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1406 transform_causing_aa);
1408 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1413 AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform());
1415 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1416 renderer_->DrawFrame(&render_passes_in_draw_order_,
1421 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium);
1423 // RenderPassMaskProgram
1424 render_passes_in_draw_order_.clear();
1426 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1431 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1437 root_pass, child_pass, mask, FilterOperations(), gfx::Transform());
1439 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1440 renderer_->DrawFrame(&render_passes_in_draw_order_,
1445 TestRenderPassMaskProgram(TexCoordPrecisionMedium);
1447 // RenderPassMaskColorMatrixProgram
1448 render_passes_in_draw_order_.clear();
1450 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1455 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1460 AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform());
1462 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1463 renderer_->DrawFrame(&render_passes_in_draw_order_,
1468 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium);
1470 // RenderPassProgramAA
1471 render_passes_in_draw_order_.clear();
1473 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1476 transform_causing_aa);
1478 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1484 root_pass, child_pass, 0, FilterOperations(), transform_causing_aa);
1486 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1487 renderer_->DrawFrame(&render_passes_in_draw_order_,
1492 TestRenderPassProgramAA(TexCoordPrecisionMedium);
1494 // RenderPassColorMatrixProgramAA
1495 render_passes_in_draw_order_.clear();
1497 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1500 transform_causing_aa);
1502 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1507 AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa);
1509 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1510 renderer_->DrawFrame(&render_passes_in_draw_order_,
1515 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium);
1517 // RenderPassMaskProgramAA
1518 render_passes_in_draw_order_.clear();
1520 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1523 transform_causing_aa);
1525 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1531 root_pass, child_pass, mask, FilterOperations(), transform_causing_aa);
1533 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1534 renderer_->DrawFrame(&render_passes_in_draw_order_,
1539 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium);
1541 // RenderPassMaskColorMatrixProgramAA
1542 render_passes_in_draw_order_.clear();
1544 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1547 transform_causing_aa);
1549 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1552 transform_causing_aa);
1554 AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa);
1556 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1557 renderer_->DrawFrame(&render_passes_in_draw_order_,
1562 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium);
1565 // At this time, the AA code path cannot be taken if the surface's rect would
1566 // project incorrectly by the given transform, because of w<0 clipping.
1567 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1568 gfx::Rect child_rect(50, 50);
1569 RenderPassId child_pass_id(2, 0);
1570 TestRenderPass* child_pass;
1572 gfx::Rect viewport_rect(1, 1);
1573 RenderPassId root_pass_id(1, 0);
1574 TestRenderPass* root_pass;
1576 gfx::Transform transform_preventing_aa;
1577 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1578 transform_preventing_aa.RotateAboutYAxis(-20.0);
1579 transform_preventing_aa.Scale(30.0, 1.0);
1581 // Verify that the test transform and test rect actually do cause the clipped
1582 // flag to trigger. Otherwise we are not testing the intended scenario.
1583 bool clipped = false;
1584 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1585 ASSERT_TRUE(clipped);
1587 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1590 transform_preventing_aa);
1592 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1598 root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa);
1600 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1601 renderer_->DrawFrame(&render_passes_in_draw_order_,
1607 // If use_aa incorrectly ignores clipping, it will use the
1608 // RenderPassProgramAA shader instead of the RenderPassProgram.
1609 TestRenderPassProgram(TexCoordPrecisionMedium);
1612 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1613 gfx::Rect viewport_rect(1, 1);
1614 RenderPassId root_pass_id(1, 0);
1615 TestRenderPass* root_pass;
1617 gfx::Transform pixel_aligned_transform_causing_aa;
1618 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1619 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1621 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1625 AddTransformedQuad(root_pass,
1628 pixel_aligned_transform_causing_aa);
1630 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1631 renderer_->DrawFrame(&render_passes_in_draw_order_,
1637 TestSolidColorProgramAA();
1640 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1642 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1644 // Specifically override methods even if they are unused (used in conjunction
1645 // with StrictMock). We need to make sure that GLRenderer does not issue
1646 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1647 // through the OutputSurface abstraction.
1648 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1649 MOCK_METHOD3(reshapeWithScaleFactor,
1650 void(int width, int height, float scale_factor));
1651 MOCK_METHOD4(drawElements,
1652 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1655 class MockOutputSurface : public OutputSurface {
1659 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1660 new StrictMock<OutputSurfaceMockContext>))) {
1661 surface_size_ = gfx::Size(100, 100);
1663 virtual ~MockOutputSurface() {}
1665 MOCK_METHOD0(EnsureBackbuffer, void());
1666 MOCK_METHOD0(DiscardBackbuffer, void());
1667 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1668 MOCK_METHOD0(BindFramebuffer, void());
1669 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1672 class MockOutputSurfaceTest : public GLRendererTest {
1674 virtual void SetUp() {
1675 FakeOutputSurfaceClient output_surface_client_;
1676 CHECK(output_surface_.BindToClient(&output_surface_client_));
1678 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1679 resource_provider_ = ResourceProvider::Create(&output_surface_,
1680 shared_bitmap_manager_.get(),
1687 renderer_.reset(new FakeRendererGL(&renderer_client_,
1690 resource_provider_.get()));
1693 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1695 void DrawFrame(float device_scale_factor,
1696 const gfx::Rect& device_viewport_rect) {
1697 RenderPassId render_pass_id(1, 0);
1698 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1700 device_viewport_rect,
1702 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1704 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1706 EXPECT_CALL(output_surface_,
1707 Reshape(device_viewport_rect.size(), device_scale_factor))
1710 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1712 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1714 renderer_->DecideRenderPassAllocationsForFrame(
1715 render_passes_in_draw_order_);
1716 renderer_->DrawFrame(&render_passes_in_draw_order_,
1717 device_scale_factor,
1718 device_viewport_rect,
1719 device_viewport_rect,
1723 OutputSurfaceMockContext* Context() {
1724 return static_cast<OutputSurfaceMockContext*>(
1725 static_cast<TestContextProvider*>(output_surface_.context_provider())
1729 LayerTreeSettings settings_;
1730 FakeOutputSurfaceClient output_surface_client_;
1731 StrictMock<MockOutputSurface> output_surface_;
1732 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1733 scoped_ptr<ResourceProvider> resource_provider_;
1734 FakeRendererClient renderer_client_;
1735 scoped_ptr<FakeRendererGL> renderer_;
1738 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1739 gfx::Rect device_viewport_rect(1, 1);
1740 DrawFrame(1.f, device_viewport_rect);
1742 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1743 renderer_->SwapBuffers(CompositorFrameMetadata());
1746 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1747 gfx::Rect device_viewport_rect(1, 1);
1749 DrawFrame(1.f, device_viewport_rect);
1750 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1751 renderer_->SwapBuffers(CompositorFrameMetadata());
1753 device_viewport_rect = gfx::Rect(2, 2);
1755 DrawFrame(2.f, device_viewport_rect);
1756 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1757 renderer_->SwapBuffers(CompositorFrameMetadata());
1759 DrawFrame(2.f, device_viewport_rect);
1760 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1761 renderer_->SwapBuffers(CompositorFrameMetadata());
1763 device_viewport_rect = gfx::Rect(1, 1);
1765 DrawFrame(1.f, device_viewport_rect);
1766 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1767 renderer_->SwapBuffers(CompositorFrameMetadata());
1770 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1772 static void SyncPointCallback(int* callback_count) {
1773 ++(*callback_count);
1774 base::MessageLoop::current()->QuitWhenIdle();
1777 static void OtherCallback(int* callback_count) {
1778 ++(*callback_count);
1779 base::MessageLoop::current()->QuitWhenIdle();
1783 #if !defined(OS_ANDROID)
1784 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1785 int sync_point_callback_count = 0;
1786 int other_callback_count = 0;
1787 gpu::gles2::GLES2Interface* gl =
1788 output_surface_->context_provider()->ContextGL();
1789 gpu::ContextSupport* context_support =
1790 output_surface_->context_provider()->ContextSupport();
1792 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1794 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1795 GL_INNOCENT_CONTEXT_RESET_ARB);
1797 context_support->SignalSyncPoint(
1798 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1799 EXPECT_EQ(0, sync_point_callback_count);
1800 EXPECT_EQ(0, other_callback_count);
1802 // Make the sync point happen.
1804 // Post a task after the sync point.
1805 base::MessageLoop::current()->PostTask(
1806 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1808 base::MessageLoop::current()->Run();
1810 // The sync point shouldn't have happened since the context was lost.
1811 EXPECT_EQ(0, sync_point_callback_count);
1812 EXPECT_EQ(1, other_callback_count);
1815 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1816 int sync_point_callback_count = 0;
1817 int other_callback_count = 0;
1819 gpu::gles2::GLES2Interface* gl =
1820 output_surface_->context_provider()->ContextGL();
1821 gpu::ContextSupport* context_support =
1822 output_surface_->context_provider()->ContextSupport();
1824 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1826 context_support->SignalSyncPoint(
1827 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1828 EXPECT_EQ(0, sync_point_callback_count);
1829 EXPECT_EQ(0, other_callback_count);
1831 // Make the sync point happen.
1833 // Post a task after the sync point.
1834 base::MessageLoop::current()->PostTask(
1835 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1837 base::MessageLoop::current()->Run();
1839 // The sync point should have happened.
1840 EXPECT_EQ(1, sync_point_callback_count);
1841 EXPECT_EQ(1, other_callback_count);
1843 #endif // OS_ANDROID