Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / cc / output / gl_renderer_unittest.cc
blob62c5e7410948cb924eb2e5766fa14d2bd9a16e21
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 "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "cc/base/math_util.h"
13 #include "cc/output/compositor_frame_metadata.h"
14 #include "cc/output/copy_output_request.h"
15 #include "cc/output/copy_output_result.h"
16 #include "cc/output/overlay_strategy_single_on_top.h"
17 #include "cc/output/texture_mailbox_deleter.h"
18 #include "cc/quads/texture_draw_quad.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/test/fake_impl_proxy.h"
21 #include "cc/test/fake_layer_tree_host_impl.h"
22 #include "cc/test/fake_output_surface.h"
23 #include "cc/test/fake_output_surface_client.h"
24 #include "cc/test/fake_renderer_client.h"
25 #include "cc/test/fake_resource_provider.h"
26 #include "cc/test/pixel_test.h"
27 #include "cc/test/render_pass_test_common.h"
28 #include "cc/test/render_pass_test_utils.h"
29 #include "cc/test/test_shared_bitmap_manager.h"
30 #include "cc/test/test_web_graphics_context_3d.h"
31 #include "gpu/GLES2/gl2extchromium.h"
32 #include "gpu/command_buffer/client/context_support.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/skia/include/core/SkImageFilter.h"
36 #include "third_party/skia/include/core/SkMatrix.h"
37 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
38 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
39 #include "ui/gfx/transform.h"
41 using testing::_;
42 using testing::AnyNumber;
43 using testing::Args;
44 using testing::AtLeast;
45 using testing::ElementsAre;
46 using testing::Expectation;
47 using testing::InSequence;
48 using testing::Mock;
49 using testing::Return;
50 using testing::StrictMock;
52 namespace cc {
54 class GLRendererTest : public testing::Test {
55 protected:
56 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
58 RenderPassList render_passes_in_draw_order_;
61 #define EXPECT_PROGRAM_VALID(program_binding) \
62 do { \
63 EXPECT_TRUE((program_binding)->program()); \
64 EXPECT_TRUE((program_binding)->initialized()); \
65 } while (false)
67 static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
68 switch (blend_mode) {
69 case BLEND_MODE_NONE:
70 case BLEND_MODE_NORMAL:
71 return SkXfermode::kSrcOver_Mode;
72 case BLEND_MODE_SCREEN:
73 return SkXfermode::kScreen_Mode;
74 case BLEND_MODE_OVERLAY:
75 return SkXfermode::kOverlay_Mode;
76 case BLEND_MODE_DARKEN:
77 return SkXfermode::kDarken_Mode;
78 case BLEND_MODE_LIGHTEN:
79 return SkXfermode::kLighten_Mode;
80 case BLEND_MODE_COLOR_DODGE:
81 return SkXfermode::kColorDodge_Mode;
82 case BLEND_MODE_COLOR_BURN:
83 return SkXfermode::kColorBurn_Mode;
84 case BLEND_MODE_HARD_LIGHT:
85 return SkXfermode::kHardLight_Mode;
86 case BLEND_MODE_SOFT_LIGHT:
87 return SkXfermode::kSoftLight_Mode;
88 case BLEND_MODE_DIFFERENCE:
89 return SkXfermode::kDifference_Mode;
90 case BLEND_MODE_EXCLUSION:
91 return SkXfermode::kExclusion_Mode;
92 case BLEND_MODE_MULTIPLY:
93 return SkXfermode::kMultiply_Mode;
94 case BLEND_MODE_HUE:
95 return SkXfermode::kHue_Mode;
96 case BLEND_MODE_SATURATION:
97 return SkXfermode::kSaturation_Mode;
98 case BLEND_MODE_COLOR:
99 return SkXfermode::kColor_Mode;
100 case BLEND_MODE_LUMINOSITY:
101 return SkXfermode::kLuminosity_Mode;
103 return SkXfermode::kSrcOver_Mode;
106 // Explicitly named to be a friend in GLRenderer for shader access.
107 class GLRendererShaderPixelTest : public GLRendererPixelTest {
108 public:
109 void SetUp() override {
110 GLRendererPixelTest::SetUp();
111 ASSERT_FALSE(renderer()->IsContextLost());
114 void TearDown() override {
115 GLRendererPixelTest::TearDown();
116 ASSERT_FALSE(renderer()->IsContextLost());
119 void TestBasicShaders() {
120 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
122 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
123 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
126 void TestShadersWithPrecision(TexCoordPrecision precision) {
127 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
128 if (renderer()->Capabilities().using_egl_image)
129 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
130 else
131 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
134 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision,
135 BlendMode blend_mode) {
136 EXPECT_PROGRAM_VALID(
137 renderer()->GetRenderPassProgram(precision, blend_mode));
138 EXPECT_PROGRAM_VALID(
139 renderer()->GetRenderPassProgramAA(precision, blend_mode));
142 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision,
143 SamplerType sampler) {
144 if (!renderer()->Capabilities().using_egl_image &&
145 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
146 // This will likely be hit in tests due to usage of osmesa.
147 return;
150 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision, sampler));
151 EXPECT_PROGRAM_VALID(
152 renderer()->GetNonPremultipliedTextureProgram(precision, sampler));
153 EXPECT_PROGRAM_VALID(
154 renderer()->GetTextureBackgroundProgram(precision, sampler));
155 EXPECT_PROGRAM_VALID(
156 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision,
157 sampler));
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
160 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
161 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
162 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
163 EXPECT_PROGRAM_VALID(
164 renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
165 EXPECT_PROGRAM_VALID(
166 renderer()->GetTileProgramSwizzleAA(precision, sampler));
167 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision, sampler));
168 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision, sampler));
171 void TestShadersWithMasks(TexCoordPrecision precision,
172 SamplerType sampler,
173 BlendMode blend_mode,
174 bool mask_for_background) {
175 if (!renderer()->Capabilities().using_egl_image &&
176 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
177 // This will likely be hit in tests due to usage of osmesa.
178 return;
181 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
182 precision, sampler, blend_mode, mask_for_background));
183 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
184 precision, sampler, blend_mode, mask_for_background));
185 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
186 precision, sampler, blend_mode, mask_for_background));
187 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
188 precision, sampler, blend_mode, mask_for_background));
192 namespace {
194 #if !defined(OS_ANDROID) && !defined(OS_WIN)
195 static const TexCoordPrecision kPrecisionList[] = {TEX_COORD_PRECISION_MEDIUM,
196 TEX_COORD_PRECISION_HIGH};
198 static const BlendMode kBlendModeList[LAST_BLEND_MODE + 1] = {
199 BLEND_MODE_NONE,
200 BLEND_MODE_NORMAL,
201 BLEND_MODE_SCREEN,
202 BLEND_MODE_OVERLAY,
203 BLEND_MODE_DARKEN,
204 BLEND_MODE_LIGHTEN,
205 BLEND_MODE_COLOR_DODGE,
206 BLEND_MODE_COLOR_BURN,
207 BLEND_MODE_HARD_LIGHT,
208 BLEND_MODE_SOFT_LIGHT,
209 BLEND_MODE_DIFFERENCE,
210 BLEND_MODE_EXCLUSION,
211 BLEND_MODE_MULTIPLY,
212 BLEND_MODE_HUE,
213 BLEND_MODE_SATURATION,
214 BLEND_MODE_COLOR,
215 BLEND_MODE_LUMINOSITY,
218 static const SamplerType kSamplerList[] = {
219 SAMPLER_TYPE_2D,
220 SAMPLER_TYPE_2D_RECT,
221 SAMPLER_TYPE_EXTERNAL_OES,
224 TEST_F(GLRendererShaderPixelTest, BasicShadersCompile) {
225 TestBasicShaders();
228 class PrecisionShaderPixelTest
229 : public GLRendererShaderPixelTest,
230 public ::testing::WithParamInterface<TexCoordPrecision> {};
232 TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
233 TestShadersWithPrecision(GetParam());
236 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile,
237 PrecisionShaderPixelTest,
238 ::testing::ValuesIn(kPrecisionList));
240 class PrecisionBlendShaderPixelTest
241 : public GLRendererShaderPixelTest,
242 public ::testing::WithParamInterface<
243 std::tr1::tuple<TexCoordPrecision, BlendMode>> {};
245 TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
246 TestShadersWithPrecisionAndBlend(std::tr1::get<0>(GetParam()),
247 std::tr1::get<1>(GetParam()));
250 INSTANTIATE_TEST_CASE_P(
251 PrecisionBlendShadersCompile,
252 PrecisionBlendShaderPixelTest,
253 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
254 ::testing::ValuesIn(kBlendModeList)));
256 class PrecisionSamplerShaderPixelTest
257 : public GLRendererShaderPixelTest,
258 public ::testing::WithParamInterface<
259 std::tr1::tuple<TexCoordPrecision, SamplerType>> {};
261 TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
262 TestShadersWithPrecisionAndSampler(std::tr1::get<0>(GetParam()),
263 std::tr1::get<1>(GetParam()));
266 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile,
267 PrecisionSamplerShaderPixelTest,
268 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
269 ::testing::ValuesIn(kSamplerList)));
271 class MaskShaderPixelTest
272 : public GLRendererShaderPixelTest,
273 public ::testing::WithParamInterface<
274 std::tr1::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {};
276 TEST_P(MaskShaderPixelTest, ShadersCompile) {
277 TestShadersWithMasks(
278 std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
279 std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam()));
282 INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
283 MaskShaderPixelTest,
284 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
285 ::testing::ValuesIn(kSamplerList),
286 ::testing::ValuesIn(kBlendModeList),
287 ::testing::Bool()));
289 #endif
291 class FakeRendererGL : public GLRenderer {
292 public:
293 FakeRendererGL(RendererClient* client,
294 const RendererSettings* settings,
295 OutputSurface* output_surface,
296 ResourceProvider* resource_provider)
297 : GLRenderer(client,
298 settings,
299 output_surface,
300 resource_provider,
301 NULL,
302 0) {}
304 FakeRendererGL(RendererClient* client,
305 const RendererSettings* settings,
306 OutputSurface* output_surface,
307 ResourceProvider* resource_provider,
308 TextureMailboxDeleter* texture_mailbox_deleter)
309 : GLRenderer(client,
310 settings,
311 output_surface,
312 resource_provider,
313 texture_mailbox_deleter,
314 0) {}
316 void SetOverlayProcessor(OverlayProcessor* processor) {
317 overlay_processor_.reset(processor);
320 // GLRenderer methods.
322 // Changing visibility to public.
323 using GLRenderer::IsBackbufferDiscarded;
324 using GLRenderer::DoDrawQuad;
325 using GLRenderer::BeginDrawingFrame;
326 using GLRenderer::FinishDrawingQuadList;
327 using GLRenderer::stencil_enabled;
330 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
331 protected:
332 GLRendererWithDefaultHarnessTest() {
333 output_surface_ =
334 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
335 CHECK(output_surface_->BindToClient(&output_surface_client_));
337 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
338 resource_provider_ = FakeResourceProvider::Create(
339 output_surface_.get(), shared_bitmap_manager_.get());
340 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
341 &settings_,
342 output_surface_.get(),
343 resource_provider_.get()));
346 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
348 RendererSettings settings_;
349 FakeOutputSurfaceClient output_surface_client_;
350 scoped_ptr<FakeOutputSurface> output_surface_;
351 FakeRendererClient renderer_client_;
352 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
353 scoped_ptr<ResourceProvider> resource_provider_;
354 scoped_ptr<FakeRendererGL> renderer_;
357 // Closing the namespace here so that GLRendererShaderTest can take advantage
358 // of the friend relationship with GLRenderer and all of the mock classes
359 // declared above it.
360 } // namespace
362 class GLRendererShaderTest : public GLRendererTest {
363 protected:
364 GLRendererShaderTest() {
365 output_surface_ = FakeOutputSurface::Create3d().Pass();
366 CHECK(output_surface_->BindToClient(&output_surface_client_));
368 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
369 resource_provider_ = FakeResourceProvider::Create(
370 output_surface_.get(), shared_bitmap_manager_.get());
371 renderer_.reset(new FakeRendererGL(&renderer_client_,
372 &settings_,
373 output_surface_.get(),
374 resource_provider_.get()));
377 void TestRenderPassProgram(TexCoordPrecision precision,
378 BlendMode blend_mode) {
379 EXPECT_PROGRAM_VALID(
380 &renderer_->render_pass_program_[precision][blend_mode]);
381 EXPECT_EQ(renderer_->render_pass_program_[precision][blend_mode].program(),
382 renderer_->program_shadow_);
385 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
386 BlendMode blend_mode) {
387 EXPECT_PROGRAM_VALID(
388 &renderer_->render_pass_color_matrix_program_[precision][blend_mode]);
389 EXPECT_EQ(
390 renderer_->render_pass_color_matrix_program_[precision][blend_mode]
391 .program(),
392 renderer_->program_shadow_);
395 void TestRenderPassMaskProgram(TexCoordPrecision precision,
396 SamplerType sampler,
397 BlendMode blend_mode) {
398 EXPECT_PROGRAM_VALID(
399 &renderer_->render_pass_mask_program_[precision]
400 [sampler]
401 [blend_mode]
402 [NO_MASK]);
403 EXPECT_EQ(
404 renderer_->render_pass_mask_program_[precision]
405 [sampler]
406 [blend_mode]
407 [NO_MASK].program(),
408 renderer_->program_shadow_);
411 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
412 SamplerType sampler,
413 BlendMode blend_mode) {
414 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_
415 [precision][sampler][blend_mode][NO_MASK]);
416 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_
417 [precision][sampler][blend_mode][NO_MASK].program(),
418 renderer_->program_shadow_);
421 void TestRenderPassProgramAA(TexCoordPrecision precision,
422 BlendMode blend_mode) {
423 EXPECT_PROGRAM_VALID(
424 &renderer_->render_pass_program_aa_[precision][blend_mode]);
425 EXPECT_EQ(
426 renderer_->render_pass_program_aa_[precision][blend_mode].program(),
427 renderer_->program_shadow_);
430 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
431 BlendMode blend_mode) {
432 EXPECT_PROGRAM_VALID(
433 &renderer_
434 ->render_pass_color_matrix_program_aa_[precision][blend_mode]);
435 EXPECT_EQ(
436 renderer_->render_pass_color_matrix_program_aa_[precision][blend_mode]
437 .program(),
438 renderer_->program_shadow_);
441 void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
442 SamplerType sampler,
443 BlendMode blend_mode) {
444 EXPECT_PROGRAM_VALID(
445 &renderer_
446 ->render_pass_mask_program_aa_
447 [precision][sampler][blend_mode][NO_MASK]);
448 EXPECT_EQ(
449 renderer_->render_pass_mask_program_aa_[precision][sampler][blend_mode]
450 [NO_MASK].program(),
451 renderer_->program_shadow_);
454 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
455 SamplerType sampler,
456 BlendMode blend_mode) {
457 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_aa_
458 [precision][sampler][blend_mode][NO_MASK]);
459 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_
460 [precision][sampler][blend_mode][NO_MASK].program(),
461 renderer_->program_shadow_);
464 void TestSolidColorProgramAA() {
465 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
466 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
467 renderer_->program_shadow_);
470 RendererSettings settings_;
471 FakeOutputSurfaceClient output_surface_client_;
472 scoped_ptr<FakeOutputSurface> output_surface_;
473 FakeRendererClient renderer_client_;
474 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
475 scoped_ptr<ResourceProvider> resource_provider_;
476 scoped_ptr<FakeRendererGL> renderer_;
479 namespace {
481 // Test GLRenderer DiscardBackbuffer functionality:
482 // Suggest discarding framebuffer when one exists and the renderer is not
483 // visible.
484 // Expected: it is discarded and damage tracker is reset.
485 TEST_F(
486 GLRendererWithDefaultHarnessTest,
487 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
488 renderer_->SetVisible(false);
489 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
490 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
493 // Test GLRenderer DiscardBackbuffer functionality:
494 // Suggest discarding framebuffer when one exists and the renderer is visible.
495 // Expected: the allocation is ignored.
496 TEST_F(GLRendererWithDefaultHarnessTest,
497 SuggestBackbufferNoDoNothingWhenVisible) {
498 renderer_->SetVisible(true);
499 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
500 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
503 // Test GLRenderer DiscardBackbuffer functionality:
504 // Suggest discarding framebuffer when one does not exist.
505 // Expected: it does nothing.
506 TEST_F(GLRendererWithDefaultHarnessTest,
507 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
508 renderer_->SetVisible(false);
509 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
510 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
512 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
513 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
516 // Test GLRenderer DiscardBackbuffer functionality:
517 // Begin drawing a frame while a framebuffer is discarded.
518 // Expected: will recreate framebuffer.
519 TEST_F(GLRendererWithDefaultHarnessTest,
520 DiscardedBackbufferIsRecreatedForScopeDuration) {
521 gfx::Rect viewport_rect(1, 1);
522 renderer_->SetVisible(false);
523 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
524 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
526 AddRenderPass(&render_passes_in_draw_order_,
527 RenderPassId(1, 0),
528 viewport_rect,
529 gfx::Transform());
531 renderer_->SetVisible(true);
532 renderer_->DrawFrame(&render_passes_in_draw_order_,
533 1.f,
534 viewport_rect,
535 viewport_rect,
536 false);
537 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
539 SwapBuffers();
540 EXPECT_EQ(1u, output_surface_->num_sent_frames());
543 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
544 gfx::Rect viewport_rect(1, 1);
545 EXPECT_FALSE(renderer_->stencil_enabled());
547 output_surface_->set_has_external_stencil_test(true);
549 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
550 RenderPassId(1, 0),
551 viewport_rect,
552 gfx::Transform());
553 root_pass->has_transparent_background = false;
555 renderer_->DrawFrame(&render_passes_in_draw_order_,
556 1.f,
557 viewport_rect,
558 viewport_rect,
559 false);
560 EXPECT_TRUE(renderer_->stencil_enabled());
563 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
564 public:
565 ForbidSynchronousCallContext() {}
567 void getAttachedShaders(GLuint program,
568 GLsizei max_count,
569 GLsizei* count,
570 GLuint* shaders) override {
571 ADD_FAILURE();
573 GLint getAttribLocation(GLuint program, const GLchar* name) override {
574 ADD_FAILURE();
575 return 0;
577 void getBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
578 void getBufferParameteriv(GLenum target,
579 GLenum pname,
580 GLint* value) override {
581 ADD_FAILURE();
583 GLenum getError() override {
584 ADD_FAILURE();
585 return GL_NO_ERROR;
587 void getFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
588 void getFramebufferAttachmentParameteriv(GLenum target,
589 GLenum attachment,
590 GLenum pname,
591 GLint* value) override {
592 ADD_FAILURE();
594 void getIntegerv(GLenum pname, GLint* value) override {
595 if (pname == GL_MAX_TEXTURE_SIZE) {
596 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
597 *value = 1024;
598 } else {
599 ADD_FAILURE();
603 // We allow querying the shader compilation and program link status in debug
604 // mode, but not release.
605 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
606 #ifndef NDEBUG
607 *value = 1;
608 #else
609 ADD_FAILURE();
610 #endif
613 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
614 #ifndef NDEBUG
615 *value = 1;
616 #else
617 ADD_FAILURE();
618 #endif
621 void getRenderbufferParameteriv(GLenum target,
622 GLenum pname,
623 GLint* value) override {
624 ADD_FAILURE();
627 void getShaderPrecisionFormat(GLenum shadertype,
628 GLenum precisiontype,
629 GLint* range,
630 GLint* precision) override {
631 ADD_FAILURE();
633 void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
634 ADD_FAILURE();
636 void getTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
637 ADD_FAILURE();
639 void getUniformfv(GLuint program, GLint location, GLfloat* value) override {
640 ADD_FAILURE();
642 void getUniformiv(GLuint program, GLint location, GLint* value) override {
643 ADD_FAILURE();
645 GLint getUniformLocation(GLuint program, const GLchar* name) override {
646 ADD_FAILURE();
647 return 0;
649 void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
650 ADD_FAILURE();
652 void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
653 ADD_FAILURE();
655 GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname) override {
656 ADD_FAILURE();
657 return 0;
660 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
661 FakeOutputSurfaceClient output_surface_client;
662 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
663 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
664 CHECK(output_surface->BindToClient(&output_surface_client));
666 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
667 new TestSharedBitmapManager());
668 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
669 output_surface.get(), shared_bitmap_manager.get());
671 RendererSettings settings;
672 FakeRendererClient renderer_client;
673 FakeRendererGL renderer(&renderer_client,
674 &settings,
675 output_surface.get(),
676 resource_provider.get());
679 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
680 public:
681 LoseContextOnFirstGetContext() {}
683 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
684 context_lost_ = true;
685 *value = 0;
688 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
689 context_lost_ = true;
690 *value = 0;
694 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
695 FakeOutputSurfaceClient output_surface_client;
696 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
697 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
698 CHECK(output_surface->BindToClient(&output_surface_client));
700 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
701 new TestSharedBitmapManager());
702 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
703 output_surface.get(), shared_bitmap_manager.get());
705 RendererSettings settings;
706 FakeRendererClient renderer_client;
707 FakeRendererGL renderer(&renderer_client,
708 &settings,
709 output_surface.get(),
710 resource_provider.get());
713 class ClearCountingContext : public TestWebGraphicsContext3D {
714 public:
715 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
717 MOCK_METHOD3(discardFramebufferEXT,
718 void(GLenum target,
719 GLsizei numAttachments,
720 const GLenum* attachments));
721 MOCK_METHOD1(clear, void(GLbitfield mask));
724 TEST_F(GLRendererTest, OpaqueBackground) {
725 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
726 ClearCountingContext* context = context_owned.get();
728 FakeOutputSurfaceClient output_surface_client;
729 scoped_ptr<OutputSurface> output_surface(
730 FakeOutputSurface::Create3d(context_owned.Pass()));
731 CHECK(output_surface->BindToClient(&output_surface_client));
733 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
734 new TestSharedBitmapManager());
735 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
736 output_surface.get(), shared_bitmap_manager.get());
738 RendererSettings settings;
739 FakeRendererClient renderer_client;
740 FakeRendererGL renderer(&renderer_client,
741 &settings,
742 output_surface.get(),
743 resource_provider.get());
745 gfx::Rect viewport_rect(1, 1);
746 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
747 RenderPassId(1, 0),
748 viewport_rect,
749 gfx::Transform());
750 root_pass->has_transparent_background = false;
752 // On DEBUG builds, render passes with opaque background clear to blue to
753 // easily see regions that were not drawn on the screen.
754 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
755 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
756 .Times(1);
757 #ifdef NDEBUG
758 EXPECT_CALL(*context, clear(_)).Times(0);
759 #else
760 EXPECT_CALL(*context, clear(_)).Times(1);
761 #endif
762 renderer.DrawFrame(&render_passes_in_draw_order_,
763 1.f,
764 viewport_rect,
765 viewport_rect,
766 false);
767 Mock::VerifyAndClearExpectations(context);
770 TEST_F(GLRendererTest, TransparentBackground) {
771 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
772 ClearCountingContext* context = context_owned.get();
774 FakeOutputSurfaceClient output_surface_client;
775 scoped_ptr<OutputSurface> output_surface(
776 FakeOutputSurface::Create3d(context_owned.Pass()));
777 CHECK(output_surface->BindToClient(&output_surface_client));
779 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
780 new TestSharedBitmapManager());
781 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
782 output_surface.get(), shared_bitmap_manager.get());
784 RendererSettings settings;
785 FakeRendererClient renderer_client;
786 FakeRendererGL renderer(&renderer_client,
787 &settings,
788 output_surface.get(),
789 resource_provider.get());
791 gfx::Rect viewport_rect(1, 1);
792 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
793 RenderPassId(1, 0),
794 viewport_rect,
795 gfx::Transform());
796 root_pass->has_transparent_background = true;
798 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
799 EXPECT_CALL(*context, clear(_)).Times(1);
800 renderer.DrawFrame(&render_passes_in_draw_order_,
801 1.f,
802 viewport_rect,
803 viewport_rect,
804 false);
806 Mock::VerifyAndClearExpectations(context);
809 TEST_F(GLRendererTest, OffscreenOutputSurface) {
810 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
811 ClearCountingContext* context = context_owned.get();
813 FakeOutputSurfaceClient output_surface_client;
814 scoped_ptr<OutputSurface> output_surface(
815 FakeOutputSurface::CreateOffscreen(context_owned.Pass()));
816 CHECK(output_surface->BindToClient(&output_surface_client));
818 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
819 new TestSharedBitmapManager());
820 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
821 output_surface.get(), shared_bitmap_manager.get());
823 RendererSettings settings;
824 FakeRendererClient renderer_client;
825 FakeRendererGL renderer(&renderer_client,
826 &settings,
827 output_surface.get(),
828 resource_provider.get());
830 gfx::Rect viewport_rect(1, 1);
831 AddRenderPass(&render_passes_in_draw_order_,
832 RenderPassId(1, 0),
833 viewport_rect,
834 gfx::Transform());
836 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
837 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
838 .Times(1);
839 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
840 renderer.DrawFrame(&render_passes_in_draw_order_,
841 1.f,
842 viewport_rect,
843 viewport_rect,
844 false);
845 Mock::VerifyAndClearExpectations(context);
848 class VisibilityChangeIsLastCallTrackingContext
849 : public TestWebGraphicsContext3D {
850 public:
851 VisibilityChangeIsLastCallTrackingContext()
852 : last_call_was_set_visibility_(false) {}
854 // TestWebGraphicsContext3D methods.
855 void flush() override { last_call_was_set_visibility_ = false; }
856 void deleteTexture(GLuint) override { last_call_was_set_visibility_ = false; }
857 void deleteFramebuffer(GLuint) override {
858 last_call_was_set_visibility_ = false;
860 void deleteQueryEXT(GLuint) override {
861 last_call_was_set_visibility_ = false;
863 void deleteRenderbuffer(GLuint) override {
864 last_call_was_set_visibility_ = false;
867 // Methods added for test.
868 void set_last_call_was_visibility(bool visible) {
869 DCHECK(last_call_was_set_visibility_ == false);
870 last_call_was_set_visibility_ = true;
872 bool last_call_was_set_visibility() const {
873 return last_call_was_set_visibility_;
876 private:
877 bool last_call_was_set_visibility_;
880 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
881 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
882 new VisibilityChangeIsLastCallTrackingContext);
883 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
885 scoped_refptr<TestContextProvider> provider =
886 TestContextProvider::Create(context_owned.Pass());
888 provider->support()->SetSurfaceVisibleCallback(base::Bind(
889 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
890 base::Unretained(context)));
892 FakeOutputSurfaceClient output_surface_client;
893 scoped_ptr<OutputSurface> output_surface(
894 FakeOutputSurface::Create3d(provider));
895 CHECK(output_surface->BindToClient(&output_surface_client));
897 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
898 new TestSharedBitmapManager());
899 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
900 output_surface.get(), shared_bitmap_manager.get());
902 RendererSettings settings;
903 FakeRendererClient renderer_client;
904 FakeRendererGL renderer(&renderer_client,
905 &settings,
906 output_surface.get(),
907 resource_provider.get());
909 gfx::Rect viewport_rect(1, 1);
910 AddRenderPass(&render_passes_in_draw_order_,
911 RenderPassId(1, 0),
912 viewport_rect,
913 gfx::Transform());
915 // Ensure that the call to SetSurfaceVisible is the last call issue to the
916 // GPU process, after glFlush is called, and after the RendererClient's
917 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
918 // RenderClient and the Context by giving them both a pointer to a variable on
919 // the stack.
920 renderer.SetVisible(true);
921 renderer.DrawFrame(&render_passes_in_draw_order_,
922 1.f,
923 viewport_rect,
924 viewport_rect,
925 false);
926 renderer.SetVisible(false);
927 EXPECT_TRUE(context->last_call_was_set_visibility());
930 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
931 public:
932 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
933 test_capabilities_.gpu.egl_image_external = true;
936 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
937 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
938 MOCK_METHOD4(drawElements,
939 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
941 virtual void activeTexture(GLenum texture) {
942 EXPECT_NE(texture, active_texture_);
943 active_texture_ = texture;
946 GLenum active_texture() const { return active_texture_; }
948 private:
949 GLenum active_texture_;
952 TEST_F(GLRendererTest, ActiveTextureState) {
953 scoped_ptr<TextureStateTrackingContext> context_owned(
954 new TextureStateTrackingContext);
955 TextureStateTrackingContext* context = context_owned.get();
957 FakeOutputSurfaceClient output_surface_client;
958 scoped_ptr<OutputSurface> output_surface(
959 FakeOutputSurface::Create3d(context_owned.Pass()));
960 CHECK(output_surface->BindToClient(&output_surface_client));
962 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
963 new TestSharedBitmapManager());
964 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
965 output_surface.get(), shared_bitmap_manager.get());
967 RendererSettings settings;
968 FakeRendererClient renderer_client;
969 FakeRendererGL renderer(&renderer_client,
970 &settings,
971 output_surface.get(),
972 resource_provider.get());
974 // During initialization we are allowed to set any texture parameters.
975 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
977 TestRenderPass* root_pass =
978 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 1),
979 gfx::Rect(100, 100), gfx::Transform());
980 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
981 RenderPassId(0, 0));
983 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
985 // Set up expected texture filter state transitions that match the quads
986 // created in AppendOneOfEveryQuadType().
987 Mock::VerifyAndClearExpectations(context);
989 InSequence sequence;
991 // The sync points for all quads are waited on first. This sync point is
992 // for a texture quad drawn later in the frame.
993 EXPECT_CALL(*context,
994 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
995 .Times(1);
997 // yuv_quad is drawn with the default linear filter.
998 EXPECT_CALL(*context, drawElements(_, _, _, _));
1000 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1001 // scaled.
1002 EXPECT_CALL(
1003 *context,
1004 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1005 EXPECT_CALL(
1006 *context,
1007 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1008 EXPECT_CALL(*context, drawElements(_, _, _, _));
1010 // transformed_tile_quad uses GL_LINEAR.
1011 EXPECT_CALL(*context, drawElements(_, _, _, _));
1013 // scaled_tile_quad also uses GL_LINEAR.
1014 EXPECT_CALL(*context, drawElements(_, _, _, _));
1016 // The remaining quads also use GL_LINEAR because nearest neighbor
1017 // filtering is currently only used with tile quads.
1018 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(7);
1021 gfx::Rect viewport_rect(100, 100);
1022 renderer.DrawFrame(&render_passes_in_draw_order_,
1023 1.f,
1024 viewport_rect,
1025 viewport_rect,
1026 false);
1027 Mock::VerifyAndClearExpectations(context);
1030 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
1031 public:
1032 MOCK_METHOD1(clear, void(GLbitfield mask));
1033 MOCK_METHOD4(drawElements,
1034 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1037 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
1038 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
1039 new NoClearRootRenderPassMockContext);
1040 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
1042 FakeOutputSurfaceClient output_surface_client;
1043 scoped_ptr<OutputSurface> output_surface(
1044 FakeOutputSurface::Create3d(mock_context_owned.Pass()));
1045 CHECK(output_surface->BindToClient(&output_surface_client));
1047 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1048 new TestSharedBitmapManager());
1049 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1050 output_surface.get(), shared_bitmap_manager.get());
1052 RendererSettings settings;
1053 settings.should_clear_root_render_pass = false;
1055 FakeRendererClient renderer_client;
1056 FakeRendererGL renderer(&renderer_client,
1057 &settings,
1058 output_surface.get(),
1059 resource_provider.get());
1061 gfx::Rect viewport_rect(10, 10);
1063 RenderPassId child_pass_id(2, 0);
1064 TestRenderPass* child_pass =
1065 AddRenderPass(&render_passes_in_draw_order_, child_pass_id, viewport_rect,
1066 gfx::Transform());
1067 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
1069 RenderPassId root_pass_id(1, 0);
1070 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1071 root_pass_id,
1072 viewport_rect,
1073 gfx::Transform());
1074 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1077 AddRenderPassQuad(root_pass, child_pass);
1079 #ifdef NDEBUG
1080 GLint clear_bits = GL_COLOR_BUFFER_BIT;
1081 #else
1082 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1083 #endif
1085 // First render pass is not the root one, clearing should happen.
1086 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
1088 Expectation first_render_pass =
1089 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
1091 // The second render pass is the root one, clearing should be prevented.
1092 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
1093 first_render_pass);
1095 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
1096 first_render_pass);
1098 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1099 renderer.DrawFrame(&render_passes_in_draw_order_,
1100 1.f,
1101 viewport_rect,
1102 viewport_rect,
1103 false);
1105 // In multiple render passes all but the root pass should clear the
1106 // framebuffer.
1107 Mock::VerifyAndClearExpectations(&mock_context);
1110 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
1111 public:
1112 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1114 void clear(GLbitfield) override { EXPECT_FALSE(scissor_enabled_); }
1116 void enable(GLenum cap) override {
1117 if (cap == GL_SCISSOR_TEST)
1118 scissor_enabled_ = true;
1121 void disable(GLenum cap) override {
1122 if (cap == GL_SCISSOR_TEST)
1123 scissor_enabled_ = false;
1126 private:
1127 bool scissor_enabled_;
1130 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
1131 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
1132 new ScissorTestOnClearCheckingContext);
1134 FakeOutputSurfaceClient output_surface_client;
1135 scoped_ptr<OutputSurface> output_surface(
1136 FakeOutputSurface::Create3d(context_owned.Pass()));
1137 CHECK(output_surface->BindToClient(&output_surface_client));
1139 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1140 new TestSharedBitmapManager());
1141 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1142 output_surface.get(), shared_bitmap_manager.get());
1144 RendererSettings settings;
1145 FakeRendererClient renderer_client;
1146 FakeRendererGL renderer(&renderer_client,
1147 &settings,
1148 output_surface.get(),
1149 resource_provider.get());
1150 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1152 gfx::Rect viewport_rect(1, 1);
1154 gfx::Rect grand_child_rect(25, 25);
1155 RenderPassId grand_child_pass_id(3, 0);
1156 TestRenderPass* grand_child_pass =
1157 AddRenderPass(&render_passes_in_draw_order_,
1158 grand_child_pass_id,
1159 grand_child_rect,
1160 gfx::Transform());
1161 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
1163 gfx::Rect child_rect(50, 50);
1164 RenderPassId child_pass_id(2, 0);
1165 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
1166 child_pass_id,
1167 child_rect,
1168 gfx::Transform());
1169 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1171 RenderPassId root_pass_id(1, 0);
1172 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1173 root_pass_id,
1174 viewport_rect,
1175 gfx::Transform());
1176 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1178 AddRenderPassQuad(root_pass, child_pass);
1179 AddRenderPassQuad(child_pass, grand_child_pass);
1181 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1182 renderer.DrawFrame(&render_passes_in_draw_order_,
1183 1.f,
1184 viewport_rect,
1185 viewport_rect,
1186 false);
1189 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1190 public:
1191 DiscardCheckingContext() : discarded_(0) {
1192 set_have_post_sub_buffer(true);
1193 set_have_discard_framebuffer(true);
1196 void discardFramebufferEXT(GLenum target,
1197 GLsizei numAttachments,
1198 const GLenum* attachments) override {
1199 ++discarded_;
1202 int discarded() const { return discarded_; }
1203 void reset() { discarded_ = 0; }
1205 private:
1206 int discarded_;
1209 class NonReshapableOutputSurface : public FakeOutputSurface {
1210 public:
1211 explicit NonReshapableOutputSurface(
1212 scoped_ptr<TestWebGraphicsContext3D> context3d)
1213 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1214 false) {
1215 surface_size_ = gfx::Size(500, 500);
1217 void Reshape(const gfx::Size& size, float scale_factor) override {}
1218 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1221 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1222 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1223 DiscardCheckingContext* context = context_owned.get();
1225 FakeOutputSurfaceClient output_surface_client;
1226 scoped_ptr<NonReshapableOutputSurface> output_surface(
1227 new NonReshapableOutputSurface(context_owned.Pass()));
1228 CHECK(output_surface->BindToClient(&output_surface_client));
1229 output_surface->set_fixed_size(gfx::Size(100, 100));
1231 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1232 new TestSharedBitmapManager());
1233 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1234 output_surface.get(), shared_bitmap_manager.get());
1236 RendererSettings settings;
1237 settings.partial_swap_enabled = true;
1238 FakeRendererClient renderer_client;
1239 FakeRendererGL renderer(&renderer_client,
1240 &settings,
1241 output_surface.get(),
1242 resource_provider.get());
1243 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1245 gfx::Rect viewport_rect(100, 100);
1246 gfx::Rect clip_rect(100, 100);
1249 // Partial frame, should not discard.
1250 RenderPassId root_pass_id(1, 0);
1251 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1252 root_pass_id,
1253 viewport_rect,
1254 gfx::Transform());
1255 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1256 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1258 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1259 renderer.DrawFrame(&render_passes_in_draw_order_,
1260 1.f,
1261 viewport_rect,
1262 clip_rect,
1263 false);
1264 EXPECT_EQ(0, context->discarded());
1265 context->reset();
1268 // Full frame, should discard.
1269 RenderPassId root_pass_id(1, 0);
1270 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1271 root_pass_id,
1272 viewport_rect,
1273 gfx::Transform());
1274 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1275 root_pass->damage_rect = root_pass->output_rect;
1277 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1278 renderer.DrawFrame(&render_passes_in_draw_order_,
1279 1.f,
1280 viewport_rect,
1281 clip_rect,
1282 false);
1283 EXPECT_EQ(1, context->discarded());
1284 context->reset();
1287 // Full frame, external scissor is set, should not discard.
1288 output_surface->set_has_external_stencil_test(true);
1289 RenderPassId root_pass_id(1, 0);
1290 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1291 root_pass_id,
1292 viewport_rect,
1293 gfx::Transform());
1294 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1295 root_pass->damage_rect = root_pass->output_rect;
1296 root_pass->has_transparent_background = false;
1298 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1299 renderer.DrawFrame(&render_passes_in_draw_order_,
1300 1.f,
1301 viewport_rect,
1302 clip_rect,
1303 false);
1304 EXPECT_EQ(0, context->discarded());
1305 context->reset();
1306 output_surface->set_has_external_stencil_test(false);
1309 // Full frame, clipped, should not discard.
1310 clip_rect = gfx::Rect(10, 10, 10, 10);
1311 RenderPassId root_pass_id(1, 0);
1312 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1313 root_pass_id,
1314 viewport_rect,
1315 gfx::Transform());
1316 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1317 root_pass->damage_rect = root_pass->output_rect;
1319 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1320 renderer.DrawFrame(&render_passes_in_draw_order_,
1321 1.f,
1322 viewport_rect,
1323 clip_rect,
1324 false);
1325 EXPECT_EQ(0, context->discarded());
1326 context->reset();
1329 // Full frame, doesn't cover the surface, should not discard.
1330 viewport_rect = gfx::Rect(10, 10, 10, 10);
1331 RenderPassId root_pass_id(1, 0);
1332 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1333 root_pass_id,
1334 viewport_rect,
1335 gfx::Transform());
1336 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1337 root_pass->damage_rect = root_pass->output_rect;
1339 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1340 renderer.DrawFrame(&render_passes_in_draw_order_,
1341 1.f,
1342 viewport_rect,
1343 clip_rect,
1344 false);
1345 EXPECT_EQ(0, context->discarded());
1346 context->reset();
1349 // Full frame, doesn't cover the surface (no offset), should not discard.
1350 clip_rect = gfx::Rect(100, 100);
1351 viewport_rect = gfx::Rect(50, 50);
1352 RenderPassId root_pass_id(1, 0);
1353 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1354 root_pass_id,
1355 viewport_rect,
1356 gfx::Transform());
1357 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1358 root_pass->damage_rect = root_pass->output_rect;
1360 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1361 renderer.DrawFrame(&render_passes_in_draw_order_,
1362 1.f,
1363 viewport_rect,
1364 clip_rect,
1365 false);
1366 EXPECT_EQ(0, context->discarded());
1367 context->reset();
1371 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1372 public:
1373 MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
1374 MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
1377 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1378 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1379 // and maintains a fixed size. This test verifies that glViewport and
1380 // glScissor's Y coordinate is flipped correctly in this environment, and that
1381 // the glViewport can be at a nonzero origin within the surface.
1382 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1383 new FlippedScissorAndViewportContext);
1385 // We expect exactly one call to viewport on this context and exactly two
1386 // to scissor (one to scissor the clear, one to scissor the quad draw).
1387 EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100));
1388 EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100));
1389 EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20));
1391 FakeOutputSurfaceClient output_surface_client;
1392 scoped_ptr<OutputSurface> output_surface(
1393 new NonReshapableOutputSurface(context_owned.Pass()));
1394 CHECK(output_surface->BindToClient(&output_surface_client));
1396 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1397 new TestSharedBitmapManager());
1398 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1399 output_surface.get(), shared_bitmap_manager.get());
1401 RendererSettings settings;
1402 FakeRendererClient renderer_client;
1403 FakeRendererGL renderer(&renderer_client,
1404 &settings,
1405 output_surface.get(),
1406 resource_provider.get());
1407 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1409 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1410 gfx::Rect viewport_rect(device_viewport_rect.size());
1411 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1413 RenderPassId root_pass_id(1, 0);
1414 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1415 root_pass_id,
1416 viewport_rect,
1417 gfx::Transform());
1418 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1420 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1421 renderer.DrawFrame(&render_passes_in_draw_order_,
1422 1.f,
1423 device_viewport_rect,
1424 device_viewport_rect,
1425 false);
1428 TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
1429 // When using render-to-FBO to display the surface, all rendering is done
1430 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1431 // the correct framebuffer during rendering, if changed.
1432 // Note: there is one path that will set it to 0, but that is after the render
1433 // has finished.
1434 FakeOutputSurfaceClient output_surface_client;
1435 scoped_ptr<FakeOutputSurface> output_surface(
1436 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1437 CHECK(output_surface->BindToClient(&output_surface_client));
1439 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1440 new TestSharedBitmapManager());
1441 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1442 output_surface.get(), shared_bitmap_manager.get());
1444 RendererSettings settings;
1445 FakeRendererClient renderer_client;
1446 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
1447 resource_provider.get());
1448 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1450 gfx::Rect device_viewport_rect(0, 0, 100, 100);
1451 gfx::Rect viewport_rect(device_viewport_rect.size());
1452 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1454 RenderPassId root_pass_id(1, 0);
1455 TestRenderPass* root_pass =
1456 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1457 gfx::Transform());
1458 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1460 unsigned fbo;
1461 gpu::gles2::GLES2Interface* gl =
1462 output_surface->context_provider()->ContextGL();
1463 gl->GenFramebuffers(1, &fbo);
1464 output_surface->set_framebuffer(fbo);
1466 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1467 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect,
1468 device_viewport_rect, false);
1470 int bound_fbo;
1471 gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
1472 EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
1475 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1476 gfx::Rect viewport_rect(1, 1);
1478 gfx::Rect child_rect(50, 50);
1479 RenderPassId child_pass_id(2, 0);
1480 TestRenderPass* child_pass;
1482 RenderPassId root_pass_id(1, 0);
1483 TestRenderPass* root_pass;
1485 ResourceId mask = resource_provider_->CreateResource(
1486 gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
1487 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
1488 resource_provider_->best_texture_format());
1489 resource_provider_->AllocateForTesting(mask);
1491 SkScalar matrix[20];
1492 float amount = 0.5f;
1493 matrix[0] = 0.213f + 0.787f * amount;
1494 matrix[1] = 0.715f - 0.715f * amount;
1495 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1496 matrix[3] = matrix[4] = 0;
1497 matrix[5] = 0.213f - 0.213f * amount;
1498 matrix[6] = 0.715f + 0.285f * amount;
1499 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1500 matrix[8] = matrix[9] = 0;
1501 matrix[10] = 0.213f - 0.213f * amount;
1502 matrix[11] = 0.715f - 0.715f * amount;
1503 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1504 matrix[13] = matrix[14] = 0;
1505 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1506 matrix[18] = 1;
1507 skia::RefPtr<SkColorFilter> color_filter(
1508 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1509 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1510 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1511 FilterOperations filters;
1512 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1514 gfx::Transform transform_causing_aa;
1515 transform_causing_aa.Rotate(20.0);
1517 for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
1518 BlendMode blend_mode = static_cast<BlendMode>(i);
1519 SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
1520 settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
1521 // RenderPassProgram
1522 render_passes_in_draw_order_.clear();
1523 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1524 child_pass_id,
1525 child_rect,
1526 gfx::Transform());
1528 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1529 root_pass_id,
1530 viewport_rect,
1531 gfx::Transform());
1533 AddRenderPassQuad(root_pass,
1534 child_pass,
1536 FilterOperations(),
1537 gfx::Transform(),
1538 xfer_mode);
1540 renderer_->DecideRenderPassAllocationsForFrame(
1541 render_passes_in_draw_order_);
1542 renderer_->DrawFrame(&render_passes_in_draw_order_,
1543 1.f,
1544 viewport_rect,
1545 viewport_rect,
1546 false);
1547 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1549 // RenderPassColorMatrixProgram
1550 render_passes_in_draw_order_.clear();
1552 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1553 child_pass_id,
1554 child_rect,
1555 transform_causing_aa);
1557 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1558 root_pass_id,
1559 viewport_rect,
1560 gfx::Transform());
1562 AddRenderPassQuad(
1563 root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
1565 renderer_->DecideRenderPassAllocationsForFrame(
1566 render_passes_in_draw_order_);
1567 renderer_->DrawFrame(&render_passes_in_draw_order_,
1568 1.f,
1569 viewport_rect,
1570 viewport_rect,
1571 false);
1572 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1574 // RenderPassMaskProgram
1575 render_passes_in_draw_order_.clear();
1577 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1578 child_pass_id,
1579 child_rect,
1580 gfx::Transform());
1582 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1583 root_pass_id,
1584 viewport_rect,
1585 gfx::Transform());
1587 AddRenderPassQuad(root_pass,
1588 child_pass,
1589 mask,
1590 FilterOperations(),
1591 gfx::Transform(),
1592 xfer_mode);
1594 renderer_->DecideRenderPassAllocationsForFrame(
1595 render_passes_in_draw_order_);
1596 renderer_->DrawFrame(&render_passes_in_draw_order_,
1597 1.f,
1598 viewport_rect,
1599 viewport_rect,
1600 false);
1601 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1602 blend_mode);
1604 // RenderPassMaskColorMatrixProgram
1605 render_passes_in_draw_order_.clear();
1607 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1608 child_pass_id,
1609 child_rect,
1610 gfx::Transform());
1612 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1613 root_pass_id,
1614 viewport_rect,
1615 gfx::Transform());
1617 AddRenderPassQuad(
1618 root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
1620 renderer_->DecideRenderPassAllocationsForFrame(
1621 render_passes_in_draw_order_);
1622 renderer_->DrawFrame(&render_passes_in_draw_order_,
1623 1.f,
1624 viewport_rect,
1625 viewport_rect,
1626 false);
1627 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
1628 SAMPLER_TYPE_2D, blend_mode);
1630 // RenderPassProgramAA
1631 render_passes_in_draw_order_.clear();
1633 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1634 child_pass_id,
1635 child_rect,
1636 transform_causing_aa);
1638 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1639 root_pass_id,
1640 viewport_rect,
1641 gfx::Transform());
1643 AddRenderPassQuad(root_pass,
1644 child_pass,
1646 FilterOperations(),
1647 transform_causing_aa,
1648 xfer_mode);
1650 renderer_->DecideRenderPassAllocationsForFrame(
1651 render_passes_in_draw_order_);
1652 renderer_->DrawFrame(&render_passes_in_draw_order_,
1653 1.f,
1654 viewport_rect,
1655 viewport_rect,
1656 false);
1657 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1659 // RenderPassColorMatrixProgramAA
1660 render_passes_in_draw_order_.clear();
1662 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1663 child_pass_id,
1664 child_rect,
1665 transform_causing_aa);
1667 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1668 root_pass_id,
1669 viewport_rect,
1670 gfx::Transform());
1672 AddRenderPassQuad(
1673 root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
1675 renderer_->DecideRenderPassAllocationsForFrame(
1676 render_passes_in_draw_order_);
1677 renderer_->DrawFrame(&render_passes_in_draw_order_,
1678 1.f,
1679 viewport_rect,
1680 viewport_rect,
1681 false);
1682 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1684 // RenderPassMaskProgramAA
1685 render_passes_in_draw_order_.clear();
1687 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1688 child_pass_id,
1689 child_rect,
1690 transform_causing_aa);
1692 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1693 root_pass_id,
1694 viewport_rect,
1695 gfx::Transform());
1697 AddRenderPassQuad(root_pass,
1698 child_pass,
1699 mask,
1700 FilterOperations(),
1701 transform_causing_aa,
1702 xfer_mode);
1704 renderer_->DecideRenderPassAllocationsForFrame(
1705 render_passes_in_draw_order_);
1706 renderer_->DrawFrame(&render_passes_in_draw_order_,
1707 1.f,
1708 viewport_rect,
1709 viewport_rect,
1710 false);
1711 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1712 blend_mode);
1714 // RenderPassMaskColorMatrixProgramAA
1715 render_passes_in_draw_order_.clear();
1717 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1718 child_pass_id,
1719 child_rect,
1720 transform_causing_aa);
1722 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1723 root_pass_id,
1724 viewport_rect,
1725 transform_causing_aa);
1727 AddRenderPassQuad(
1728 root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
1730 renderer_->DecideRenderPassAllocationsForFrame(
1731 render_passes_in_draw_order_);
1732 renderer_->DrawFrame(&render_passes_in_draw_order_,
1733 1.f,
1734 viewport_rect,
1735 viewport_rect,
1736 false);
1737 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
1738 SAMPLER_TYPE_2D, blend_mode);
1742 // At this time, the AA code path cannot be taken if the surface's rect would
1743 // project incorrectly by the given transform, because of w<0 clipping.
1744 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1745 gfx::Rect child_rect(50, 50);
1746 RenderPassId child_pass_id(2, 0);
1747 TestRenderPass* child_pass;
1749 gfx::Rect viewport_rect(1, 1);
1750 RenderPassId root_pass_id(1, 0);
1751 TestRenderPass* root_pass;
1753 gfx::Transform transform_preventing_aa;
1754 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1755 transform_preventing_aa.RotateAboutYAxis(-20.0);
1756 transform_preventing_aa.Scale(30.0, 1.0);
1758 // Verify that the test transform and test rect actually do cause the clipped
1759 // flag to trigger. Otherwise we are not testing the intended scenario.
1760 bool clipped = false;
1761 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1762 ASSERT_TRUE(clipped);
1764 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1765 child_pass_id,
1766 child_rect,
1767 transform_preventing_aa);
1769 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1770 root_pass_id,
1771 viewport_rect,
1772 gfx::Transform());
1774 AddRenderPassQuad(root_pass,
1775 child_pass,
1777 FilterOperations(),
1778 transform_preventing_aa,
1779 SkXfermode::kSrcOver_Mode);
1781 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1782 renderer_->DrawFrame(&render_passes_in_draw_order_,
1783 1.f,
1784 viewport_rect,
1785 viewport_rect,
1786 false);
1788 // If use_aa incorrectly ignores clipping, it will use the
1789 // RenderPassProgramAA shader instead of the RenderPassProgram.
1790 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
1793 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1794 gfx::Rect viewport_rect(1, 1);
1795 RenderPassId root_pass_id(1, 0);
1796 TestRenderPass* root_pass;
1798 gfx::Transform pixel_aligned_transform_causing_aa;
1799 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1800 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1802 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1803 root_pass_id,
1804 viewport_rect,
1805 gfx::Transform());
1806 AddTransformedQuad(root_pass,
1807 viewport_rect,
1808 SK_ColorYELLOW,
1809 pixel_aligned_transform_causing_aa);
1811 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1812 renderer_->DrawFrame(&render_passes_in_draw_order_,
1813 1.f,
1814 viewport_rect,
1815 viewport_rect,
1816 false);
1818 TestSolidColorProgramAA();
1821 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1822 public:
1823 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1825 // Specifically override methods even if they are unused (used in conjunction
1826 // with StrictMock). We need to make sure that GLRenderer does not issue
1827 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1828 // through the OutputSurface abstraction.
1829 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1830 MOCK_METHOD3(reshapeWithScaleFactor,
1831 void(int width, int height, float scale_factor));
1832 MOCK_METHOD4(drawElements,
1833 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1836 class MockOutputSurface : public OutputSurface {
1837 public:
1838 MockOutputSurface()
1839 : OutputSurface(
1840 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1841 new StrictMock<OutputSurfaceMockContext>))) {
1842 surface_size_ = gfx::Size(100, 100);
1844 virtual ~MockOutputSurface() {}
1846 MOCK_METHOD0(EnsureBackbuffer, void());
1847 MOCK_METHOD0(DiscardBackbuffer, void());
1848 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1849 MOCK_METHOD0(BindFramebuffer, void());
1850 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1853 class MockOutputSurfaceTest : public GLRendererTest {
1854 protected:
1855 virtual void SetUp() {
1856 FakeOutputSurfaceClient output_surface_client_;
1857 CHECK(output_surface_.BindToClient(&output_surface_client_));
1859 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1860 resource_provider_ = FakeResourceProvider::Create(
1861 &output_surface_, shared_bitmap_manager_.get());
1863 renderer_.reset(new FakeRendererGL(&renderer_client_,
1864 &settings_,
1865 &output_surface_,
1866 resource_provider_.get()));
1869 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1871 void DrawFrame(float device_scale_factor,
1872 const gfx::Rect& device_viewport_rect) {
1873 RenderPassId render_pass_id(1, 0);
1874 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1875 render_pass_id,
1876 device_viewport_rect,
1877 gfx::Transform());
1878 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1880 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1882 EXPECT_CALL(output_surface_,
1883 Reshape(device_viewport_rect.size(), device_scale_factor))
1884 .Times(1);
1886 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1888 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1890 renderer_->DecideRenderPassAllocationsForFrame(
1891 render_passes_in_draw_order_);
1892 renderer_->DrawFrame(&render_passes_in_draw_order_,
1893 device_scale_factor,
1894 device_viewport_rect,
1895 device_viewport_rect,
1896 false);
1899 OutputSurfaceMockContext* Context() {
1900 return static_cast<OutputSurfaceMockContext*>(
1901 static_cast<TestContextProvider*>(output_surface_.context_provider())
1902 ->TestContext3d());
1905 RendererSettings settings_;
1906 FakeOutputSurfaceClient output_surface_client_;
1907 StrictMock<MockOutputSurface> output_surface_;
1908 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1909 scoped_ptr<ResourceProvider> resource_provider_;
1910 FakeRendererClient renderer_client_;
1911 scoped_ptr<FakeRendererGL> renderer_;
1914 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1915 gfx::Rect device_viewport_rect(1, 1);
1916 DrawFrame(1.f, device_viewport_rect);
1918 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1919 renderer_->SwapBuffers(CompositorFrameMetadata());
1922 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1923 gfx::Rect device_viewport_rect(1, 1);
1925 DrawFrame(1.f, device_viewport_rect);
1926 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1927 renderer_->SwapBuffers(CompositorFrameMetadata());
1929 device_viewport_rect = gfx::Rect(2, 2);
1931 DrawFrame(2.f, device_viewport_rect);
1932 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1933 renderer_->SwapBuffers(CompositorFrameMetadata());
1935 DrawFrame(2.f, device_viewport_rect);
1936 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1937 renderer_->SwapBuffers(CompositorFrameMetadata());
1939 device_viewport_rect = gfx::Rect(1, 1);
1941 DrawFrame(1.f, device_viewport_rect);
1942 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1943 renderer_->SwapBuffers(CompositorFrameMetadata());
1946 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1947 protected:
1948 static void SyncPointCallback(int* callback_count) {
1949 ++(*callback_count);
1950 base::MessageLoop::current()->QuitWhenIdle();
1953 static void OtherCallback(int* callback_count) {
1954 ++(*callback_count);
1955 base::MessageLoop::current()->QuitWhenIdle();
1959 #if !defined(OS_ANDROID)
1960 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1961 int sync_point_callback_count = 0;
1962 int other_callback_count = 0;
1963 gpu::gles2::GLES2Interface* gl =
1964 output_surface_->context_provider()->ContextGL();
1965 gpu::ContextSupport* context_support =
1966 output_surface_->context_provider()->ContextSupport();
1968 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1970 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1971 GL_INNOCENT_CONTEXT_RESET_ARB);
1973 context_support->SignalSyncPoint(
1974 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1975 EXPECT_EQ(0, sync_point_callback_count);
1976 EXPECT_EQ(0, other_callback_count);
1978 // Make the sync point happen.
1979 gl->Finish();
1980 // Post a task after the sync point.
1981 base::ThreadTaskRunnerHandle::Get()->PostTask(
1982 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1984 base::MessageLoop::current()->Run();
1986 // The sync point shouldn't have happened since the context was lost.
1987 EXPECT_EQ(0, sync_point_callback_count);
1988 EXPECT_EQ(1, other_callback_count);
1991 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1992 int sync_point_callback_count = 0;
1993 int other_callback_count = 0;
1995 gpu::gles2::GLES2Interface* gl =
1996 output_surface_->context_provider()->ContextGL();
1997 gpu::ContextSupport* context_support =
1998 output_surface_->context_provider()->ContextSupport();
2000 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
2002 context_support->SignalSyncPoint(
2003 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
2004 EXPECT_EQ(0, sync_point_callback_count);
2005 EXPECT_EQ(0, other_callback_count);
2007 // Make the sync point happen.
2008 gl->Finish();
2009 // Post a task after the sync point.
2010 base::ThreadTaskRunnerHandle::Get()->PostTask(
2011 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
2013 base::MessageLoop::current()->Run();
2015 // The sync point should have happened.
2016 EXPECT_EQ(1, sync_point_callback_count);
2017 EXPECT_EQ(1, other_callback_count);
2019 #endif // OS_ANDROID
2021 class TestOverlayProcessor : public OverlayProcessor {
2022 public:
2023 class Strategy : public OverlayProcessor::Strategy {
2024 public:
2025 Strategy() {}
2026 ~Strategy() override {}
2027 MOCK_METHOD2(Attempt,
2028 bool(RenderPassList* render_passes_in_draw_order,
2029 OverlayCandidateList* candidates));
2032 TestOverlayProcessor(OutputSurface* surface,
2033 ResourceProvider* resource_provider)
2034 : OverlayProcessor(surface, resource_provider) {}
2035 ~TestOverlayProcessor() override {}
2036 void Initialize() override {
2037 strategy_ = new Strategy();
2038 strategies_.push_back(scoped_ptr<OverlayProcessor::Strategy>(strategy_));
2041 Strategy* strategy_;
2044 void MailboxReleased(unsigned sync_point,
2045 bool lost_resource,
2046 BlockingTaskRunner* main_thread_task_runner) {
2049 void IgnoreCopyResult(scoped_ptr<CopyOutputResult> result) {
2052 TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
2053 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
2054 FakeOutputSurfaceClient output_surface_client;
2055 scoped_ptr<OutputSurface> output_surface(
2056 FakeOutputSurface::Create3d(context_owned.Pass()));
2057 CHECK(output_surface->BindToClient(&output_surface_client));
2059 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2060 new TestSharedBitmapManager());
2061 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2062 output_surface.get(), shared_bitmap_manager.get());
2063 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2064 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2066 RendererSettings settings;
2067 FakeRendererClient renderer_client;
2068 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2069 resource_provider.get(), mailbox_deleter.get());
2071 TestOverlayProcessor* processor =
2072 new TestOverlayProcessor(output_surface.get(), resource_provider.get());
2073 processor->Initialize();
2074 renderer.SetOverlayProcessor(processor);
2076 gfx::Rect viewport_rect(1, 1);
2077 TestRenderPass* root_pass =
2078 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2079 viewport_rect, gfx::Transform());
2080 root_pass->has_transparent_background = false;
2081 root_pass->copy_requests.push_back(
2082 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult)));
2084 unsigned sync_point = 0;
2085 TextureMailbox mailbox =
2086 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2087 mailbox.set_allow_overlay(true);
2088 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2089 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2090 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2091 mailbox, release_callback.Pass());
2092 bool premultiplied_alpha = false;
2093 bool flipped = false;
2094 bool nearest_neighbor = false;
2095 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2097 TextureDrawQuad* overlay_quad =
2098 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2099 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2100 viewport_rect, viewport_rect, viewport_rect, resource_id,
2101 premultiplied_alpha, gfx::PointF(0, 0),
2102 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2103 flipped, nearest_neighbor);
2105 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2106 // Attempt will be called for each strategy in OverlayProcessor. We have
2107 // added a fake strategy, so checking for Attempt calls checks if there was
2108 // any attempt to overlay, which there shouldn't be. We can't use the quad
2109 // list because the render pass is cleaned up by DrawFrame.
2110 EXPECT_CALL(*processor->strategy_, Attempt(_, _)).Times(0);
2111 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2112 viewport_rect, false);
2113 Mock::VerifyAndClearExpectations(processor->strategy_);
2115 // Without a copy request Attempt() should be called once.
2116 root_pass = AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2117 viewport_rect, gfx::Transform());
2118 root_pass->has_transparent_background = false;
2120 overlay_quad = root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2121 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2122 viewport_rect, viewport_rect, viewport_rect, resource_id,
2123 premultiplied_alpha, gfx::PointF(0, 0),
2124 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2125 flipped, nearest_neighbor);
2127 EXPECT_CALL(*processor->strategy_, Attempt(_, _)).Times(1);
2128 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2129 viewport_rect, false);
2132 class SingleOverlayOnTopProcessor : public OverlayProcessor {
2133 public:
2134 class SingleOverlayValidator : public OverlayCandidateValidator {
2135 public:
2136 void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
2137 ASSERT_EQ(2U, surfaces->size());
2138 OverlayCandidate& candidate = surfaces->back();
2139 candidate.overlay_handled = true;
2143 SingleOverlayOnTopProcessor(OutputSurface* surface,
2144 ResourceProvider* resource_provider)
2145 : OverlayProcessor(surface, resource_provider) {}
2147 void Initialize() override {
2148 strategies_.push_back(scoped_ptr<Strategy>(
2149 new OverlayStrategySingleOnTop(&validator_, resource_provider_)));
2152 SingleOverlayValidator validator_;
2155 class WaitSyncPointCountingContext : public TestWebGraphicsContext3D {
2156 public:
2157 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
2160 class MockOverlayScheduler {
2161 public:
2162 MOCK_METHOD5(Schedule,
2163 void(int plane_z_order,
2164 gfx::OverlayTransform plane_transform,
2165 unsigned overlay_texture_id,
2166 const gfx::Rect& display_bounds,
2167 const gfx::RectF& uv_rect));
2170 TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
2171 scoped_ptr<WaitSyncPointCountingContext> context_owned(
2172 new WaitSyncPointCountingContext);
2173 WaitSyncPointCountingContext* context = context_owned.get();
2175 MockOverlayScheduler overlay_scheduler;
2176 scoped_refptr<TestContextProvider> context_provider =
2177 TestContextProvider::Create(context_owned.Pass());
2178 context_provider->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2179 &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler)));
2181 FakeOutputSurfaceClient output_surface_client;
2182 scoped_ptr<OutputSurface> output_surface(
2183 FakeOutputSurface::Create3d(context_provider));
2184 CHECK(output_surface->BindToClient(&output_surface_client));
2186 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2187 new TestSharedBitmapManager());
2188 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2189 output_surface.get(), shared_bitmap_manager.get());
2190 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2191 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2193 RendererSettings settings;
2194 FakeRendererClient renderer_client;
2195 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2196 resource_provider.get(), mailbox_deleter.get());
2198 SingleOverlayOnTopProcessor* processor = new SingleOverlayOnTopProcessor(
2199 output_surface.get(), resource_provider.get());
2200 processor->Initialize();
2201 renderer.SetOverlayProcessor(processor);
2203 gfx::Rect viewport_rect(1, 1);
2204 TestRenderPass* root_pass =
2205 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2206 viewport_rect, gfx::Transform());
2207 root_pass->has_transparent_background = false;
2209 unsigned sync_point = TestRenderPass::kSyncPointForMailboxTextureQuad;
2210 TextureMailbox mailbox =
2211 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2212 mailbox.set_allow_overlay(true);
2213 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2214 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2215 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2216 mailbox, release_callback.Pass());
2217 bool premultiplied_alpha = false;
2218 bool flipped = false;
2219 bool nearest_neighbor = false;
2220 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2221 gfx::PointF uv_top_left(0, 0);
2222 gfx::PointF uv_bottom_right(1, 1);
2224 TextureDrawQuad* overlay_quad =
2225 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2226 SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
2227 shared_state->SetAll(gfx::Transform(), viewport_rect.size(), viewport_rect,
2228 viewport_rect, false, 1, SkXfermode::kSrcOver_Mode, 0);
2229 overlay_quad->SetNew(shared_state, viewport_rect, viewport_rect,
2230 viewport_rect, resource_id, premultiplied_alpha,
2231 uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT,
2232 vertex_opacity, flipped, nearest_neighbor);
2234 // Verify that overlay_quad actually gets turned into an overlay, and even
2235 // though it's not drawn, that its sync point is waited on.
2236 EXPECT_CALL(*context,
2237 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
2238 .Times(1);
2239 EXPECT_CALL(overlay_scheduler,
2240 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, viewport_rect,
2241 BoundingRect(uv_top_left, uv_bottom_right))).Times(1);
2243 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2244 viewport_rect, false);
2247 } // namespace
2248 } // namespace cc