Componentize component_updater: Copy over test data with executable bit.
[chromium-blink-merge.git] / cc / output / gl_renderer_unittest.cc
blob2ca7444f6f56a69046d2b8ab5b0c526f8d13e132
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"
7 #include <set>
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"
32 using testing::_;
33 using testing::AnyNumber;
34 using testing::Args;
35 using testing::AtLeast;
36 using testing::ElementsAre;
37 using testing::Expectation;
38 using testing::InSequence;
39 using testing::Mock;
40 using testing::Return;
41 using testing::StrictMock;
43 namespace cc {
45 class GLRendererTest : public testing::Test {
46 protected:
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) \
53 do { \
54 EXPECT_TRUE((program_binding)->program()); \
55 EXPECT_TRUE((program_binding)->initialized()); \
56 } while (false)
58 // Explicitly named to be a friend in GLRenderer for shader access.
59 class GLRendererShaderPixelTest : public GLRendererPixelTest {
60 public:
61 void TestShaders() {
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));
77 EXPECT_PROGRAM_VALID(
78 renderer()->GetRenderPassColorMatrixProgram(precision));
79 EXPECT_PROGRAM_VALID(
80 renderer()->GetRenderPassMaskColorMatrixProgramAA(precision));
81 EXPECT_PROGRAM_VALID(
82 renderer()->GetRenderPassColorMatrixProgramAA(precision));
83 EXPECT_PROGRAM_VALID(
84 renderer()->GetRenderPassMaskColorMatrixProgram(precision));
85 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
86 EXPECT_PROGRAM_VALID(
87 renderer()->GetNonPremultipliedTextureProgram(precision));
88 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision));
89 EXPECT_PROGRAM_VALID(
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));
97 else
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));
119 namespace {
121 #if !defined(OS_ANDROID)
122 TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); }
123 #endif
125 class FakeRendererGL : public GLRenderer {
126 public:
127 FakeRendererGL(RendererClient* client,
128 const LayerTreeSettings* settings,
129 OutputSurface* output_surface,
130 ResourceProvider* resource_provider)
131 : GLRenderer(client,
132 settings,
133 output_surface,
134 resource_provider,
135 NULL,
136 0) {}
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 {
149 protected:
150 GLRendererWithDefaultHarnessTest() {
151 output_surface_ =
152 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
153 CHECK(output_surface_->BindToClient(&output_surface_client_));
155 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
156 resource_provider_ =
157 ResourceProvider::Create(
158 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
159 false).Pass();
160 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
161 &settings_,
162 output_surface_.get(),
163 resource_provider_.get()));
166 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
168 LayerTreeSettings settings_;
169 FakeOutputSurfaceClient output_surface_client_;
170 scoped_ptr<FakeOutputSurface> output_surface_;
171 FakeRendererClient renderer_client_;
172 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
173 scoped_ptr<ResourceProvider> resource_provider_;
174 scoped_ptr<FakeRendererGL> renderer_;
177 // Closing the namespace here so that GLRendererShaderTest can take advantage
178 // of the friend relationship with GLRenderer and all of the mock classes
179 // declared above it.
180 } // namespace
182 class GLRendererShaderTest : public GLRendererTest {
183 protected:
184 GLRendererShaderTest() {
185 output_surface_ = FakeOutputSurface::Create3d().Pass();
186 CHECK(output_surface_->BindToClient(&output_surface_client_));
188 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
189 resource_provider_ =
190 ResourceProvider::Create(
191 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
192 false).Pass();
193 renderer_.reset(new FakeRendererGL(&renderer_client_,
194 &settings_,
195 output_surface_.get(),
196 resource_provider_.get()));
199 void TestRenderPassProgram(TexCoordPrecision precision) {
200 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_[precision]);
201 EXPECT_EQ(renderer_->render_pass_program_[precision].program(),
202 renderer_->program_shadow_);
205 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision) {
206 EXPECT_PROGRAM_VALID(
207 &renderer_->render_pass_color_matrix_program_[precision]);
208 EXPECT_EQ(renderer_->render_pass_color_matrix_program_[precision].program(),
209 renderer_->program_shadow_);
212 void TestRenderPassMaskProgram(TexCoordPrecision precision) {
213 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_[precision]);
214 EXPECT_EQ(renderer_->render_pass_mask_program_[precision].program(),
215 renderer_->program_shadow_);
218 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) {
219 EXPECT_PROGRAM_VALID(
220 &renderer_->render_pass_mask_color_matrix_program_[precision]);
221 EXPECT_EQ(
222 renderer_->render_pass_mask_color_matrix_program_[precision].program(),
223 renderer_->program_shadow_);
226 void TestRenderPassProgramAA(TexCoordPrecision precision) {
227 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_aa_[precision]);
228 EXPECT_EQ(renderer_->render_pass_program_aa_[precision].program(),
229 renderer_->program_shadow_);
232 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision) {
233 EXPECT_PROGRAM_VALID(
234 &renderer_->render_pass_color_matrix_program_aa_[precision]);
235 EXPECT_EQ(
236 renderer_->render_pass_color_matrix_program_aa_[precision].program(),
237 renderer_->program_shadow_);
240 void TestRenderPassMaskProgramAA(TexCoordPrecision precision) {
241 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_aa_[precision]);
242 EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision].program(),
243 renderer_->program_shadow_);
246 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) {
247 EXPECT_PROGRAM_VALID(
248 &renderer_->render_pass_mask_color_matrix_program_aa_[precision]);
249 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_[precision]
250 .program(),
251 renderer_->program_shadow_);
254 void TestSolidColorProgramAA() {
255 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
256 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
257 renderer_->program_shadow_);
260 LayerTreeSettings settings_;
261 FakeOutputSurfaceClient output_surface_client_;
262 scoped_ptr<FakeOutputSurface> output_surface_;
263 FakeRendererClient renderer_client_;
264 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
265 scoped_ptr<ResourceProvider> resource_provider_;
266 scoped_ptr<FakeRendererGL> renderer_;
269 namespace {
271 // Test GLRenderer DiscardBackbuffer functionality:
272 // Suggest discarding framebuffer when one exists and the renderer is not
273 // visible.
274 // Expected: it is discarded and damage tracker is reset.
275 TEST_F(
276 GLRendererWithDefaultHarnessTest,
277 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
278 renderer_->SetVisible(false);
279 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
280 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
283 // Test GLRenderer DiscardBackbuffer functionality:
284 // Suggest discarding framebuffer when one exists and the renderer is visible.
285 // Expected: the allocation is ignored.
286 TEST_F(GLRendererWithDefaultHarnessTest,
287 SuggestBackbufferNoDoNothingWhenVisible) {
288 renderer_->SetVisible(true);
289 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
290 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
293 // Test GLRenderer DiscardBackbuffer functionality:
294 // Suggest discarding framebuffer when one does not exist.
295 // Expected: it does nothing.
296 TEST_F(GLRendererWithDefaultHarnessTest,
297 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
298 renderer_->SetVisible(false);
299 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
300 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
302 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
303 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
306 // Test GLRenderer DiscardBackbuffer functionality:
307 // Begin drawing a frame while a framebuffer is discarded.
308 // Expected: will recreate framebuffer.
309 TEST_F(GLRendererWithDefaultHarnessTest,
310 DiscardedBackbufferIsRecreatedForScopeDuration) {
311 gfx::Rect viewport_rect(1, 1);
312 renderer_->SetVisible(false);
313 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
314 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
316 AddRenderPass(&render_passes_in_draw_order_,
317 RenderPassId(1, 0),
318 viewport_rect,
319 gfx::Transform());
321 renderer_->SetVisible(true);
322 renderer_->DrawFrame(&render_passes_in_draw_order_,
323 1.f,
324 viewport_rect,
325 viewport_rect,
326 false);
327 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
329 SwapBuffers();
330 EXPECT_EQ(1u, output_surface_->num_sent_frames());
333 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
334 gfx::Rect viewport_rect(1, 1);
335 EXPECT_FALSE(renderer_->stencil_enabled());
337 output_surface_->set_has_external_stencil_test(true);
339 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
340 RenderPassId(1, 0),
341 viewport_rect,
342 gfx::Transform());
343 root_pass->has_transparent_background = false;
345 renderer_->DrawFrame(&render_passes_in_draw_order_,
346 1.f,
347 viewport_rect,
348 viewport_rect,
349 false);
350 EXPECT_TRUE(renderer_->stencil_enabled());
353 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
354 public:
355 ForbidSynchronousCallContext() {}
357 virtual void getAttachedShaders(GLuint program,
358 GLsizei max_count,
359 GLsizei* count,
360 GLuint* shaders) OVERRIDE {
361 ADD_FAILURE();
363 virtual GLint getAttribLocation(GLuint program, const GLchar* name) OVERRIDE {
364 ADD_FAILURE();
365 return 0;
367 virtual void getBooleanv(GLenum pname, GLboolean* value) OVERRIDE {
368 ADD_FAILURE();
370 virtual void getBufferParameteriv(GLenum target,
371 GLenum pname,
372 GLint* value) OVERRIDE {
373 ADD_FAILURE();
375 virtual GLenum getError() OVERRIDE {
376 ADD_FAILURE();
377 return GL_NO_ERROR;
379 virtual void getFloatv(GLenum pname, GLfloat* value) OVERRIDE {
380 ADD_FAILURE();
382 virtual void getFramebufferAttachmentParameteriv(GLenum target,
383 GLenum attachment,
384 GLenum pname,
385 GLint* value) OVERRIDE {
386 ADD_FAILURE();
388 virtual void getIntegerv(GLenum pname, GLint* value) OVERRIDE {
389 if (pname == GL_MAX_TEXTURE_SIZE) {
390 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
391 *value = 1024;
392 } else {
393 ADD_FAILURE();
397 // We allow querying the shader compilation and program link status in debug
398 // mode, but not release.
399 virtual void getProgramiv(GLuint program,
400 GLenum pname,
401 GLint* value) OVERRIDE {
402 #ifndef NDEBUG
403 *value = 1;
404 #else
405 ADD_FAILURE();
406 #endif
409 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
410 #ifndef NDEBUG
411 *value = 1;
412 #else
413 ADD_FAILURE();
414 #endif
417 virtual void getRenderbufferParameteriv(GLenum target,
418 GLenum pname,
419 GLint* value) OVERRIDE {
420 ADD_FAILURE();
423 virtual void getShaderPrecisionFormat(GLenum shadertype,
424 GLenum precisiontype,
425 GLint* range,
426 GLint* precision) OVERRIDE {
427 ADD_FAILURE();
429 virtual void getTexParameterfv(GLenum target,
430 GLenum pname,
431 GLfloat* value) OVERRIDE {
432 ADD_FAILURE();
434 virtual void getTexParameteriv(GLenum target,
435 GLenum pname,
436 GLint* value) OVERRIDE {
437 ADD_FAILURE();
439 virtual void getUniformfv(GLuint program,
440 GLint location,
441 GLfloat* value) OVERRIDE {
442 ADD_FAILURE();
444 virtual void getUniformiv(GLuint program,
445 GLint location,
446 GLint* value) OVERRIDE {
447 ADD_FAILURE();
449 virtual GLint getUniformLocation(GLuint program,
450 const GLchar* name) OVERRIDE {
451 ADD_FAILURE();
452 return 0;
454 virtual void getVertexAttribfv(GLuint index,
455 GLenum pname,
456 GLfloat* value) OVERRIDE {
457 ADD_FAILURE();
459 virtual void getVertexAttribiv(GLuint index,
460 GLenum pname,
461 GLint* value) OVERRIDE {
462 ADD_FAILURE();
464 virtual GLsizeiptr getVertexAttribOffset(GLuint index,
465 GLenum pname) OVERRIDE {
466 ADD_FAILURE();
467 return 0;
470 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
471 FakeOutputSurfaceClient output_surface_client;
472 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
473 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
474 CHECK(output_surface->BindToClient(&output_surface_client));
476 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
477 new TestSharedBitmapManager());
478 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
479 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
481 LayerTreeSettings settings;
482 FakeRendererClient renderer_client;
483 FakeRendererGL renderer(&renderer_client,
484 &settings,
485 output_surface.get(),
486 resource_provider.get());
489 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
490 public:
491 LoseContextOnFirstGetContext() {}
493 virtual void getProgramiv(GLuint program,
494 GLenum pname,
495 GLint* value) OVERRIDE {
496 context_lost_ = true;
497 *value = 0;
500 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE {
501 context_lost_ = true;
502 *value = 0;
506 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
507 FakeOutputSurfaceClient output_surface_client;
508 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
509 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
510 CHECK(output_surface->BindToClient(&output_surface_client));
512 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
513 new TestSharedBitmapManager());
514 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
515 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
517 LayerTreeSettings settings;
518 FakeRendererClient renderer_client;
519 FakeRendererGL renderer(&renderer_client,
520 &settings,
521 output_surface.get(),
522 resource_provider.get());
525 class ClearCountingContext : public TestWebGraphicsContext3D {
526 public:
527 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
529 MOCK_METHOD3(discardFramebufferEXT,
530 void(GLenum target,
531 GLsizei numAttachments,
532 const GLenum* attachments));
533 MOCK_METHOD1(clear, void(GLbitfield mask));
536 TEST_F(GLRendererTest, OpaqueBackground) {
537 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
538 ClearCountingContext* context = context_owned.get();
540 FakeOutputSurfaceClient output_surface_client;
541 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
542 context_owned.PassAs<TestWebGraphicsContext3D>()));
543 CHECK(output_surface->BindToClient(&output_surface_client));
545 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
546 new TestSharedBitmapManager());
547 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
548 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
550 LayerTreeSettings settings;
551 FakeRendererClient renderer_client;
552 FakeRendererGL renderer(&renderer_client,
553 &settings,
554 output_surface.get(),
555 resource_provider.get());
557 gfx::Rect viewport_rect(1, 1);
558 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
559 RenderPassId(1, 0),
560 viewport_rect,
561 gfx::Transform());
562 root_pass->has_transparent_background = false;
564 // On DEBUG builds, render passes with opaque background clear to blue to
565 // easily see regions that were not drawn on the screen.
566 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
567 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
568 .Times(1);
569 #ifdef NDEBUG
570 EXPECT_CALL(*context, clear(_)).Times(0);
571 #else
572 EXPECT_CALL(*context, clear(_)).Times(1);
573 #endif
574 renderer.DrawFrame(&render_passes_in_draw_order_,
575 1.f,
576 viewport_rect,
577 viewport_rect,
578 false);
579 Mock::VerifyAndClearExpectations(context);
582 TEST_F(GLRendererTest, TransparentBackground) {
583 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
584 ClearCountingContext* context = context_owned.get();
586 FakeOutputSurfaceClient output_surface_client;
587 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
588 context_owned.PassAs<TestWebGraphicsContext3D>()));
589 CHECK(output_surface->BindToClient(&output_surface_client));
591 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
592 new TestSharedBitmapManager());
593 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
594 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
596 LayerTreeSettings settings;
597 FakeRendererClient renderer_client;
598 FakeRendererGL renderer(&renderer_client,
599 &settings,
600 output_surface.get(),
601 resource_provider.get());
603 gfx::Rect viewport_rect(1, 1);
604 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
605 RenderPassId(1, 0),
606 viewport_rect,
607 gfx::Transform());
608 root_pass->has_transparent_background = true;
610 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
611 EXPECT_CALL(*context, clear(_)).Times(1);
612 renderer.DrawFrame(&render_passes_in_draw_order_,
613 1.f,
614 viewport_rect,
615 viewport_rect,
616 false);
618 Mock::VerifyAndClearExpectations(context);
621 TEST_F(GLRendererTest, OffscreenOutputSurface) {
622 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
623 ClearCountingContext* context = context_owned.get();
625 FakeOutputSurfaceClient output_surface_client;
626 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateOffscreen(
627 context_owned.PassAs<TestWebGraphicsContext3D>()));
628 CHECK(output_surface->BindToClient(&output_surface_client));
630 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
631 new TestSharedBitmapManager());
632 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
633 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
635 LayerTreeSettings settings;
636 FakeRendererClient renderer_client;
637 FakeRendererGL renderer(&renderer_client,
638 &settings,
639 output_surface.get(),
640 resource_provider.get());
642 gfx::Rect viewport_rect(1, 1);
643 AddRenderPass(&render_passes_in_draw_order_,
644 RenderPassId(1, 0),
645 viewport_rect,
646 gfx::Transform());
648 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
649 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
650 .Times(1);
651 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
652 renderer.DrawFrame(&render_passes_in_draw_order_,
653 1.f,
654 viewport_rect,
655 viewport_rect,
656 false);
657 Mock::VerifyAndClearExpectations(context);
660 class VisibilityChangeIsLastCallTrackingContext
661 : public TestWebGraphicsContext3D {
662 public:
663 VisibilityChangeIsLastCallTrackingContext()
664 : last_call_was_set_visibility_(false) {}
666 // TestWebGraphicsContext3D methods.
667 virtual void flush() OVERRIDE { last_call_was_set_visibility_ = false; }
668 virtual void deleteTexture(GLuint) OVERRIDE {
669 last_call_was_set_visibility_ = false;
671 virtual void deleteFramebuffer(GLuint) OVERRIDE {
672 last_call_was_set_visibility_ = false;
674 virtual void deleteQueryEXT(GLuint) OVERRIDE {
675 last_call_was_set_visibility_ = false;
677 virtual void deleteRenderbuffer(GLuint) OVERRIDE {
678 last_call_was_set_visibility_ = false;
681 // Methods added for test.
682 void set_last_call_was_visibility(bool visible) {
683 DCHECK(last_call_was_set_visibility_ == false);
684 last_call_was_set_visibility_ = true;
686 bool last_call_was_set_visibility() const {
687 return last_call_was_set_visibility_;
690 private:
691 bool last_call_was_set_visibility_;
694 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
695 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
696 new VisibilityChangeIsLastCallTrackingContext);
697 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
699 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(
700 context_owned.PassAs<TestWebGraphicsContext3D>());
702 provider->support()->SetSurfaceVisibleCallback(base::Bind(
703 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
704 base::Unretained(context)));
706 FakeOutputSurfaceClient output_surface_client;
707 scoped_ptr<OutputSurface> output_surface(
708 FakeOutputSurface::Create3d(provider));
709 CHECK(output_surface->BindToClient(&output_surface_client));
711 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
712 new TestSharedBitmapManager());
713 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
714 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
716 LayerTreeSettings settings;
717 FakeRendererClient renderer_client;
718 FakeRendererGL renderer(&renderer_client,
719 &settings,
720 output_surface.get(),
721 resource_provider.get());
723 gfx::Rect viewport_rect(1, 1);
724 AddRenderPass(&render_passes_in_draw_order_,
725 RenderPassId(1, 0),
726 viewport_rect,
727 gfx::Transform());
729 // Ensure that the call to SetSurfaceVisible is the last call issue to the
730 // GPU process, after glFlush is called, and after the RendererClient's
731 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
732 // RenderClient and the Context by giving them both a pointer to a variable on
733 // the stack.
734 renderer.SetVisible(true);
735 renderer.DrawFrame(&render_passes_in_draw_order_,
736 1.f,
737 viewport_rect,
738 viewport_rect,
739 false);
740 renderer.SetVisible(false);
741 EXPECT_TRUE(context->last_call_was_set_visibility());
744 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
745 public:
746 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
747 test_capabilities_.gpu.egl_image_external = true;
750 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
751 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
752 MOCK_METHOD4(drawElements,
753 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
755 virtual void activeTexture(GLenum texture) {
756 EXPECT_NE(texture, active_texture_);
757 active_texture_ = texture;
760 GLenum active_texture() const { return active_texture_; }
762 private:
763 GLenum active_texture_;
766 TEST_F(GLRendererTest, ActiveTextureState) {
767 scoped_ptr<TextureStateTrackingContext> context_owned(
768 new TextureStateTrackingContext);
769 TextureStateTrackingContext* context = context_owned.get();
771 FakeOutputSurfaceClient output_surface_client;
772 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
773 context_owned.PassAs<TestWebGraphicsContext3D>()));
774 CHECK(output_surface->BindToClient(&output_surface_client));
776 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
777 new TestSharedBitmapManager());
778 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
779 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
781 LayerTreeSettings settings;
782 FakeRendererClient renderer_client;
783 FakeRendererGL renderer(&renderer_client,
784 &settings,
785 output_surface.get(),
786 resource_provider.get());
788 // During initialization we are allowed to set any texture parameters.
789 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
791 RenderPassId id(1, 1);
792 TestRenderPass* root_pass = AddRenderPass(
793 &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
794 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
795 RenderPassId(2, 1));
797 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
799 // Set up expected texture filter state transitions that match the quads
800 // created in AppendOneOfEveryQuadType().
801 Mock::VerifyAndClearExpectations(context);
803 InSequence sequence;
805 // The sync points for all quads are waited on first. This sync point is
806 // for a texture quad drawn later in the frame.
807 EXPECT_CALL(*context,
808 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
809 .Times(1);
811 // yuv_quad is drawn with the default linear filter.
812 EXPECT_CALL(*context, drawElements(_, _, _, _));
814 // tile_quad is drawn with GL_NEAREST because it is not transformed or
815 // scaled.
816 EXPECT_CALL(
817 *context,
818 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
819 EXPECT_CALL(
820 *context,
821 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
822 EXPECT_CALL(*context, drawElements(_, _, _, _));
824 // transformed_tile_quad uses GL_LINEAR.
825 EXPECT_CALL(*context, drawElements(_, _, _, _));
827 // scaled_tile_quad also uses GL_LINEAR.
828 EXPECT_CALL(*context, drawElements(_, _, _, _));
830 // The remaining quads also use GL_LINEAR because nearest neighbor
831 // filtering is currently only used with tile quads.
832 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(7);
835 gfx::Rect viewport_rect(100, 100);
836 renderer.DrawFrame(&render_passes_in_draw_order_,
837 1.f,
838 viewport_rect,
839 viewport_rect,
840 false);
841 Mock::VerifyAndClearExpectations(context);
844 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
845 public:
846 MOCK_METHOD1(clear, void(GLbitfield mask));
847 MOCK_METHOD4(drawElements,
848 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
851 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
852 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
853 new NoClearRootRenderPassMockContext);
854 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
856 FakeOutputSurfaceClient output_surface_client;
857 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
858 mock_context_owned.PassAs<TestWebGraphicsContext3D>()));
859 CHECK(output_surface->BindToClient(&output_surface_client));
861 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
862 new TestSharedBitmapManager());
863 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
864 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
866 LayerTreeSettings settings;
867 settings.should_clear_root_render_pass = false;
869 FakeRendererClient renderer_client;
870 FakeRendererGL renderer(&renderer_client,
871 &settings,
872 output_surface.get(),
873 resource_provider.get());
875 gfx::Rect viewport_rect(10, 10);
877 RenderPassId root_pass_id(1, 0);
878 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
879 root_pass_id,
880 viewport_rect,
881 gfx::Transform());
882 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
884 RenderPassId child_pass_id(2, 0);
885 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
886 child_pass_id,
887 viewport_rect,
888 gfx::Transform());
889 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
891 AddRenderPassQuad(root_pass, child_pass);
893 #ifdef NDEBUG
894 GLint clear_bits = GL_COLOR_BUFFER_BIT;
895 #else
896 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
897 #endif
899 // First render pass is not the root one, clearing should happen.
900 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
902 Expectation first_render_pass =
903 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
905 // The second render pass is the root one, clearing should be prevented.
906 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
907 first_render_pass);
909 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
910 first_render_pass);
912 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
913 renderer.DrawFrame(&render_passes_in_draw_order_,
914 1.f,
915 viewport_rect,
916 viewport_rect,
917 false);
919 // In multiple render passes all but the root pass should clear the
920 // framebuffer.
921 Mock::VerifyAndClearExpectations(&mock_context);
924 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
925 public:
926 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
928 virtual void clear(GLbitfield) OVERRIDE { EXPECT_FALSE(scissor_enabled_); }
930 virtual void enable(GLenum cap) OVERRIDE {
931 if (cap == GL_SCISSOR_TEST)
932 scissor_enabled_ = true;
935 virtual void disable(GLenum cap) OVERRIDE {
936 if (cap == GL_SCISSOR_TEST)
937 scissor_enabled_ = false;
940 private:
941 bool scissor_enabled_;
944 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
945 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
946 new ScissorTestOnClearCheckingContext);
948 FakeOutputSurfaceClient output_surface_client;
949 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
950 context_owned.PassAs<TestWebGraphicsContext3D>()));
951 CHECK(output_surface->BindToClient(&output_surface_client));
953 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
954 new TestSharedBitmapManager());
955 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
956 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
958 LayerTreeSettings settings;
959 FakeRendererClient renderer_client;
960 FakeRendererGL renderer(&renderer_client,
961 &settings,
962 output_surface.get(),
963 resource_provider.get());
964 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
966 gfx::Rect viewport_rect(1, 1);
968 gfx::Rect grand_child_rect(25, 25);
969 RenderPassId grand_child_pass_id(3, 0);
970 TestRenderPass* grand_child_pass =
971 AddRenderPass(&render_passes_in_draw_order_,
972 grand_child_pass_id,
973 grand_child_rect,
974 gfx::Transform());
975 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
977 gfx::Rect child_rect(50, 50);
978 RenderPassId child_pass_id(2, 0);
979 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
980 child_pass_id,
981 child_rect,
982 gfx::Transform());
983 AddQuad(child_pass, child_rect, SK_ColorBLUE);
985 RenderPassId root_pass_id(1, 0);
986 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
987 root_pass_id,
988 viewport_rect,
989 gfx::Transform());
990 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
992 AddRenderPassQuad(root_pass, child_pass);
993 AddRenderPassQuad(child_pass, grand_child_pass);
995 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
996 renderer.DrawFrame(&render_passes_in_draw_order_,
997 1.f,
998 viewport_rect,
999 viewport_rect,
1000 false);
1003 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1004 public:
1005 DiscardCheckingContext() : discarded_(0) {
1006 set_have_post_sub_buffer(true);
1007 set_have_discard_framebuffer(true);
1010 virtual void discardFramebufferEXT(GLenum target,
1011 GLsizei numAttachments,
1012 const GLenum* attachments) OVERRIDE {
1013 ++discarded_;
1016 int discarded() const { return discarded_; }
1017 void reset() { discarded_ = 0; }
1019 private:
1020 int discarded_;
1023 class NonReshapableOutputSurface : public FakeOutputSurface {
1024 public:
1025 explicit NonReshapableOutputSurface(
1026 scoped_ptr<TestWebGraphicsContext3D> context3d)
1027 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1028 false) {
1029 surface_size_ = gfx::Size(500, 500);
1031 virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {}
1032 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1035 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1036 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1037 DiscardCheckingContext* context = context_owned.get();
1039 FakeOutputSurfaceClient output_surface_client;
1040 scoped_ptr<NonReshapableOutputSurface> output_surface(
1041 new NonReshapableOutputSurface(
1042 context_owned.PassAs<TestWebGraphicsContext3D>()));
1043 CHECK(output_surface->BindToClient(&output_surface_client));
1044 output_surface->set_fixed_size(gfx::Size(100, 100));
1046 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1047 new TestSharedBitmapManager());
1048 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1049 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
1051 LayerTreeSettings settings;
1052 settings.partial_swap_enabled = true;
1053 FakeRendererClient renderer_client;
1054 FakeRendererGL renderer(&renderer_client,
1055 &settings,
1056 output_surface.get(),
1057 resource_provider.get());
1058 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1060 gfx::Rect viewport_rect(100, 100);
1061 gfx::Rect clip_rect(100, 100);
1064 // Partial frame, should not discard.
1065 RenderPassId root_pass_id(1, 0);
1066 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1067 root_pass_id,
1068 viewport_rect,
1069 gfx::Transform());
1070 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1071 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1073 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1074 renderer.DrawFrame(&render_passes_in_draw_order_,
1075 1.f,
1076 viewport_rect,
1077 clip_rect,
1078 false);
1079 EXPECT_EQ(0, context->discarded());
1080 context->reset();
1083 // Full frame, should discard.
1084 RenderPassId root_pass_id(1, 0);
1085 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1086 root_pass_id,
1087 viewport_rect,
1088 gfx::Transform());
1089 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1090 root_pass->damage_rect = root_pass->output_rect;
1092 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1093 renderer.DrawFrame(&render_passes_in_draw_order_,
1094 1.f,
1095 viewport_rect,
1096 clip_rect,
1097 false);
1098 EXPECT_EQ(1, context->discarded());
1099 context->reset();
1102 // Full frame, external scissor is set, should not discard.
1103 output_surface->set_has_external_stencil_test(true);
1104 RenderPassId root_pass_id(1, 0);
1105 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1106 root_pass_id,
1107 viewport_rect,
1108 gfx::Transform());
1109 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1110 root_pass->damage_rect = root_pass->output_rect;
1111 root_pass->has_transparent_background = false;
1113 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1114 renderer.DrawFrame(&render_passes_in_draw_order_,
1115 1.f,
1116 viewport_rect,
1117 clip_rect,
1118 false);
1119 EXPECT_EQ(0, context->discarded());
1120 context->reset();
1121 output_surface->set_has_external_stencil_test(false);
1124 // Full frame, clipped, should not discard.
1125 clip_rect = gfx::Rect(10, 10, 10, 10);
1126 RenderPassId root_pass_id(1, 0);
1127 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1128 root_pass_id,
1129 viewport_rect,
1130 gfx::Transform());
1131 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1132 root_pass->damage_rect = root_pass->output_rect;
1134 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1135 renderer.DrawFrame(&render_passes_in_draw_order_,
1136 1.f,
1137 viewport_rect,
1138 clip_rect,
1139 false);
1140 EXPECT_EQ(0, context->discarded());
1141 context->reset();
1144 // Full frame, doesn't cover the surface, should not discard.
1145 viewport_rect = gfx::Rect(10, 10, 10, 10);
1146 RenderPassId root_pass_id(1, 0);
1147 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1148 root_pass_id,
1149 viewport_rect,
1150 gfx::Transform());
1151 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1152 root_pass->damage_rect = root_pass->output_rect;
1154 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1155 renderer.DrawFrame(&render_passes_in_draw_order_,
1156 1.f,
1157 viewport_rect,
1158 clip_rect,
1159 false);
1160 EXPECT_EQ(0, context->discarded());
1161 context->reset();
1164 // Full frame, doesn't cover the surface (no offset), should not discard.
1165 clip_rect = gfx::Rect(100, 100);
1166 viewport_rect = gfx::Rect(50, 50);
1167 RenderPassId root_pass_id(1, 0);
1168 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1169 root_pass_id,
1170 viewport_rect,
1171 gfx::Transform());
1172 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1173 root_pass->damage_rect = root_pass->output_rect;
1175 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1176 renderer.DrawFrame(&render_passes_in_draw_order_,
1177 1.f,
1178 viewport_rect,
1179 clip_rect,
1180 false);
1181 EXPECT_EQ(0, context->discarded());
1182 context->reset();
1186 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1187 public:
1188 FlippedScissorAndViewportContext()
1189 : did_call_viewport_(false), did_call_scissor_(false) {}
1190 virtual ~FlippedScissorAndViewportContext() {
1191 EXPECT_TRUE(did_call_viewport_);
1192 EXPECT_TRUE(did_call_scissor_);
1195 virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height)
1196 OVERRIDE {
1197 EXPECT_EQ(10, x);
1198 EXPECT_EQ(390, y);
1199 EXPECT_EQ(100, width);
1200 EXPECT_EQ(100, height);
1201 did_call_viewport_ = true;
1204 virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height)
1205 OVERRIDE {
1206 EXPECT_EQ(30, x);
1207 EXPECT_EQ(450, y);
1208 EXPECT_EQ(20, width);
1209 EXPECT_EQ(20, height);
1210 did_call_scissor_ = true;
1213 private:
1214 bool did_call_viewport_;
1215 bool did_call_scissor_;
1218 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1219 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1220 // and maintains a fixed size. This test verifies that glViewport and
1221 // glScissor's Y coordinate is flipped correctly in this environment, and that
1222 // the glViewport can be at a nonzero origin within the surface.
1223 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1224 new FlippedScissorAndViewportContext);
1226 FakeOutputSurfaceClient output_surface_client;
1227 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface(
1228 context_owned.PassAs<TestWebGraphicsContext3D>()));
1229 CHECK(output_surface->BindToClient(&output_surface_client));
1231 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1232 new TestSharedBitmapManager());
1233 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1234 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false));
1236 LayerTreeSettings settings;
1237 FakeRendererClient renderer_client;
1238 FakeRendererGL renderer(&renderer_client,
1239 &settings,
1240 output_surface.get(),
1241 resource_provider.get());
1242 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1244 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1245 gfx::Rect viewport_rect(device_viewport_rect.size());
1246 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1248 RenderPassId root_pass_id(1, 0);
1249 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1250 root_pass_id,
1251 viewport_rect,
1252 gfx::Transform());
1253 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1255 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1256 renderer.DrawFrame(&render_passes_in_draw_order_,
1257 1.f,
1258 device_viewport_rect,
1259 device_viewport_rect,
1260 false);
1263 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1264 gfx::Rect viewport_rect(1, 1);
1266 gfx::Rect child_rect(50, 50);
1267 RenderPassId child_pass_id(2, 0);
1268 TestRenderPass* child_pass;
1270 RenderPassId root_pass_id(1, 0);
1271 TestRenderPass* root_pass;
1273 ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
1274 gfx::Size(20, 12),
1275 GL_CLAMP_TO_EDGE,
1276 ResourceProvider::TextureHintImmutable,
1277 resource_provider_->best_texture_format());
1278 resource_provider_->AllocateForTesting(mask);
1280 SkScalar matrix[20];
1281 float amount = 0.5f;
1282 matrix[0] = 0.213f + 0.787f * amount;
1283 matrix[1] = 0.715f - 0.715f * amount;
1284 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1285 matrix[3] = matrix[4] = 0;
1286 matrix[5] = 0.213f - 0.213f * amount;
1287 matrix[6] = 0.715f + 0.285f * amount;
1288 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1289 matrix[8] = matrix[9] = 0;
1290 matrix[10] = 0.213f - 0.213f * amount;
1291 matrix[11] = 0.715f - 0.715f * amount;
1292 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1293 matrix[13] = matrix[14] = 0;
1294 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1295 matrix[18] = 1;
1296 skia::RefPtr<SkColorFilter> color_filter(
1297 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1298 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1299 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1300 FilterOperations filters;
1301 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1303 gfx::Transform transform_causing_aa;
1304 transform_causing_aa.Rotate(20.0);
1306 // RenderPassProgram
1307 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1308 child_pass_id,
1309 child_rect,
1310 gfx::Transform());
1312 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1313 root_pass_id,
1314 viewport_rect,
1315 gfx::Transform());
1317 AddRenderPassQuad(
1318 root_pass, child_pass, 0, FilterOperations(), gfx::Transform());
1320 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1321 renderer_->DrawFrame(&render_passes_in_draw_order_,
1322 1.f,
1323 viewport_rect,
1324 viewport_rect,
1325 false);
1326 TestRenderPassProgram(TexCoordPrecisionMedium);
1328 // RenderPassColorMatrixProgram
1329 render_passes_in_draw_order_.clear();
1331 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1332 child_pass_id,
1333 child_rect,
1334 transform_causing_aa);
1336 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1337 root_pass_id,
1338 viewport_rect,
1339 gfx::Transform());
1341 AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform());
1343 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1344 renderer_->DrawFrame(&render_passes_in_draw_order_,
1345 1.f,
1346 viewport_rect,
1347 viewport_rect,
1348 false);
1349 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium);
1351 // RenderPassMaskProgram
1352 render_passes_in_draw_order_.clear();
1354 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1355 child_pass_id,
1356 child_rect,
1357 gfx::Transform());
1359 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1360 root_pass_id,
1361 viewport_rect,
1362 gfx::Transform());
1364 AddRenderPassQuad(
1365 root_pass, child_pass, mask, FilterOperations(), gfx::Transform());
1367 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1368 renderer_->DrawFrame(&render_passes_in_draw_order_,
1369 1.f,
1370 viewport_rect,
1371 viewport_rect,
1372 false);
1373 TestRenderPassMaskProgram(TexCoordPrecisionMedium);
1375 // RenderPassMaskColorMatrixProgram
1376 render_passes_in_draw_order_.clear();
1378 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1379 child_pass_id,
1380 child_rect,
1381 gfx::Transform());
1383 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1384 root_pass_id,
1385 viewport_rect,
1386 gfx::Transform());
1388 AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform());
1390 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1391 renderer_->DrawFrame(&render_passes_in_draw_order_,
1392 1.f,
1393 viewport_rect,
1394 viewport_rect,
1395 false);
1396 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium);
1398 // RenderPassProgramAA
1399 render_passes_in_draw_order_.clear();
1401 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1402 child_pass_id,
1403 child_rect,
1404 transform_causing_aa);
1406 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1407 root_pass_id,
1408 viewport_rect,
1409 gfx::Transform());
1411 AddRenderPassQuad(
1412 root_pass, child_pass, 0, FilterOperations(), transform_causing_aa);
1414 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1415 renderer_->DrawFrame(&render_passes_in_draw_order_,
1416 1.f,
1417 viewport_rect,
1418 viewport_rect,
1419 false);
1420 TestRenderPassProgramAA(TexCoordPrecisionMedium);
1422 // RenderPassColorMatrixProgramAA
1423 render_passes_in_draw_order_.clear();
1425 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1426 child_pass_id,
1427 child_rect,
1428 transform_causing_aa);
1430 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1431 root_pass_id,
1432 viewport_rect,
1433 gfx::Transform());
1435 AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa);
1437 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1438 renderer_->DrawFrame(&render_passes_in_draw_order_,
1439 1.f,
1440 viewport_rect,
1441 viewport_rect,
1442 false);
1443 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium);
1445 // RenderPassMaskProgramAA
1446 render_passes_in_draw_order_.clear();
1448 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1449 child_pass_id,
1450 child_rect,
1451 transform_causing_aa);
1453 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1454 root_pass_id,
1455 viewport_rect,
1456 gfx::Transform());
1458 AddRenderPassQuad(
1459 root_pass, child_pass, mask, FilterOperations(), transform_causing_aa);
1461 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1462 renderer_->DrawFrame(&render_passes_in_draw_order_,
1463 1.f,
1464 viewport_rect,
1465 viewport_rect,
1466 false);
1467 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium);
1469 // RenderPassMaskColorMatrixProgramAA
1470 render_passes_in_draw_order_.clear();
1472 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1473 child_pass_id,
1474 child_rect,
1475 transform_causing_aa);
1477 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1478 root_pass_id,
1479 viewport_rect,
1480 transform_causing_aa);
1482 AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa);
1484 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1485 renderer_->DrawFrame(&render_passes_in_draw_order_,
1486 1.f,
1487 viewport_rect,
1488 viewport_rect,
1489 false);
1490 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium);
1493 // At this time, the AA code path cannot be taken if the surface's rect would
1494 // project incorrectly by the given transform, because of w<0 clipping.
1495 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1496 gfx::Rect child_rect(50, 50);
1497 RenderPassId child_pass_id(2, 0);
1498 TestRenderPass* child_pass;
1500 gfx::Rect viewport_rect(1, 1);
1501 RenderPassId root_pass_id(1, 0);
1502 TestRenderPass* root_pass;
1504 gfx::Transform transform_preventing_aa;
1505 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1506 transform_preventing_aa.RotateAboutYAxis(-20.0);
1507 transform_preventing_aa.Scale(30.0, 1.0);
1509 // Verify that the test transform and test rect actually do cause the clipped
1510 // flag to trigger. Otherwise we are not testing the intended scenario.
1511 bool clipped = false;
1512 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1513 ASSERT_TRUE(clipped);
1515 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1516 child_pass_id,
1517 child_rect,
1518 transform_preventing_aa);
1520 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1521 root_pass_id,
1522 viewport_rect,
1523 gfx::Transform());
1525 AddRenderPassQuad(
1526 root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa);
1528 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1529 renderer_->DrawFrame(&render_passes_in_draw_order_,
1530 1.f,
1531 viewport_rect,
1532 viewport_rect,
1533 false);
1535 // If use_aa incorrectly ignores clipping, it will use the
1536 // RenderPassProgramAA shader instead of the RenderPassProgram.
1537 TestRenderPassProgram(TexCoordPrecisionMedium);
1540 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1541 gfx::Rect viewport_rect(1, 1);
1542 RenderPassId root_pass_id(1, 0);
1543 TestRenderPass* root_pass;
1545 gfx::Transform pixel_aligned_transform_causing_aa;
1546 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1547 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1549 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1550 root_pass_id,
1551 viewport_rect,
1552 gfx::Transform());
1553 AddTransformedQuad(root_pass,
1554 viewport_rect,
1555 SK_ColorYELLOW,
1556 pixel_aligned_transform_causing_aa);
1558 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1559 renderer_->DrawFrame(&render_passes_in_draw_order_,
1560 1.f,
1561 viewport_rect,
1562 viewport_rect,
1563 false);
1565 TestSolidColorProgramAA();
1568 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1569 public:
1570 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1572 // Specifically override methods even if they are unused (used in conjunction
1573 // with StrictMock). We need to make sure that GLRenderer does not issue
1574 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1575 // through the OutputSurface abstraction.
1576 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1577 MOCK_METHOD3(reshapeWithScaleFactor,
1578 void(int width, int height, float scale_factor));
1579 MOCK_METHOD4(drawElements,
1580 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1583 class MockOutputSurface : public OutputSurface {
1584 public:
1585 MockOutputSurface()
1586 : OutputSurface(
1587 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1588 new StrictMock<OutputSurfaceMockContext>))) {
1589 surface_size_ = gfx::Size(100, 100);
1591 virtual ~MockOutputSurface() {}
1593 MOCK_METHOD0(EnsureBackbuffer, void());
1594 MOCK_METHOD0(DiscardBackbuffer, void());
1595 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1596 MOCK_METHOD0(BindFramebuffer, void());
1597 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1600 class MockOutputSurfaceTest : public GLRendererTest {
1601 protected:
1602 virtual void SetUp() {
1603 FakeOutputSurfaceClient output_surface_client_;
1604 CHECK(output_surface_.BindToClient(&output_surface_client_));
1606 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1607 resource_provider_ =
1608 ResourceProvider::Create(
1609 &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false)
1610 .Pass();
1612 renderer_.reset(new FakeRendererGL(&renderer_client_,
1613 &settings_,
1614 &output_surface_,
1615 resource_provider_.get()));
1618 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1620 void DrawFrame(float device_scale_factor,
1621 const gfx::Rect& device_viewport_rect) {
1622 RenderPassId render_pass_id(1, 0);
1623 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1624 render_pass_id,
1625 device_viewport_rect,
1626 gfx::Transform());
1627 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1629 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1631 EXPECT_CALL(output_surface_,
1632 Reshape(device_viewport_rect.size(), device_scale_factor))
1633 .Times(1);
1635 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1637 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1639 renderer_->DecideRenderPassAllocationsForFrame(
1640 render_passes_in_draw_order_);
1641 renderer_->DrawFrame(&render_passes_in_draw_order_,
1642 device_scale_factor,
1643 device_viewport_rect,
1644 device_viewport_rect,
1645 false);
1648 OutputSurfaceMockContext* Context() {
1649 return static_cast<OutputSurfaceMockContext*>(
1650 static_cast<TestContextProvider*>(
1651 output_surface_.context_provider().get())->TestContext3d());
1654 LayerTreeSettings settings_;
1655 FakeOutputSurfaceClient output_surface_client_;
1656 StrictMock<MockOutputSurface> output_surface_;
1657 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1658 scoped_ptr<ResourceProvider> resource_provider_;
1659 FakeRendererClient renderer_client_;
1660 scoped_ptr<FakeRendererGL> renderer_;
1663 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1664 gfx::Rect device_viewport_rect(1, 1);
1665 DrawFrame(1.f, device_viewport_rect);
1667 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1668 renderer_->SwapBuffers(CompositorFrameMetadata());
1671 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1672 gfx::Rect device_viewport_rect(1, 1);
1674 DrawFrame(1.f, device_viewport_rect);
1675 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1676 renderer_->SwapBuffers(CompositorFrameMetadata());
1678 device_viewport_rect = gfx::Rect(2, 2);
1680 DrawFrame(2.f, device_viewport_rect);
1681 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1682 renderer_->SwapBuffers(CompositorFrameMetadata());
1684 DrawFrame(2.f, device_viewport_rect);
1685 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1686 renderer_->SwapBuffers(CompositorFrameMetadata());
1688 device_viewport_rect = gfx::Rect(1, 1);
1690 DrawFrame(1.f, device_viewport_rect);
1691 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1692 renderer_->SwapBuffers(CompositorFrameMetadata());
1695 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1696 protected:
1697 static void SyncPointCallback(int* callback_count) {
1698 ++(*callback_count);
1699 base::MessageLoop::current()->QuitWhenIdle();
1702 static void OtherCallback(int* callback_count) {
1703 ++(*callback_count);
1704 base::MessageLoop::current()->QuitWhenIdle();
1708 #if !defined(OS_ANDROID)
1709 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1710 int sync_point_callback_count = 0;
1711 int other_callback_count = 0;
1712 gpu::gles2::GLES2Interface* gl =
1713 output_surface_->context_provider()->ContextGL();
1714 gpu::ContextSupport* context_support =
1715 output_surface_->context_provider()->ContextSupport();
1717 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1719 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1720 GL_INNOCENT_CONTEXT_RESET_ARB);
1722 context_support->SignalSyncPoint(
1723 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1724 EXPECT_EQ(0, sync_point_callback_count);
1725 EXPECT_EQ(0, other_callback_count);
1727 // Make the sync point happen.
1728 gl->Finish();
1729 // Post a task after the sync point.
1730 base::MessageLoop::current()->PostTask(
1731 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1733 base::MessageLoop::current()->Run();
1735 // The sync point shouldn't have happened since the context was lost.
1736 EXPECT_EQ(0, sync_point_callback_count);
1737 EXPECT_EQ(1, other_callback_count);
1740 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1741 int sync_point_callback_count = 0;
1742 int other_callback_count = 0;
1744 gpu::gles2::GLES2Interface* gl =
1745 output_surface_->context_provider()->ContextGL();
1746 gpu::ContextSupport* context_support =
1747 output_surface_->context_provider()->ContextSupport();
1749 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1751 context_support->SignalSyncPoint(
1752 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1753 EXPECT_EQ(0, sync_point_callback_count);
1754 EXPECT_EQ(0, other_callback_count);
1756 // Make the sync point happen.
1757 gl->Finish();
1758 // Post a task after the sync point.
1759 base::MessageLoop::current()->PostTask(
1760 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1762 base::MessageLoop::current()->Run();
1764 // The sync point should have happened.
1765 EXPECT_EQ(1, sync_point_callback_count);
1766 EXPECT_EQ(1, other_callback_count);
1768 #endif // OS_ANDROID
1770 } // namespace
1771 } // namespace cc