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, ExternalStencil) {
337 gfx::Rect viewport_rect(1, 1);
338 EXPECT_FALSE(renderer_->stencil_enabled());
340 output_surface_->set_has_external_stencil_test(true);
342 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
343 RenderPass::Id(1, 0),
346 root_pass->has_transparent_background = false;
348 renderer_->DrawFrame(&render_passes_in_draw_order_,
353 EXPECT_TRUE(renderer_->stencil_enabled());
356 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
358 ForbidSynchronousCallContext() {}
360 virtual void getAttachedShaders(GLuint program,
363 GLuint* shaders) OVERRIDE {
366 virtual GLint getAttribLocation(GLuint program, const GLchar* name) OVERRIDE {
370 virtual void getBooleanv(GLenum pname, GLboolean* value) OVERRIDE {
373 virtual void getBufferParameteriv(GLenum target,
375 GLint* value) OVERRIDE {
378 virtual GLenum getError() OVERRIDE {
382 virtual void getFloatv(GLenum pname, GLfloat* value) OVERRIDE {
385 virtual void getFramebufferAttachmentParameteriv(GLenum target,
388 GLint* value) OVERRIDE {
391 virtual void getIntegerv(GLenum pname, GLint* value) OVERRIDE {
392 if (pname == GL_MAX_TEXTURE_SIZE) {
393 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
400 // We allow querying the shader compilation and program link status in debug
401 // mode, but not release.
402 virtual void getProgramiv(GLuint program,
404 GLint* value) OVERRIDE {
412 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
420 virtual void getRenderbufferParameteriv(GLenum target,
422 GLint* value) OVERRIDE {
426 virtual void getShaderPrecisionFormat(GLenum shadertype,
427 GLenum precisiontype,
429 GLint* precision) OVERRIDE {
432 virtual void getTexParameterfv(GLenum target,
434 GLfloat* value) OVERRIDE {
437 virtual void getTexParameteriv(GLenum target,
439 GLint* value) OVERRIDE {
442 virtual void getUniformfv(GLuint program,
444 GLfloat* value) OVERRIDE {
447 virtual void getUniformiv(GLuint program,
449 GLint* value) OVERRIDE {
452 virtual GLint getUniformLocation(GLuint program,
453 const GLchar* name) OVERRIDE {
457 virtual void getVertexAttribfv(GLuint index,
459 GLfloat* value) OVERRIDE {
462 virtual void getVertexAttribiv(GLuint index,
464 GLint* value) OVERRIDE {
467 virtual GLsizeiptr getVertexAttribOffset(GLuint index,
468 GLenum pname) OVERRIDE {
473 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
474 FakeOutputSurfaceClient output_surface_client;
475 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
476 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
477 CHECK(output_surface->BindToClient(&output_surface_client));
479 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
480 new TestSharedBitmapManager());
481 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
482 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
484 LayerTreeSettings settings;
485 FakeRendererClient renderer_client;
486 FakeRendererGL renderer(&renderer_client,
488 output_surface.get(),
489 resource_provider.get());
492 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
494 LoseContextOnFirstGetContext() {}
496 virtual void getProgramiv(GLuint program,
498 GLint* value) OVERRIDE {
499 context_lost_ = true;
503 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
504 context_lost_ = true;
509 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
510 FakeOutputSurfaceClient output_surface_client;
511 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
512 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
513 CHECK(output_surface->BindToClient(&output_surface_client));
515 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
516 new TestSharedBitmapManager());
517 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
518 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
520 LayerTreeSettings settings;
521 FakeRendererClient renderer_client;
522 FakeRendererGL renderer(&renderer_client,
524 output_surface.get(),
525 resource_provider.get());
528 class ClearCountingContext : public TestWebGraphicsContext3D {
530 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
532 MOCK_METHOD3(discardFramebufferEXT,
534 GLsizei numAttachments,
535 const GLenum* attachments));
536 MOCK_METHOD1(clear, void(GLbitfield mask));
539 TEST_F(GLRendererTest, OpaqueBackground) {
540 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
541 ClearCountingContext* context = context_owned.get();
543 FakeOutputSurfaceClient output_surface_client;
544 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
545 context_owned.PassAs<TestWebGraphicsContext3D>()));
546 CHECK(output_surface->BindToClient(&output_surface_client));
548 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
549 new TestSharedBitmapManager());
550 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
551 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
553 LayerTreeSettings settings;
554 FakeRendererClient renderer_client;
555 FakeRendererGL renderer(&renderer_client,
557 output_surface.get(),
558 resource_provider.get());
560 gfx::Rect viewport_rect(1, 1);
561 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
562 RenderPass::Id(1, 0),
565 root_pass->has_transparent_background = false;
567 // On DEBUG builds, render passes with opaque background clear to blue to
568 // easily see regions that were not drawn on the screen.
569 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
570 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
573 EXPECT_CALL(*context, clear(_)).Times(0);
575 EXPECT_CALL(*context, clear(_)).Times(1);
577 renderer.DrawFrame(&render_passes_in_draw_order_,
582 Mock::VerifyAndClearExpectations(context);
585 TEST_F(GLRendererTest, TransparentBackground) {
586 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
587 ClearCountingContext* context = context_owned.get();
589 FakeOutputSurfaceClient output_surface_client;
590 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
591 context_owned.PassAs<TestWebGraphicsContext3D>()));
592 CHECK(output_surface->BindToClient(&output_surface_client));
594 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
595 new TestSharedBitmapManager());
596 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
597 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
599 LayerTreeSettings settings;
600 FakeRendererClient renderer_client;
601 FakeRendererGL renderer(&renderer_client,
603 output_surface.get(),
604 resource_provider.get());
606 gfx::Rect viewport_rect(1, 1);
607 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
608 RenderPass::Id(1, 0),
611 root_pass->has_transparent_background = true;
613 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
614 EXPECT_CALL(*context, clear(_)).Times(1);
615 renderer.DrawFrame(&render_passes_in_draw_order_,
621 Mock::VerifyAndClearExpectations(context);
624 TEST_F(GLRendererTest, OffscreenOutputSurface) {
625 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
626 ClearCountingContext* context = context_owned.get();
628 FakeOutputSurfaceClient output_surface_client;
629 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateOffscreen(
630 context_owned.PassAs<TestWebGraphicsContext3D>()));
631 CHECK(output_surface->BindToClient(&output_surface_client));
633 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
634 new TestSharedBitmapManager());
635 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
636 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
638 LayerTreeSettings settings;
639 FakeRendererClient renderer_client;
640 FakeRendererGL renderer(&renderer_client,
642 output_surface.get(),
643 resource_provider.get());
645 gfx::Rect viewport_rect(1, 1);
646 AddRenderPass(&render_passes_in_draw_order_,
647 RenderPass::Id(1, 0),
651 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
652 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
654 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
655 renderer.DrawFrame(&render_passes_in_draw_order_,
660 Mock::VerifyAndClearExpectations(context);
663 class VisibilityChangeIsLastCallTrackingContext
664 : public TestWebGraphicsContext3D {
666 VisibilityChangeIsLastCallTrackingContext()
667 : last_call_was_set_visibility_(false) {}
669 // TestWebGraphicsContext3D methods.
670 virtual void flush() OVERRIDE { last_call_was_set_visibility_ = false; }
671 virtual void deleteTexture(GLuint) OVERRIDE {
672 last_call_was_set_visibility_ = false;
674 virtual void deleteFramebuffer(GLuint) OVERRIDE {
675 last_call_was_set_visibility_ = false;
677 virtual void deleteQueryEXT(GLuint) OVERRIDE {
678 last_call_was_set_visibility_ = false;
680 virtual void deleteRenderbuffer(GLuint) OVERRIDE {
681 last_call_was_set_visibility_ = false;
684 // Methods added for test.
685 void set_last_call_was_visibility(bool visible) {
686 DCHECK(last_call_was_set_visibility_ == false);
687 last_call_was_set_visibility_ = true;
689 bool last_call_was_set_visibility() const {
690 return last_call_was_set_visibility_;
694 bool last_call_was_set_visibility_;
697 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
698 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
699 new VisibilityChangeIsLastCallTrackingContext);
700 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
702 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(
703 context_owned.PassAs<TestWebGraphicsContext3D>());
705 provider->support()->SetSurfaceVisibleCallback(base::Bind(
706 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
707 base::Unretained(context)));
709 FakeOutputSurfaceClient output_surface_client;
710 scoped_ptr<OutputSurface> output_surface(
711 FakeOutputSurface::Create3d(provider));
712 CHECK(output_surface->BindToClient(&output_surface_client));
714 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
715 new TestSharedBitmapManager());
716 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
717 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
719 LayerTreeSettings settings;
720 FakeRendererClient renderer_client;
721 FakeRendererGL renderer(&renderer_client,
723 output_surface.get(),
724 resource_provider.get());
726 gfx::Rect viewport_rect(1, 1);
727 AddRenderPass(&render_passes_in_draw_order_,
728 RenderPass::Id(1, 0),
732 // Ensure that the call to SetSurfaceVisible is the last call issue to the
733 // GPU process, after glFlush is called, and after the RendererClient's
734 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
735 // RenderClient and the Context by giving them both a pointer to a variable on
737 renderer.SetVisible(true);
738 renderer.DrawFrame(&render_passes_in_draw_order_,
743 renderer.SetVisible(false);
744 EXPECT_TRUE(context->last_call_was_set_visibility());
747 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
749 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
750 test_capabilities_.gpu.egl_image_external = true;
753 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
754 MOCK_METHOD4(drawElements,
755 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
757 virtual void activeTexture(GLenum texture) {
758 EXPECT_NE(texture, active_texture_);
759 active_texture_ = texture;
762 GLenum active_texture() const { return active_texture_; }
765 GLenum active_texture_;
768 TEST_F(GLRendererTest, ActiveTextureState) {
769 scoped_ptr<TextureStateTrackingContext> context_owned(
770 new TextureStateTrackingContext);
771 TextureStateTrackingContext* context = context_owned.get();
773 FakeOutputSurfaceClient output_surface_client;
774 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
775 context_owned.PassAs<TestWebGraphicsContext3D>()));
776 CHECK(output_surface->BindToClient(&output_surface_client));
778 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
779 new TestSharedBitmapManager());
780 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
781 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
783 LayerTreeSettings settings;
784 FakeRendererClient renderer_client;
785 FakeRendererGL renderer(&renderer_client,
787 output_surface.get(),
788 resource_provider.get());
790 // During initialization we are allowed to set any texture parameters.
791 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
793 RenderPass::Id id(1, 1);
794 TestRenderPass* root_pass = AddRenderPass(
795 &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
796 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
797 RenderPass::Id(2, 1));
799 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
801 // Set up expected texture filter state transitions that match the quads
802 // created in AppendOneOfEveryQuadType().
803 Mock::VerifyAndClearExpectations(context);
807 // yuv_quad is drawn with the default linear filter.
808 EXPECT_CALL(*context, drawElements(_, _, _, _));
810 // tile_quad is drawn with GL_NEAREST because it is not transformed or
814 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
817 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
818 EXPECT_CALL(*context, drawElements(_, _, _, _));
820 // transformed_tile_quad uses GL_LINEAR.
821 EXPECT_CALL(*context, drawElements(_, _, _, _));
823 // scaled_tile_quad also uses GL_LINEAR.
824 EXPECT_CALL(*context, drawElements(_, _, _, _));
826 // The remaining quads also use GL_LINEAR because nearest neighbor
827 // filtering is currently only used with tile quads.
828 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6);
831 gfx::Rect viewport_rect(100, 100);
832 renderer.DrawFrame(&render_passes_in_draw_order_,
837 Mock::VerifyAndClearExpectations(context);
840 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
842 MOCK_METHOD1(clear, void(GLbitfield mask));
843 MOCK_METHOD4(drawElements,
844 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
847 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
848 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
849 new NoClearRootRenderPassMockContext);
850 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
852 FakeOutputSurfaceClient output_surface_client;
853 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
854 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
855 CHECK(output_surface->BindToClient(&output_surface_client));
857 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
858 new TestSharedBitmapManager());
859 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
860 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
862 LayerTreeSettings settings;
863 settings.should_clear_root_render_pass = false;
865 FakeRendererClient renderer_client;
866 FakeRendererGL renderer(&renderer_client,
868 output_surface.get(),
869 resource_provider.get());
871 gfx::Rect viewport_rect(10, 10);
873 RenderPass::Id root_pass_id(1, 0);
874 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
878 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
880 RenderPass::Id child_pass_id(2, 0);
881 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
885 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
887 AddRenderPassQuad(root_pass, child_pass);
890 GLint clear_bits = GL_COLOR_BUFFER_BIT;
892 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
895 // First render pass is not the root one, clearing should happen.
896 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
898 Expectation first_render_pass =
899 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
901 // The second render pass is the root one, clearing should be prevented.
902 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
905 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
908 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
909 renderer.DrawFrame(&render_passes_in_draw_order_,
915 // In multiple render passes all but the root pass should clear the
917 Mock::VerifyAndClearExpectations(&mock_context);
920 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
922 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
924 virtual void clear(GLbitfield) OVERRIDE { EXPECT_FALSE(scissor_enabled_); }
926 virtual void enable(GLenum cap) OVERRIDE {
927 if (cap == GL_SCISSOR_TEST)
928 scissor_enabled_ = true;
931 virtual void disable(GLenum cap) OVERRIDE {
932 if (cap == GL_SCISSOR_TEST)
933 scissor_enabled_ = false;
937 bool scissor_enabled_;
940 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
941 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
942 new ScissorTestOnClearCheckingContext);
944 FakeOutputSurfaceClient output_surface_client;
945 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
946 context_owned.PassAs<TestWebGraphicsContext3D>()));
947 CHECK(output_surface->BindToClient(&output_surface_client));
949 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
950 new TestSharedBitmapManager());
951 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
952 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
954 LayerTreeSettings settings;
955 FakeRendererClient renderer_client;
956 FakeRendererGL renderer(&renderer_client,
958 output_surface.get(),
959 resource_provider.get());
960 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
962 gfx::Rect viewport_rect(1, 1);
964 gfx::Rect grand_child_rect(25, 25);
965 RenderPass::Id grand_child_pass_id(3, 0);
966 TestRenderPass* grand_child_pass =
967 AddRenderPass(&render_passes_in_draw_order_,
971 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
973 gfx::Rect child_rect(50, 50);
974 RenderPass::Id child_pass_id(2, 0);
975 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
979 AddQuad(child_pass, child_rect, SK_ColorBLUE);
981 RenderPass::Id root_pass_id(1, 0);
982 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
986 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
988 AddRenderPassQuad(root_pass, child_pass);
989 AddRenderPassQuad(child_pass, grand_child_pass);
991 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
992 renderer.DrawFrame(&render_passes_in_draw_order_,
999 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1001 DiscardCheckingContext() : discarded_(0) {
1002 set_have_post_sub_buffer(true);
1003 set_have_discard_framebuffer(true);
1006 virtual void discardFramebufferEXT(GLenum target,
1007 GLsizei numAttachments,
1008 const GLenum* attachments) OVERRIDE {
1012 int discarded() const { return discarded_; }
1013 void reset() { discarded_ = 0; }
1019 class NonReshapableOutputSurface : public FakeOutputSurface {
1021 explicit NonReshapableOutputSurface(
1022 scoped_ptr<TestWebGraphicsContext3D> context3d)
1023 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1025 surface_size_ = gfx::Size(500, 500);
1027 virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {}
1028 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1031 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1032 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1033 DiscardCheckingContext* context = context_owned.get();
1035 FakeOutputSurfaceClient output_surface_client;
1036 scoped_ptr<NonReshapableOutputSurface> output_surface(
1037 new NonReshapableOutputSurface(
1038 context_owned.PassAs<TestWebGraphicsContext3D>()));
1039 CHECK(output_surface->BindToClient(&output_surface_client));
1040 output_surface->set_fixed_size(gfx::Size(100, 100));
1042 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1043 new TestSharedBitmapManager());
1044 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1045 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
1047 LayerTreeSettings settings;
1048 settings.partial_swap_enabled = true;
1049 FakeRendererClient renderer_client;
1050 FakeRendererGL renderer(&renderer_client,
1052 output_surface.get(),
1053 resource_provider.get());
1054 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1056 gfx::Rect viewport_rect(100, 100);
1057 gfx::Rect clip_rect(100, 100);
1060 // Partial frame, should not discard.
1061 RenderPass::Id root_pass_id(1, 0);
1062 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1066 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1067 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1069 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1070 renderer.DrawFrame(&render_passes_in_draw_order_,
1075 EXPECT_EQ(0, context->discarded());
1079 // Full frame, should discard.
1080 RenderPass::Id root_pass_id(1, 0);
1081 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1085 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1086 root_pass->damage_rect = root_pass->output_rect;
1088 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1089 renderer.DrawFrame(&render_passes_in_draw_order_,
1094 EXPECT_EQ(1, context->discarded());
1098 // Full frame, external scissor is set, should not discard.
1099 output_surface->set_has_external_stencil_test(true);
1100 RenderPass::Id root_pass_id(1, 0);
1101 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1105 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1106 root_pass->damage_rect = root_pass->output_rect;
1107 root_pass->has_transparent_background = false;
1109 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1110 renderer.DrawFrame(&render_passes_in_draw_order_,
1115 EXPECT_EQ(0, context->discarded());
1117 output_surface->set_has_external_stencil_test(false);
1120 // Full frame, clipped, should not discard.
1121 clip_rect = gfx::Rect(10, 10, 10, 10);
1122 RenderPass::Id root_pass_id(1, 0);
1123 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1127 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1128 root_pass->damage_rect = root_pass->output_rect;
1130 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1131 renderer.DrawFrame(&render_passes_in_draw_order_,
1136 EXPECT_EQ(0, context->discarded());
1140 // Full frame, doesn't cover the surface, should not discard.
1141 viewport_rect = gfx::Rect(10, 10, 10, 10);
1142 RenderPass::Id root_pass_id(1, 0);
1143 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1147 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1148 root_pass->damage_rect = root_pass->output_rect;
1150 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1151 renderer.DrawFrame(&render_passes_in_draw_order_,
1156 EXPECT_EQ(0, context->discarded());
1160 // Full frame, doesn't cover the surface (no offset), should not discard.
1161 clip_rect = gfx::Rect(100, 100);
1162 viewport_rect = gfx::Rect(50, 50);
1163 RenderPass::Id root_pass_id(1, 0);
1164 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1168 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1169 root_pass->damage_rect = root_pass->output_rect;
1171 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1172 renderer.DrawFrame(&render_passes_in_draw_order_,
1177 EXPECT_EQ(0, context->discarded());
1182 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1184 FlippedScissorAndViewportContext()
1185 : did_call_viewport_(false), did_call_scissor_(false) {}
1186 virtual ~FlippedScissorAndViewportContext() {
1187 EXPECT_TRUE(did_call_viewport_);
1188 EXPECT_TRUE(did_call_scissor_);
1191 virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1195 EXPECT_EQ(100, width);
1196 EXPECT_EQ(100, height);
1197 did_call_viewport_ = true;
1200 virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1204 EXPECT_EQ(20, width);
1205 EXPECT_EQ(20, height);
1206 did_call_scissor_ = true;
1210 bool did_call_viewport_;
1211 bool did_call_scissor_;
1214 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1215 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1216 // and maintains a fixed size. This test verifies that glViewport and
1217 // glScissor's Y coordinate is flipped correctly in this environment, and that
1218 // the glViewport can be at a nonzero origin within the surface.
1219 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1220 new FlippedScissorAndViewportContext);
1222 FakeOutputSurfaceClient output_surface_client;
1223 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface(
1224 context_owned.PassAs<TestWebGraphicsContext3D>()));
1225 CHECK(output_surface->BindToClient(&output_surface_client));
1227 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1228 new TestSharedBitmapManager());
1229 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1230 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
1232 LayerTreeSettings settings;
1233 FakeRendererClient renderer_client;
1234 FakeRendererGL renderer(&renderer_client,
1236 output_surface.get(),
1237 resource_provider.get());
1238 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1240 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1241 gfx::Rect viewport_rect(device_viewport_rect.size());
1242 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1244 RenderPass::Id root_pass_id(1, 0);
1245 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1249 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1251 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1252 renderer.DrawFrame(&render_passes_in_draw_order_,
1254 device_viewport_rect,
1255 device_viewport_rect,
1259 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1260 gfx::Rect viewport_rect(1, 1);
1262 gfx::Rect child_rect(50, 50);
1263 RenderPass::Id child_pass_id(2, 0);
1264 TestRenderPass* child_pass;
1266 RenderPass::Id root_pass_id(1, 0);
1267 TestRenderPass* root_pass;
1269 ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
1272 ResourceProvider::TextureUsageAny,
1273 resource_provider_->best_texture_format());
1274 resource_provider_->AllocateForTesting(mask);
1276 SkScalar matrix[20];
1277 float amount = 0.5f;
1278 matrix[0] = 0.213f + 0.787f * amount;
1279 matrix[1] = 0.715f - 0.715f * amount;
1280 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1281 matrix[3] = matrix[4] = 0;
1282 matrix[5] = 0.213f - 0.213f * amount;
1283 matrix[6] = 0.715f + 0.285f * amount;
1284 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1285 matrix[8] = matrix[9] = 0;
1286 matrix[10] = 0.213f - 0.213f * amount;
1287 matrix[11] = 0.715f - 0.715f * amount;
1288 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1289 matrix[13] = matrix[14] = 0;
1290 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1292 skia::RefPtr<SkColorFilter> color_filter(
1293 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1294 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1295 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1296 FilterOperations filters;
1297 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1299 gfx::Transform transform_causing_aa;
1300 transform_causing_aa.Rotate(20.0);
1302 // RenderPassProgram
1303 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1308 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1314 root_pass, child_pass, 0, FilterOperations(), gfx::Transform());
1316 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1317 renderer_->DrawFrame(&render_passes_in_draw_order_,
1322 TestRenderPassProgram(TexCoordPrecisionMedium);
1324 // RenderPassColorMatrixProgram
1325 render_passes_in_draw_order_.clear();
1327 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1330 transform_causing_aa);
1332 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1337 AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform());
1339 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1340 renderer_->DrawFrame(&render_passes_in_draw_order_,
1345 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium);
1347 // RenderPassMaskProgram
1348 render_passes_in_draw_order_.clear();
1350 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1355 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1361 root_pass, child_pass, mask, FilterOperations(), gfx::Transform());
1363 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1364 renderer_->DrawFrame(&render_passes_in_draw_order_,
1369 TestRenderPassMaskProgram(TexCoordPrecisionMedium);
1371 // RenderPassMaskColorMatrixProgram
1372 render_passes_in_draw_order_.clear();
1374 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1379 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1384 AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform());
1386 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1387 renderer_->DrawFrame(&render_passes_in_draw_order_,
1392 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium);
1394 // RenderPassProgramAA
1395 render_passes_in_draw_order_.clear();
1397 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1400 transform_causing_aa);
1402 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1408 root_pass, child_pass, 0, FilterOperations(), transform_causing_aa);
1410 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1411 renderer_->DrawFrame(&render_passes_in_draw_order_,
1416 TestRenderPassProgramAA(TexCoordPrecisionMedium);
1418 // RenderPassColorMatrixProgramAA
1419 render_passes_in_draw_order_.clear();
1421 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1424 transform_causing_aa);
1426 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1431 AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa);
1433 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1434 renderer_->DrawFrame(&render_passes_in_draw_order_,
1439 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium);
1441 // RenderPassMaskProgramAA
1442 render_passes_in_draw_order_.clear();
1444 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1447 transform_causing_aa);
1449 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1455 root_pass, child_pass, mask, FilterOperations(), transform_causing_aa);
1457 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1458 renderer_->DrawFrame(&render_passes_in_draw_order_,
1463 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium);
1465 // RenderPassMaskColorMatrixProgramAA
1466 render_passes_in_draw_order_.clear();
1468 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1471 transform_causing_aa);
1473 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1476 transform_causing_aa);
1478 AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa);
1480 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1481 renderer_->DrawFrame(&render_passes_in_draw_order_,
1486 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium);
1489 // At this time, the AA code path cannot be taken if the surface's rect would
1490 // project incorrectly by the given transform, because of w<0 clipping.
1491 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1492 gfx::Rect child_rect(50, 50);
1493 RenderPass::Id child_pass_id(2, 0);
1494 TestRenderPass* child_pass;
1496 gfx::Rect viewport_rect(1, 1);
1497 RenderPass::Id root_pass_id(1, 0);
1498 TestRenderPass* root_pass;
1500 gfx::Transform transform_preventing_aa;
1501 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1502 transform_preventing_aa.RotateAboutYAxis(-20.0);
1503 transform_preventing_aa.Scale(30.0, 1.0);
1505 // Verify that the test transform and test rect actually do cause the clipped
1506 // flag to trigger. Otherwise we are not testing the intended scenario.
1507 bool clipped = false;
1508 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1509 ASSERT_TRUE(clipped);
1511 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1514 transform_preventing_aa);
1516 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1522 root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa);
1524 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1525 renderer_->DrawFrame(&render_passes_in_draw_order_,
1531 // If use_aa incorrectly ignores clipping, it will use the
1532 // RenderPassProgramAA shader instead of the RenderPassProgram.
1533 TestRenderPassProgram(TexCoordPrecisionMedium);
1536 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1537 gfx::Rect viewport_rect(1, 1);
1538 RenderPass::Id root_pass_id(1, 0);
1539 TestRenderPass* root_pass;
1541 gfx::Transform pixel_aligned_transform_causing_aa;
1542 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1543 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1545 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1549 AddTransformedQuad(root_pass,
1552 pixel_aligned_transform_causing_aa);
1554 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1555 renderer_->DrawFrame(&render_passes_in_draw_order_,
1561 TestSolidColorProgramAA();
1564 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1566 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1568 // Specifically override methods even if they are unused (used in conjunction
1569 // with StrictMock). We need to make sure that GLRenderer does not issue
1570 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1571 // through the OutputSurface abstraction.
1572 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1573 MOCK_METHOD3(reshapeWithScaleFactor,
1574 void(int width, int height, float scale_factor));
1575 MOCK_METHOD4(drawElements,
1576 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1579 class MockOutputSurface : public OutputSurface {
1583 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1584 new StrictMock<OutputSurfaceMockContext>))) {
1585 surface_size_ = gfx::Size(100, 100);
1587 virtual ~MockOutputSurface() {}
1589 MOCK_METHOD0(EnsureBackbuffer, void());
1590 MOCK_METHOD0(DiscardBackbuffer, void());
1591 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1592 MOCK_METHOD0(BindFramebuffer, void());
1593 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1596 class MockOutputSurfaceTest : public GLRendererTest {
1598 virtual void SetUp() {
1599 FakeOutputSurfaceClient output_surface_client_;
1600 CHECK(output_surface_.BindToClient(&output_surface_client_));
1602 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1603 resource_provider_ =
1604 ResourceProvider::Create(
1605 &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false)
1608 renderer_.reset(new FakeRendererGL(&renderer_client_,
1611 resource_provider_.get()));
1614 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1616 void DrawFrame(float device_scale_factor,
1617 const gfx::Rect& device_viewport_rect) {
1618 RenderPass::Id render_pass_id(1, 0);
1619 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1621 device_viewport_rect,
1623 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1625 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1627 EXPECT_CALL(output_surface_,
1628 Reshape(device_viewport_rect.size(), device_scale_factor))
1631 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1633 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1635 renderer_->DecideRenderPassAllocationsForFrame(
1636 render_passes_in_draw_order_);
1637 renderer_->DrawFrame(&render_passes_in_draw_order_,
1638 device_scale_factor,
1639 device_viewport_rect,
1640 device_viewport_rect,
1644 OutputSurfaceMockContext* Context() {
1645 return static_cast<OutputSurfaceMockContext*>(
1646 static_cast<TestContextProvider*>(
1647 output_surface_.context_provider().get())->TestContext3d());
1650 LayerTreeSettings settings_;
1651 FakeOutputSurfaceClient output_surface_client_;
1652 StrictMock<MockOutputSurface> output_surface_;
1653 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1654 scoped_ptr<ResourceProvider> resource_provider_;
1655 FakeRendererClient renderer_client_;
1656 scoped_ptr<FakeRendererGL> renderer_;
1659 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1660 gfx::Rect device_viewport_rect(1, 1);
1661 DrawFrame(1.f, device_viewport_rect);
1663 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1664 renderer_->SwapBuffers(CompositorFrameMetadata());
1667 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1668 gfx::Rect device_viewport_rect(1, 1);
1670 DrawFrame(1.f, device_viewport_rect);
1671 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1672 renderer_->SwapBuffers(CompositorFrameMetadata());
1674 device_viewport_rect = gfx::Rect(2, 2);
1676 DrawFrame(2.f, device_viewport_rect);
1677 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1678 renderer_->SwapBuffers(CompositorFrameMetadata());
1680 DrawFrame(2.f, device_viewport_rect);
1681 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1682 renderer_->SwapBuffers(CompositorFrameMetadata());
1684 device_viewport_rect = gfx::Rect(1, 1);
1686 DrawFrame(1.f, device_viewport_rect);
1687 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1688 renderer_->SwapBuffers(CompositorFrameMetadata());
1691 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1693 static void SyncPointCallback(int* callback_count) {
1694 ++(*callback_count);
1695 base::MessageLoop::current()->QuitWhenIdle();
1698 static void OtherCallback(int* callback_count) {
1699 ++(*callback_count);
1700 base::MessageLoop::current()->QuitWhenIdle();
1704 #if !defined(OS_ANDROID)
1705 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1706 int sync_point_callback_count = 0;
1707 int other_callback_count = 0;
1708 gpu::gles2::GLES2Interface* gl =
1709 output_surface_->context_provider()->ContextGL();
1710 gpu::ContextSupport* context_support =
1711 output_surface_->context_provider()->ContextSupport();
1713 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1715 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1716 GL_INNOCENT_CONTEXT_RESET_ARB);
1718 context_support->SignalSyncPoint(
1719 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1720 EXPECT_EQ(0, sync_point_callback_count);
1721 EXPECT_EQ(0, other_callback_count);
1723 // Make the sync point happen.
1725 // Post a task after the sync point.
1726 base::MessageLoop::current()->PostTask(
1727 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1729 base::MessageLoop::current()->Run();
1731 // The sync point shouldn't have happened since the context was lost.
1732 EXPECT_EQ(0, sync_point_callback_count);
1733 EXPECT_EQ(1, other_callback_count);
1736 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1737 int sync_point_callback_count = 0;
1738 int other_callback_count = 0;
1740 gpu::gles2::GLES2Interface* gl =
1741 output_surface_->context_provider()->ContextGL();
1742 gpu::ContextSupport* context_support =
1743 output_surface_->context_provider()->ContextSupport();
1745 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1747 context_support->SignalSyncPoint(
1748 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1749 EXPECT_EQ(0, sync_point_callback_count);
1750 EXPECT_EQ(0, other_callback_count);
1752 // Make the sync point happen.
1754 // Post a task after the sync point.
1755 base::MessageLoop::current()->PostTask(
1756 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1758 base::MessageLoop::current()->Run();
1760 // The sync point should have happened.
1761 EXPECT_EQ(1, sync_point_callback_count);
1762 EXPECT_EQ(1, other_callback_count);
1764 #endif // OS_ANDROID