Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / cc / output / gl_renderer_unittest.cc
blobbd6eeb9f03152b82167cbaf869edd4549091be65
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/overlay_strategy_underlay.h"
18 #include "cc/output/texture_mailbox_deleter.h"
19 #include "cc/quads/texture_draw_quad.h"
20 #include "cc/resources/resource_provider.h"
21 #include "cc/test/fake_impl_proxy.h"
22 #include "cc/test/fake_layer_tree_host_impl.h"
23 #include "cc/test/fake_output_surface.h"
24 #include "cc/test/fake_output_surface_client.h"
25 #include "cc/test/fake_renderer_client.h"
26 #include "cc/test/fake_resource_provider.h"
27 #include "cc/test/pixel_test.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()->GetDebugBorderProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
122 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
125 void TestShadersWithPrecision(TexCoordPrecision precision) {
126 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
127 if (renderer()->Capabilities().using_egl_image)
128 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
129 else
130 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
133 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision,
134 BlendMode blend_mode) {
135 EXPECT_PROGRAM_VALID(
136 renderer()->GetRenderPassProgram(precision, blend_mode));
137 EXPECT_PROGRAM_VALID(
138 renderer()->GetRenderPassProgramAA(precision, blend_mode));
141 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision,
142 SamplerType sampler) {
143 if (!renderer()->Capabilities().using_egl_image &&
144 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
145 // This will likely be hit in tests due to usage of osmesa.
146 return;
149 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision, sampler));
150 EXPECT_PROGRAM_VALID(
151 renderer()->GetNonPremultipliedTextureProgram(precision, sampler));
152 EXPECT_PROGRAM_VALID(
153 renderer()->GetTextureBackgroundProgram(precision, sampler));
154 EXPECT_PROGRAM_VALID(
155 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision,
156 sampler));
158 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
160 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
161 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
162 EXPECT_PROGRAM_VALID(
163 renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
164 EXPECT_PROGRAM_VALID(
165 renderer()->GetTileProgramSwizzleAA(precision, sampler));
166 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision, sampler));
167 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision, sampler));
170 void TestShadersWithMasks(TexCoordPrecision precision,
171 SamplerType sampler,
172 BlendMode blend_mode,
173 bool mask_for_background) {
174 if (!renderer()->Capabilities().using_egl_image &&
175 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
176 // This will likely be hit in tests due to usage of osmesa.
177 return;
180 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
181 precision, sampler, blend_mode, mask_for_background));
182 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
183 precision, sampler, blend_mode, mask_for_background));
184 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
185 precision, sampler, blend_mode, mask_for_background));
186 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
187 precision, sampler, blend_mode, mask_for_background));
191 namespace {
193 #if !defined(OS_ANDROID) && !defined(OS_WIN)
194 static const TexCoordPrecision kPrecisionList[] = {TEX_COORD_PRECISION_MEDIUM,
195 TEX_COORD_PRECISION_HIGH};
197 static const BlendMode kBlendModeList[LAST_BLEND_MODE + 1] = {
198 BLEND_MODE_NONE,
199 BLEND_MODE_NORMAL,
200 BLEND_MODE_SCREEN,
201 BLEND_MODE_OVERLAY,
202 BLEND_MODE_DARKEN,
203 BLEND_MODE_LIGHTEN,
204 BLEND_MODE_COLOR_DODGE,
205 BLEND_MODE_COLOR_BURN,
206 BLEND_MODE_HARD_LIGHT,
207 BLEND_MODE_SOFT_LIGHT,
208 BLEND_MODE_DIFFERENCE,
209 BLEND_MODE_EXCLUSION,
210 BLEND_MODE_MULTIPLY,
211 BLEND_MODE_HUE,
212 BLEND_MODE_SATURATION,
213 BLEND_MODE_COLOR,
214 BLEND_MODE_LUMINOSITY,
217 static const SamplerType kSamplerList[] = {
218 SAMPLER_TYPE_2D,
219 SAMPLER_TYPE_2D_RECT,
220 SAMPLER_TYPE_EXTERNAL_OES,
223 TEST_F(GLRendererShaderPixelTest, BasicShadersCompile) {
224 TestBasicShaders();
227 class PrecisionShaderPixelTest
228 : public GLRendererShaderPixelTest,
229 public ::testing::WithParamInterface<TexCoordPrecision> {};
231 TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
232 TestShadersWithPrecision(GetParam());
235 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile,
236 PrecisionShaderPixelTest,
237 ::testing::ValuesIn(kPrecisionList));
239 class PrecisionBlendShaderPixelTest
240 : public GLRendererShaderPixelTest,
241 public ::testing::WithParamInterface<
242 std::tr1::tuple<TexCoordPrecision, BlendMode>> {};
244 TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
245 TestShadersWithPrecisionAndBlend(std::tr1::get<0>(GetParam()),
246 std::tr1::get<1>(GetParam()));
249 INSTANTIATE_TEST_CASE_P(
250 PrecisionBlendShadersCompile,
251 PrecisionBlendShaderPixelTest,
252 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
253 ::testing::ValuesIn(kBlendModeList)));
255 class PrecisionSamplerShaderPixelTest
256 : public GLRendererShaderPixelTest,
257 public ::testing::WithParamInterface<
258 std::tr1::tuple<TexCoordPrecision, SamplerType>> {};
260 TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
261 TestShadersWithPrecisionAndSampler(std::tr1::get<0>(GetParam()),
262 std::tr1::get<1>(GetParam()));
265 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile,
266 PrecisionSamplerShaderPixelTest,
267 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
268 ::testing::ValuesIn(kSamplerList)));
270 class MaskShaderPixelTest
271 : public GLRendererShaderPixelTest,
272 public ::testing::WithParamInterface<
273 std::tr1::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {};
275 TEST_P(MaskShaderPixelTest, ShadersCompile) {
276 TestShadersWithMasks(
277 std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
278 std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam()));
281 INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
282 MaskShaderPixelTest,
283 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
284 ::testing::ValuesIn(kSamplerList),
285 ::testing::ValuesIn(kBlendModeList),
286 ::testing::Bool()));
288 #endif
290 class FakeRendererGL : public GLRenderer {
291 public:
292 FakeRendererGL(RendererClient* client,
293 const RendererSettings* settings,
294 OutputSurface* output_surface,
295 ResourceProvider* resource_provider)
296 : GLRenderer(client,
297 settings,
298 output_surface,
299 resource_provider,
300 NULL,
301 0) {}
303 FakeRendererGL(RendererClient* client,
304 const RendererSettings* settings,
305 OutputSurface* output_surface,
306 ResourceProvider* resource_provider,
307 TextureMailboxDeleter* texture_mailbox_deleter)
308 : GLRenderer(client,
309 settings,
310 output_surface,
311 resource_provider,
312 texture_mailbox_deleter,
313 0) {}
315 void SetOverlayProcessor(OverlayProcessor* processor) {
316 overlay_processor_.reset(processor);
319 // GLRenderer methods.
321 // Changing visibility to public.
322 using GLRenderer::IsBackbufferDiscarded;
323 using GLRenderer::DoDrawQuad;
324 using GLRenderer::BeginDrawingFrame;
325 using GLRenderer::FinishDrawingQuadList;
326 using GLRenderer::stencil_enabled;
329 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
330 protected:
331 GLRendererWithDefaultHarnessTest() {
332 output_surface_ =
333 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
334 CHECK(output_surface_->BindToClient(&output_surface_client_));
336 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
337 resource_provider_ = FakeResourceProvider::Create(
338 output_surface_.get(), shared_bitmap_manager_.get());
339 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
340 &settings_,
341 output_surface_.get(),
342 resource_provider_.get()));
345 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
347 RendererSettings settings_;
348 FakeOutputSurfaceClient output_surface_client_;
349 scoped_ptr<FakeOutputSurface> output_surface_;
350 FakeRendererClient renderer_client_;
351 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
352 scoped_ptr<ResourceProvider> resource_provider_;
353 scoped_ptr<FakeRendererGL> renderer_;
356 // Closing the namespace here so that GLRendererShaderTest can take advantage
357 // of the friend relationship with GLRenderer and all of the mock classes
358 // declared above it.
359 } // namespace
361 class GLRendererShaderTest : public GLRendererTest {
362 protected:
363 GLRendererShaderTest() {
364 output_surface_ = FakeOutputSurface::Create3d().Pass();
365 CHECK(output_surface_->BindToClient(&output_surface_client_));
367 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
368 resource_provider_ = FakeResourceProvider::Create(
369 output_surface_.get(), shared_bitmap_manager_.get());
370 renderer_.reset(new FakeRendererGL(&renderer_client_,
371 &settings_,
372 output_surface_.get(),
373 resource_provider_.get()));
376 void TestRenderPassProgram(TexCoordPrecision precision,
377 BlendMode blend_mode) {
378 EXPECT_PROGRAM_VALID(
379 &renderer_->render_pass_program_[precision][blend_mode]);
380 EXPECT_EQ(renderer_->render_pass_program_[precision][blend_mode].program(),
381 renderer_->program_shadow_);
384 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
385 BlendMode blend_mode) {
386 EXPECT_PROGRAM_VALID(
387 &renderer_->render_pass_color_matrix_program_[precision][blend_mode]);
388 EXPECT_EQ(
389 renderer_->render_pass_color_matrix_program_[precision][blend_mode]
390 .program(),
391 renderer_->program_shadow_);
394 void TestRenderPassMaskProgram(TexCoordPrecision precision,
395 SamplerType sampler,
396 BlendMode blend_mode) {
397 EXPECT_PROGRAM_VALID(
398 &renderer_->render_pass_mask_program_[precision]
399 [sampler]
400 [blend_mode]
401 [NO_MASK]);
402 EXPECT_EQ(
403 renderer_->render_pass_mask_program_[precision]
404 [sampler]
405 [blend_mode]
406 [NO_MASK].program(),
407 renderer_->program_shadow_);
410 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
411 SamplerType sampler,
412 BlendMode blend_mode) {
413 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_
414 [precision][sampler][blend_mode][NO_MASK]);
415 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_
416 [precision][sampler][blend_mode][NO_MASK].program(),
417 renderer_->program_shadow_);
420 void TestRenderPassProgramAA(TexCoordPrecision precision,
421 BlendMode blend_mode) {
422 EXPECT_PROGRAM_VALID(
423 &renderer_->render_pass_program_aa_[precision][blend_mode]);
424 EXPECT_EQ(
425 renderer_->render_pass_program_aa_[precision][blend_mode].program(),
426 renderer_->program_shadow_);
429 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
430 BlendMode blend_mode) {
431 EXPECT_PROGRAM_VALID(
432 &renderer_
433 ->render_pass_color_matrix_program_aa_[precision][blend_mode]);
434 EXPECT_EQ(
435 renderer_->render_pass_color_matrix_program_aa_[precision][blend_mode]
436 .program(),
437 renderer_->program_shadow_);
440 void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
441 SamplerType sampler,
442 BlendMode blend_mode) {
443 EXPECT_PROGRAM_VALID(
444 &renderer_
445 ->render_pass_mask_program_aa_
446 [precision][sampler][blend_mode][NO_MASK]);
447 EXPECT_EQ(
448 renderer_->render_pass_mask_program_aa_[precision][sampler][blend_mode]
449 [NO_MASK].program(),
450 renderer_->program_shadow_);
453 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
454 SamplerType sampler,
455 BlendMode blend_mode) {
456 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_aa_
457 [precision][sampler][blend_mode][NO_MASK]);
458 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_
459 [precision][sampler][blend_mode][NO_MASK].program(),
460 renderer_->program_shadow_);
463 void TestSolidColorProgramAA() {
464 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
465 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
466 renderer_->program_shadow_);
469 RendererSettings settings_;
470 FakeOutputSurfaceClient output_surface_client_;
471 scoped_ptr<FakeOutputSurface> output_surface_;
472 FakeRendererClient renderer_client_;
473 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
474 scoped_ptr<ResourceProvider> resource_provider_;
475 scoped_ptr<FakeRendererGL> renderer_;
478 namespace {
480 // Test GLRenderer DiscardBackbuffer functionality:
481 // Suggest discarding framebuffer when one exists and the renderer is not
482 // visible.
483 // Expected: it is discarded and damage tracker is reset.
484 TEST_F(
485 GLRendererWithDefaultHarnessTest,
486 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
487 renderer_->SetVisible(false);
488 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
489 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
492 // Test GLRenderer DiscardBackbuffer functionality:
493 // Suggest discarding framebuffer when one exists and the renderer is visible.
494 // Expected: the allocation is ignored.
495 TEST_F(GLRendererWithDefaultHarnessTest,
496 SuggestBackbufferNoDoNothingWhenVisible) {
497 renderer_->SetVisible(true);
498 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
499 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
502 // Test GLRenderer DiscardBackbuffer functionality:
503 // Suggest discarding framebuffer when one does not exist.
504 // Expected: it does nothing.
505 TEST_F(GLRendererWithDefaultHarnessTest,
506 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
507 renderer_->SetVisible(false);
508 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
509 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
511 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
512 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
515 // Test GLRenderer DiscardBackbuffer functionality:
516 // Begin drawing a frame while a framebuffer is discarded.
517 // Expected: will recreate framebuffer.
518 TEST_F(GLRendererWithDefaultHarnessTest,
519 DiscardedBackbufferIsRecreatedForScopeDuration) {
520 gfx::Rect viewport_rect(1, 1);
521 renderer_->SetVisible(false);
522 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
523 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
525 AddRenderPass(&render_passes_in_draw_order_,
526 RenderPassId(1, 0),
527 viewport_rect,
528 gfx::Transform());
530 renderer_->SetVisible(true);
531 renderer_->DrawFrame(&render_passes_in_draw_order_,
532 1.f,
533 viewport_rect,
534 viewport_rect,
535 false);
536 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
538 SwapBuffers();
539 EXPECT_EQ(1u, output_surface_->num_sent_frames());
542 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
543 gfx::Rect viewport_rect(1, 1);
544 EXPECT_FALSE(renderer_->stencil_enabled());
546 output_surface_->set_has_external_stencil_test(true);
548 RenderPass* root_pass =
549 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
550 viewport_rect, gfx::Transform());
551 root_pass->has_transparent_background = false;
553 renderer_->DrawFrame(&render_passes_in_draw_order_,
554 1.f,
555 viewport_rect,
556 viewport_rect,
557 false);
558 EXPECT_TRUE(renderer_->stencil_enabled());
561 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
562 public:
563 ForbidSynchronousCallContext() {}
565 void getAttachedShaders(GLuint program,
566 GLsizei max_count,
567 GLsizei* count,
568 GLuint* shaders) override {
569 ADD_FAILURE();
571 GLint getAttribLocation(GLuint program, const GLchar* name) override {
572 ADD_FAILURE();
573 return 0;
575 void getBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
576 void getBufferParameteriv(GLenum target,
577 GLenum pname,
578 GLint* value) override {
579 ADD_FAILURE();
581 GLenum getError() override {
582 ADD_FAILURE();
583 return GL_NO_ERROR;
585 void getFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
586 void getFramebufferAttachmentParameteriv(GLenum target,
587 GLenum attachment,
588 GLenum pname,
589 GLint* value) override {
590 ADD_FAILURE();
592 void getIntegerv(GLenum pname, GLint* value) override {
593 if (pname == GL_MAX_TEXTURE_SIZE) {
594 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
595 *value = 1024;
596 } else {
597 ADD_FAILURE();
601 // We allow querying the shader compilation and program link status in debug
602 // mode, but not release.
603 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
604 #ifndef NDEBUG
605 *value = 1;
606 #else
607 ADD_FAILURE();
608 #endif
611 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
612 #ifndef NDEBUG
613 *value = 1;
614 #else
615 ADD_FAILURE();
616 #endif
619 void getRenderbufferParameteriv(GLenum target,
620 GLenum pname,
621 GLint* value) override {
622 ADD_FAILURE();
625 void getShaderPrecisionFormat(GLenum shadertype,
626 GLenum precisiontype,
627 GLint* range,
628 GLint* precision) override {
629 ADD_FAILURE();
631 void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
632 ADD_FAILURE();
634 void getTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
635 ADD_FAILURE();
637 void getUniformfv(GLuint program, GLint location, GLfloat* value) override {
638 ADD_FAILURE();
640 void getUniformiv(GLuint program, GLint location, GLint* value) override {
641 ADD_FAILURE();
643 GLint getUniformLocation(GLuint program, const GLchar* name) override {
644 ADD_FAILURE();
645 return 0;
647 void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
648 ADD_FAILURE();
650 void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
651 ADD_FAILURE();
653 GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname) override {
654 ADD_FAILURE();
655 return 0;
658 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
659 FakeOutputSurfaceClient output_surface_client;
660 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
661 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
662 CHECK(output_surface->BindToClient(&output_surface_client));
664 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
665 new TestSharedBitmapManager());
666 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
667 output_surface.get(), shared_bitmap_manager.get());
669 RendererSettings settings;
670 FakeRendererClient renderer_client;
671 FakeRendererGL renderer(&renderer_client,
672 &settings,
673 output_surface.get(),
674 resource_provider.get());
677 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
678 public:
679 LoseContextOnFirstGetContext() {}
681 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
682 context_lost_ = true;
683 *value = 0;
686 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
687 context_lost_ = true;
688 *value = 0;
692 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
693 FakeOutputSurfaceClient output_surface_client;
694 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
695 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
696 CHECK(output_surface->BindToClient(&output_surface_client));
698 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
699 new TestSharedBitmapManager());
700 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
701 output_surface.get(), shared_bitmap_manager.get());
703 RendererSettings settings;
704 FakeRendererClient renderer_client;
705 FakeRendererGL renderer(&renderer_client,
706 &settings,
707 output_surface.get(),
708 resource_provider.get());
711 class ClearCountingContext : public TestWebGraphicsContext3D {
712 public:
713 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
715 MOCK_METHOD3(discardFramebufferEXT,
716 void(GLenum target,
717 GLsizei numAttachments,
718 const GLenum* attachments));
719 MOCK_METHOD1(clear, void(GLbitfield mask));
722 TEST_F(GLRendererTest, OpaqueBackground) {
723 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
724 ClearCountingContext* context = context_owned.get();
726 FakeOutputSurfaceClient output_surface_client;
727 scoped_ptr<OutputSurface> output_surface(
728 FakeOutputSurface::Create3d(context_owned.Pass()));
729 CHECK(output_surface->BindToClient(&output_surface_client));
731 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
732 new TestSharedBitmapManager());
733 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
734 output_surface.get(), shared_bitmap_manager.get());
736 RendererSettings settings;
737 FakeRendererClient renderer_client;
738 FakeRendererGL renderer(&renderer_client,
739 &settings,
740 output_surface.get(),
741 resource_provider.get());
743 gfx::Rect viewport_rect(1, 1);
744 RenderPass* root_pass =
745 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
746 viewport_rect, gfx::Transform());
747 root_pass->has_transparent_background = false;
749 // On DEBUG builds, render passes with opaque background clear to blue to
750 // easily see regions that were not drawn on the screen.
751 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
752 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
753 .Times(1);
754 #ifdef NDEBUG
755 EXPECT_CALL(*context, clear(_)).Times(0);
756 #else
757 EXPECT_CALL(*context, clear(_)).Times(1);
758 #endif
759 renderer.DrawFrame(&render_passes_in_draw_order_,
760 1.f,
761 viewport_rect,
762 viewport_rect,
763 false);
764 Mock::VerifyAndClearExpectations(context);
767 TEST_F(GLRendererTest, TransparentBackground) {
768 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
769 ClearCountingContext* context = context_owned.get();
771 FakeOutputSurfaceClient output_surface_client;
772 scoped_ptr<OutputSurface> output_surface(
773 FakeOutputSurface::Create3d(context_owned.Pass()));
774 CHECK(output_surface->BindToClient(&output_surface_client));
776 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
777 new TestSharedBitmapManager());
778 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
779 output_surface.get(), shared_bitmap_manager.get());
781 RendererSettings settings;
782 FakeRendererClient renderer_client;
783 FakeRendererGL renderer(&renderer_client,
784 &settings,
785 output_surface.get(),
786 resource_provider.get());
788 gfx::Rect viewport_rect(1, 1);
789 RenderPass* root_pass =
790 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
791 viewport_rect, gfx::Transform());
792 root_pass->has_transparent_background = true;
794 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
795 EXPECT_CALL(*context, clear(_)).Times(1);
796 renderer.DrawFrame(&render_passes_in_draw_order_,
797 1.f,
798 viewport_rect,
799 viewport_rect,
800 false);
802 Mock::VerifyAndClearExpectations(context);
805 TEST_F(GLRendererTest, OffscreenOutputSurface) {
806 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
807 ClearCountingContext* context = context_owned.get();
809 FakeOutputSurfaceClient output_surface_client;
810 scoped_ptr<OutputSurface> output_surface(
811 FakeOutputSurface::CreateOffscreen(context_owned.Pass()));
812 CHECK(output_surface->BindToClient(&output_surface_client));
814 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
815 new TestSharedBitmapManager());
816 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
817 output_surface.get(), shared_bitmap_manager.get());
819 RendererSettings settings;
820 FakeRendererClient renderer_client;
821 FakeRendererGL renderer(&renderer_client,
822 &settings,
823 output_surface.get(),
824 resource_provider.get());
826 gfx::Rect viewport_rect(1, 1);
827 AddRenderPass(&render_passes_in_draw_order_,
828 RenderPassId(1, 0),
829 viewport_rect,
830 gfx::Transform());
832 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
833 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
834 .Times(1);
835 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
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 VisibilityChangeIsLastCallTrackingContext
845 : public TestWebGraphicsContext3D {
846 public:
847 VisibilityChangeIsLastCallTrackingContext()
848 : last_call_was_set_visibility_(false) {}
850 // TestWebGraphicsContext3D methods.
851 void flush() override { last_call_was_set_visibility_ = false; }
852 void deleteTexture(GLuint) override { last_call_was_set_visibility_ = false; }
853 void deleteFramebuffer(GLuint) override {
854 last_call_was_set_visibility_ = false;
856 void deleteQueryEXT(GLuint) override {
857 last_call_was_set_visibility_ = false;
859 void deleteRenderbuffer(GLuint) override {
860 last_call_was_set_visibility_ = false;
863 // Methods added for test.
864 void set_last_call_was_visibility(bool visible) {
865 DCHECK(last_call_was_set_visibility_ == false);
866 last_call_was_set_visibility_ = true;
868 bool last_call_was_set_visibility() const {
869 return last_call_was_set_visibility_;
872 private:
873 bool last_call_was_set_visibility_;
876 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
877 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
878 new VisibilityChangeIsLastCallTrackingContext);
879 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
881 scoped_refptr<TestContextProvider> provider =
882 TestContextProvider::Create(context_owned.Pass());
884 provider->support()->SetSurfaceVisibleCallback(base::Bind(
885 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
886 base::Unretained(context)));
888 FakeOutputSurfaceClient output_surface_client;
889 scoped_ptr<OutputSurface> output_surface(
890 FakeOutputSurface::Create3d(provider));
891 CHECK(output_surface->BindToClient(&output_surface_client));
893 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
894 new TestSharedBitmapManager());
895 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
896 output_surface.get(), shared_bitmap_manager.get());
898 RendererSettings settings;
899 FakeRendererClient renderer_client;
900 FakeRendererGL renderer(&renderer_client,
901 &settings,
902 output_surface.get(),
903 resource_provider.get());
905 gfx::Rect viewport_rect(1, 1);
906 AddRenderPass(&render_passes_in_draw_order_,
907 RenderPassId(1, 0),
908 viewport_rect,
909 gfx::Transform());
911 // Ensure that the call to SetSurfaceVisible is the last call issue to the
912 // GPU process, after glFlush is called, and after the RendererClient's
913 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
914 // RenderClient and the Context by giving them both a pointer to a variable on
915 // the stack.
916 renderer.SetVisible(true);
917 renderer.DrawFrame(&render_passes_in_draw_order_,
918 1.f,
919 viewport_rect,
920 viewport_rect,
921 false);
922 renderer.SetVisible(false);
923 EXPECT_TRUE(context->last_call_was_set_visibility());
926 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
927 public:
928 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
929 test_capabilities_.gpu.egl_image_external = true;
932 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
933 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
934 MOCK_METHOD4(drawElements,
935 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
937 virtual void activeTexture(GLenum texture) {
938 EXPECT_NE(texture, active_texture_);
939 active_texture_ = texture;
942 GLenum active_texture() const { return active_texture_; }
944 private:
945 GLenum active_texture_;
948 TEST_F(GLRendererTest, ActiveTextureState) {
949 scoped_ptr<TextureStateTrackingContext> context_owned(
950 new TextureStateTrackingContext);
951 TextureStateTrackingContext* context = context_owned.get();
953 FakeOutputSurfaceClient output_surface_client;
954 scoped_ptr<OutputSurface> output_surface(
955 FakeOutputSurface::Create3d(context_owned.Pass()));
956 CHECK(output_surface->BindToClient(&output_surface_client));
958 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
959 new TestSharedBitmapManager());
960 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
961 output_surface.get(), shared_bitmap_manager.get());
963 RendererSettings settings;
964 FakeRendererClient renderer_client;
965 FakeRendererGL renderer(&renderer_client,
966 &settings,
967 output_surface.get(),
968 resource_provider.get());
970 // During initialization we are allowed to set any texture parameters.
971 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
973 RenderPass* root_pass =
974 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 1),
975 gfx::Rect(100, 100), gfx::Transform());
976 uint32_t mailbox_sync_point;
977 AddOneOfEveryQuadType(root_pass, resource_provider.get(), RenderPassId(0, 0),
978 &mailbox_sync_point);
980 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
982 // Set up expected texture filter state transitions that match the quads
983 // created in AppendOneOfEveryQuadType().
984 Mock::VerifyAndClearExpectations(context);
986 InSequence sequence;
988 // The sync points for all quads are waited on first. This sync point is
989 // for a texture quad drawn later in the frame.
990 EXPECT_CALL(*context, waitSyncPoint(mailbox_sync_point)).Times(1);
992 // yuv_quad is drawn with the default linear filter.
993 EXPECT_CALL(*context, drawElements(_, _, _, _));
995 // tile_quad is drawn with GL_NEAREST because it is not transformed or
996 // scaled.
997 EXPECT_CALL(
998 *context,
999 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1000 EXPECT_CALL(
1001 *context,
1002 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1003 EXPECT_CALL(*context, drawElements(_, _, _, _));
1005 // transformed_tile_quad uses GL_LINEAR.
1006 EXPECT_CALL(*context, drawElements(_, _, _, _));
1008 // scaled_tile_quad also uses GL_LINEAR.
1009 EXPECT_CALL(*context, drawElements(_, _, _, _));
1011 // The remaining quads also use GL_LINEAR because nearest neighbor
1012 // filtering is currently only used with tile quads.
1013 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6);
1016 gfx::Rect viewport_rect(100, 100);
1017 renderer.DrawFrame(&render_passes_in_draw_order_,
1018 1.f,
1019 viewport_rect,
1020 viewport_rect,
1021 false);
1022 Mock::VerifyAndClearExpectations(context);
1025 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
1026 public:
1027 MOCK_METHOD1(clear, void(GLbitfield mask));
1028 MOCK_METHOD4(drawElements,
1029 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1032 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
1033 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
1034 new NoClearRootRenderPassMockContext);
1035 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
1037 FakeOutputSurfaceClient output_surface_client;
1038 scoped_ptr<OutputSurface> output_surface(
1039 FakeOutputSurface::Create3d(mock_context_owned.Pass()));
1040 CHECK(output_surface->BindToClient(&output_surface_client));
1042 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1043 new TestSharedBitmapManager());
1044 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1045 output_surface.get(), shared_bitmap_manager.get());
1047 RendererSettings settings;
1048 settings.should_clear_root_render_pass = false;
1050 FakeRendererClient renderer_client;
1051 FakeRendererGL renderer(&renderer_client,
1052 &settings,
1053 output_surface.get(),
1054 resource_provider.get());
1056 gfx::Rect viewport_rect(10, 10);
1058 RenderPassId child_pass_id(2, 0);
1059 RenderPass* child_pass =
1060 AddRenderPass(&render_passes_in_draw_order_, child_pass_id, viewport_rect,
1061 gfx::Transform());
1062 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
1064 RenderPassId root_pass_id(1, 0);
1065 RenderPass* root_pass =
1066 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1067 gfx::Transform());
1068 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1071 AddRenderPassQuad(root_pass, child_pass);
1073 #ifdef NDEBUG
1074 GLint clear_bits = GL_COLOR_BUFFER_BIT;
1075 #else
1076 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1077 #endif
1079 // First render pass is not the root one, clearing should happen.
1080 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
1082 Expectation first_render_pass =
1083 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
1085 // The second render pass is the root one, clearing should be prevented.
1086 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
1087 first_render_pass);
1089 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
1090 first_render_pass);
1092 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1093 renderer.DrawFrame(&render_passes_in_draw_order_,
1094 1.f,
1095 viewport_rect,
1096 viewport_rect,
1097 false);
1099 // In multiple render passes all but the root pass should clear the
1100 // framebuffer.
1101 Mock::VerifyAndClearExpectations(&mock_context);
1104 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
1105 public:
1106 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1108 void clear(GLbitfield) override { EXPECT_FALSE(scissor_enabled_); }
1110 void enable(GLenum cap) override {
1111 if (cap == GL_SCISSOR_TEST)
1112 scissor_enabled_ = true;
1115 void disable(GLenum cap) override {
1116 if (cap == GL_SCISSOR_TEST)
1117 scissor_enabled_ = false;
1120 private:
1121 bool scissor_enabled_;
1124 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
1125 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
1126 new ScissorTestOnClearCheckingContext);
1128 FakeOutputSurfaceClient output_surface_client;
1129 scoped_ptr<OutputSurface> output_surface(
1130 FakeOutputSurface::Create3d(context_owned.Pass()));
1131 CHECK(output_surface->BindToClient(&output_surface_client));
1133 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1134 new TestSharedBitmapManager());
1135 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1136 output_surface.get(), shared_bitmap_manager.get());
1138 RendererSettings settings;
1139 FakeRendererClient renderer_client;
1140 FakeRendererGL renderer(&renderer_client,
1141 &settings,
1142 output_surface.get(),
1143 resource_provider.get());
1144 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1146 gfx::Rect viewport_rect(1, 1);
1148 gfx::Rect grand_child_rect(25, 25);
1149 RenderPassId grand_child_pass_id(3, 0);
1150 RenderPass* grand_child_pass =
1151 AddRenderPass(&render_passes_in_draw_order_, grand_child_pass_id,
1152 grand_child_rect, gfx::Transform());
1153 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
1155 gfx::Rect child_rect(50, 50);
1156 RenderPassId child_pass_id(2, 0);
1157 RenderPass* child_pass =
1158 AddRenderPass(&render_passes_in_draw_order_, child_pass_id, child_rect,
1159 gfx::Transform());
1160 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1162 RenderPassId root_pass_id(1, 0);
1163 RenderPass* root_pass =
1164 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1165 gfx::Transform());
1166 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1168 AddRenderPassQuad(root_pass, child_pass);
1169 AddRenderPassQuad(child_pass, grand_child_pass);
1171 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1172 renderer.DrawFrame(&render_passes_in_draw_order_,
1173 1.f,
1174 viewport_rect,
1175 viewport_rect,
1176 false);
1179 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1180 public:
1181 DiscardCheckingContext() : discarded_(0) {
1182 set_have_post_sub_buffer(true);
1183 set_have_discard_framebuffer(true);
1186 void discardFramebufferEXT(GLenum target,
1187 GLsizei numAttachments,
1188 const GLenum* attachments) override {
1189 ++discarded_;
1192 int discarded() const { return discarded_; }
1193 void reset() { discarded_ = 0; }
1195 private:
1196 int discarded_;
1199 class NonReshapableOutputSurface : public FakeOutputSurface {
1200 public:
1201 explicit NonReshapableOutputSurface(
1202 scoped_ptr<TestWebGraphicsContext3D> context3d)
1203 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1204 false) {
1205 surface_size_ = gfx::Size(500, 500);
1207 void Reshape(const gfx::Size& size, float scale_factor) override {}
1208 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1211 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1212 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1213 DiscardCheckingContext* context = context_owned.get();
1215 FakeOutputSurfaceClient output_surface_client;
1216 scoped_ptr<NonReshapableOutputSurface> output_surface(
1217 new NonReshapableOutputSurface(context_owned.Pass()));
1218 CHECK(output_surface->BindToClient(&output_surface_client));
1219 output_surface->set_fixed_size(gfx::Size(100, 100));
1221 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1222 new TestSharedBitmapManager());
1223 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1224 output_surface.get(), shared_bitmap_manager.get());
1226 RendererSettings settings;
1227 settings.partial_swap_enabled = true;
1228 FakeRendererClient renderer_client;
1229 FakeRendererGL renderer(&renderer_client,
1230 &settings,
1231 output_surface.get(),
1232 resource_provider.get());
1233 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1235 gfx::Rect viewport_rect(100, 100);
1236 gfx::Rect clip_rect(100, 100);
1239 // Partial frame, should not discard.
1240 RenderPassId root_pass_id(1, 0);
1241 RenderPass* root_pass =
1242 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1243 viewport_rect, gfx::Transform());
1244 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1245 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1247 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1248 renderer.DrawFrame(&render_passes_in_draw_order_,
1249 1.f,
1250 viewport_rect,
1251 clip_rect,
1252 false);
1253 EXPECT_EQ(0, context->discarded());
1254 context->reset();
1257 // Full frame, should discard.
1258 RenderPassId root_pass_id(1, 0);
1259 RenderPass* root_pass =
1260 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1261 viewport_rect, gfx::Transform());
1262 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1263 root_pass->damage_rect = root_pass->output_rect;
1265 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1266 renderer.DrawFrame(&render_passes_in_draw_order_,
1267 1.f,
1268 viewport_rect,
1269 clip_rect,
1270 false);
1271 EXPECT_EQ(1, context->discarded());
1272 context->reset();
1275 // Full frame, external scissor is set, should not discard.
1276 output_surface->set_has_external_stencil_test(true);
1277 RenderPassId root_pass_id(1, 0);
1278 RenderPass* root_pass =
1279 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1280 viewport_rect, gfx::Transform());
1281 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1282 root_pass->damage_rect = root_pass->output_rect;
1283 root_pass->has_transparent_background = false;
1285 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1286 renderer.DrawFrame(&render_passes_in_draw_order_,
1287 1.f,
1288 viewport_rect,
1289 clip_rect,
1290 false);
1291 EXPECT_EQ(0, context->discarded());
1292 context->reset();
1293 output_surface->set_has_external_stencil_test(false);
1296 // Full frame, clipped, should not discard.
1297 clip_rect = gfx::Rect(10, 10, 10, 10);
1298 RenderPassId root_pass_id(1, 0);
1299 RenderPass* root_pass =
1300 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1301 viewport_rect, gfx::Transform());
1302 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1303 root_pass->damage_rect = root_pass->output_rect;
1305 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1306 renderer.DrawFrame(&render_passes_in_draw_order_,
1307 1.f,
1308 viewport_rect,
1309 clip_rect,
1310 false);
1311 EXPECT_EQ(0, context->discarded());
1312 context->reset();
1315 // Full frame, doesn't cover the surface, should not discard.
1316 viewport_rect = gfx::Rect(10, 10, 10, 10);
1317 RenderPassId root_pass_id(1, 0);
1318 RenderPass* root_pass =
1319 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1320 viewport_rect, gfx::Transform());
1321 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1322 root_pass->damage_rect = root_pass->output_rect;
1324 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1325 renderer.DrawFrame(&render_passes_in_draw_order_,
1326 1.f,
1327 viewport_rect,
1328 clip_rect,
1329 false);
1330 EXPECT_EQ(0, context->discarded());
1331 context->reset();
1334 // Full frame, doesn't cover the surface (no offset), should not discard.
1335 clip_rect = gfx::Rect(100, 100);
1336 viewport_rect = gfx::Rect(50, 50);
1337 RenderPassId root_pass_id(1, 0);
1338 RenderPass* root_pass =
1339 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1340 viewport_rect, gfx::Transform());
1341 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1342 root_pass->damage_rect = root_pass->output_rect;
1344 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1345 renderer.DrawFrame(&render_passes_in_draw_order_,
1346 1.f,
1347 viewport_rect,
1348 clip_rect,
1349 false);
1350 EXPECT_EQ(0, context->discarded());
1351 context->reset();
1355 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1356 public:
1357 MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
1358 MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
1361 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1362 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1363 // and maintains a fixed size. This test verifies that glViewport and
1364 // glScissor's Y coordinate is flipped correctly in this environment, and that
1365 // the glViewport can be at a nonzero origin within the surface.
1366 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1367 new FlippedScissorAndViewportContext);
1369 // We expect exactly one call to viewport on this context and exactly two
1370 // to scissor (one to scissor the clear, one to scissor the quad draw).
1371 EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100));
1372 EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100));
1373 EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20));
1375 FakeOutputSurfaceClient output_surface_client;
1376 scoped_ptr<OutputSurface> output_surface(
1377 new NonReshapableOutputSurface(context_owned.Pass()));
1378 CHECK(output_surface->BindToClient(&output_surface_client));
1380 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1381 new TestSharedBitmapManager());
1382 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1383 output_surface.get(), shared_bitmap_manager.get());
1385 RendererSettings settings;
1386 FakeRendererClient renderer_client;
1387 FakeRendererGL renderer(&renderer_client,
1388 &settings,
1389 output_surface.get(),
1390 resource_provider.get());
1391 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1393 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1394 gfx::Rect viewport_rect(device_viewport_rect.size());
1395 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1397 RenderPassId root_pass_id(1, 0);
1398 RenderPass* root_pass =
1399 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1400 gfx::Transform());
1401 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1403 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1404 renderer.DrawFrame(&render_passes_in_draw_order_,
1405 1.f,
1406 device_viewport_rect,
1407 device_viewport_rect,
1408 false);
1411 TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
1412 // When using render-to-FBO to display the surface, all rendering is done
1413 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1414 // the correct framebuffer during rendering, if changed.
1415 // Note: there is one path that will set it to 0, but that is after the render
1416 // has finished.
1417 FakeOutputSurfaceClient output_surface_client;
1418 scoped_ptr<FakeOutputSurface> output_surface(
1419 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1420 CHECK(output_surface->BindToClient(&output_surface_client));
1422 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1423 new TestSharedBitmapManager());
1424 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1425 output_surface.get(), shared_bitmap_manager.get());
1427 RendererSettings settings;
1428 FakeRendererClient renderer_client;
1429 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
1430 resource_provider.get());
1431 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1433 gfx::Rect device_viewport_rect(0, 0, 100, 100);
1434 gfx::Rect viewport_rect(device_viewport_rect.size());
1435 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1437 RenderPassId root_pass_id(1, 0);
1438 RenderPass* root_pass =
1439 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1440 gfx::Transform());
1441 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1443 unsigned fbo;
1444 gpu::gles2::GLES2Interface* gl =
1445 output_surface->context_provider()->ContextGL();
1446 gl->GenFramebuffers(1, &fbo);
1447 output_surface->set_framebuffer(fbo);
1449 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1450 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect,
1451 device_viewport_rect, false);
1453 int bound_fbo;
1454 gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
1455 EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
1458 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1459 gfx::Rect viewport_rect(1, 1);
1461 gfx::Rect child_rect(50, 50);
1462 RenderPassId child_pass_id(2, 0);
1463 RenderPass* child_pass;
1465 RenderPassId root_pass_id(1, 0);
1466 RenderPass* root_pass;
1468 ResourceId mask = resource_provider_->CreateResource(
1469 gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
1470 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
1471 resource_provider_->best_texture_format());
1472 resource_provider_->AllocateForTesting(mask);
1474 SkScalar matrix[20];
1475 float amount = 0.5f;
1476 matrix[0] = 0.213f + 0.787f * amount;
1477 matrix[1] = 0.715f - 0.715f * amount;
1478 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1479 matrix[3] = matrix[4] = 0;
1480 matrix[5] = 0.213f - 0.213f * amount;
1481 matrix[6] = 0.715f + 0.285f * amount;
1482 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1483 matrix[8] = matrix[9] = 0;
1484 matrix[10] = 0.213f - 0.213f * amount;
1485 matrix[11] = 0.715f - 0.715f * amount;
1486 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1487 matrix[13] = matrix[14] = 0;
1488 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1489 matrix[18] = 1;
1490 skia::RefPtr<SkColorFilter> color_filter(
1491 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1492 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1493 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1494 FilterOperations filters;
1495 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1497 gfx::Transform transform_causing_aa;
1498 transform_causing_aa.Rotate(20.0);
1500 for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
1501 BlendMode blend_mode = static_cast<BlendMode>(i);
1502 SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
1503 settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
1504 // RenderPassProgram
1505 render_passes_in_draw_order_.clear();
1506 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1507 child_pass_id,
1508 child_rect,
1509 gfx::Transform());
1511 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1512 root_pass_id,
1513 viewport_rect,
1514 gfx::Transform());
1516 AddRenderPassQuad(root_pass,
1517 child_pass,
1519 FilterOperations(),
1520 gfx::Transform(),
1521 xfer_mode);
1523 renderer_->DecideRenderPassAllocationsForFrame(
1524 render_passes_in_draw_order_);
1525 renderer_->DrawFrame(&render_passes_in_draw_order_,
1526 1.f,
1527 viewport_rect,
1528 viewport_rect,
1529 false);
1530 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1532 // RenderPassColorMatrixProgram
1533 render_passes_in_draw_order_.clear();
1535 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1536 child_pass_id,
1537 child_rect,
1538 transform_causing_aa);
1540 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1541 root_pass_id,
1542 viewport_rect,
1543 gfx::Transform());
1545 AddRenderPassQuad(
1546 root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
1548 renderer_->DecideRenderPassAllocationsForFrame(
1549 render_passes_in_draw_order_);
1550 renderer_->DrawFrame(&render_passes_in_draw_order_,
1551 1.f,
1552 viewport_rect,
1553 viewport_rect,
1554 false);
1555 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1557 // RenderPassMaskProgram
1558 render_passes_in_draw_order_.clear();
1560 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1561 child_pass_id,
1562 child_rect,
1563 gfx::Transform());
1565 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1566 root_pass_id,
1567 viewport_rect,
1568 gfx::Transform());
1570 AddRenderPassQuad(root_pass,
1571 child_pass,
1572 mask,
1573 FilterOperations(),
1574 gfx::Transform(),
1575 xfer_mode);
1577 renderer_->DecideRenderPassAllocationsForFrame(
1578 render_passes_in_draw_order_);
1579 renderer_->DrawFrame(&render_passes_in_draw_order_,
1580 1.f,
1581 viewport_rect,
1582 viewport_rect,
1583 false);
1584 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1585 blend_mode);
1587 // RenderPassMaskColorMatrixProgram
1588 render_passes_in_draw_order_.clear();
1590 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1591 child_pass_id,
1592 child_rect,
1593 gfx::Transform());
1595 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1596 root_pass_id,
1597 viewport_rect,
1598 gfx::Transform());
1600 AddRenderPassQuad(
1601 root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
1603 renderer_->DecideRenderPassAllocationsForFrame(
1604 render_passes_in_draw_order_);
1605 renderer_->DrawFrame(&render_passes_in_draw_order_,
1606 1.f,
1607 viewport_rect,
1608 viewport_rect,
1609 false);
1610 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
1611 SAMPLER_TYPE_2D, blend_mode);
1613 // RenderPassProgramAA
1614 render_passes_in_draw_order_.clear();
1616 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1617 child_pass_id,
1618 child_rect,
1619 transform_causing_aa);
1621 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1622 root_pass_id,
1623 viewport_rect,
1624 gfx::Transform());
1626 AddRenderPassQuad(root_pass,
1627 child_pass,
1629 FilterOperations(),
1630 transform_causing_aa,
1631 xfer_mode);
1633 renderer_->DecideRenderPassAllocationsForFrame(
1634 render_passes_in_draw_order_);
1635 renderer_->DrawFrame(&render_passes_in_draw_order_,
1636 1.f,
1637 viewport_rect,
1638 viewport_rect,
1639 false);
1640 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1642 // RenderPassColorMatrixProgramAA
1643 render_passes_in_draw_order_.clear();
1645 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1646 child_pass_id,
1647 child_rect,
1648 transform_causing_aa);
1650 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1651 root_pass_id,
1652 viewport_rect,
1653 gfx::Transform());
1655 AddRenderPassQuad(
1656 root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
1658 renderer_->DecideRenderPassAllocationsForFrame(
1659 render_passes_in_draw_order_);
1660 renderer_->DrawFrame(&render_passes_in_draw_order_,
1661 1.f,
1662 viewport_rect,
1663 viewport_rect,
1664 false);
1665 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1667 // RenderPassMaskProgramAA
1668 render_passes_in_draw_order_.clear();
1670 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1671 child_pass_id,
1672 child_rect,
1673 transform_causing_aa);
1675 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1676 root_pass_id,
1677 viewport_rect,
1678 gfx::Transform());
1680 AddRenderPassQuad(root_pass,
1681 child_pass,
1682 mask,
1683 FilterOperations(),
1684 transform_causing_aa,
1685 xfer_mode);
1687 renderer_->DecideRenderPassAllocationsForFrame(
1688 render_passes_in_draw_order_);
1689 renderer_->DrawFrame(&render_passes_in_draw_order_,
1690 1.f,
1691 viewport_rect,
1692 viewport_rect,
1693 false);
1694 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1695 blend_mode);
1697 // RenderPassMaskColorMatrixProgramAA
1698 render_passes_in_draw_order_.clear();
1700 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1701 child_pass_id,
1702 child_rect,
1703 transform_causing_aa);
1705 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1706 root_pass_id,
1707 viewport_rect,
1708 transform_causing_aa);
1710 AddRenderPassQuad(
1711 root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
1713 renderer_->DecideRenderPassAllocationsForFrame(
1714 render_passes_in_draw_order_);
1715 renderer_->DrawFrame(&render_passes_in_draw_order_,
1716 1.f,
1717 viewport_rect,
1718 viewport_rect,
1719 false);
1720 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
1721 SAMPLER_TYPE_2D, blend_mode);
1725 // At this time, the AA code path cannot be taken if the surface's rect would
1726 // project incorrectly by the given transform, because of w<0 clipping.
1727 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1728 gfx::Rect child_rect(50, 50);
1729 RenderPassId child_pass_id(2, 0);
1730 RenderPass* child_pass;
1732 gfx::Rect viewport_rect(1, 1);
1733 RenderPassId root_pass_id(1, 0);
1734 RenderPass* root_pass;
1736 gfx::Transform transform_preventing_aa;
1737 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1738 transform_preventing_aa.RotateAboutYAxis(-20.0);
1739 transform_preventing_aa.Scale(30.0, 1.0);
1741 // Verify that the test transform and test rect actually do cause the clipped
1742 // flag to trigger. Otherwise we are not testing the intended scenario.
1743 bool clipped = false;
1744 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(gfx::RectF(child_rect)),
1745 &clipped);
1746 ASSERT_TRUE(clipped);
1748 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1749 child_pass_id,
1750 child_rect,
1751 transform_preventing_aa);
1753 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1754 root_pass_id,
1755 viewport_rect,
1756 gfx::Transform());
1758 AddRenderPassQuad(root_pass,
1759 child_pass,
1761 FilterOperations(),
1762 transform_preventing_aa,
1763 SkXfermode::kSrcOver_Mode);
1765 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1766 renderer_->DrawFrame(&render_passes_in_draw_order_,
1767 1.f,
1768 viewport_rect,
1769 viewport_rect,
1770 false);
1772 // If use_aa incorrectly ignores clipping, it will use the
1773 // RenderPassProgramAA shader instead of the RenderPassProgram.
1774 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
1777 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1778 gfx::Rect viewport_rect(1, 1);
1779 RenderPassId root_pass_id(1, 0);
1780 RenderPass* root_pass;
1782 gfx::Transform pixel_aligned_transform_causing_aa;
1783 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1784 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1786 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1787 root_pass_id,
1788 viewport_rect,
1789 gfx::Transform());
1790 AddTransformedQuad(root_pass,
1791 viewport_rect,
1792 SK_ColorYELLOW,
1793 pixel_aligned_transform_causing_aa);
1795 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1796 renderer_->DrawFrame(&render_passes_in_draw_order_,
1797 1.f,
1798 viewport_rect,
1799 viewport_rect,
1800 false);
1802 TestSolidColorProgramAA();
1805 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1806 public:
1807 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1809 // Specifically override methods even if they are unused (used in conjunction
1810 // with StrictMock). We need to make sure that GLRenderer does not issue
1811 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1812 // through the OutputSurface abstraction.
1813 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1814 MOCK_METHOD3(reshapeWithScaleFactor,
1815 void(int width, int height, float scale_factor));
1816 MOCK_METHOD4(drawElements,
1817 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1820 class MockOutputSurface : public OutputSurface {
1821 public:
1822 MockOutputSurface()
1823 : OutputSurface(
1824 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1825 new StrictMock<OutputSurfaceMockContext>))) {
1826 surface_size_ = gfx::Size(100, 100);
1828 virtual ~MockOutputSurface() {}
1830 MOCK_METHOD0(EnsureBackbuffer, void());
1831 MOCK_METHOD0(DiscardBackbuffer, void());
1832 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1833 MOCK_METHOD0(BindFramebuffer, void());
1834 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1837 class MockOutputSurfaceTest : public GLRendererTest {
1838 protected:
1839 virtual void SetUp() {
1840 FakeOutputSurfaceClient output_surface_client_;
1841 CHECK(output_surface_.BindToClient(&output_surface_client_));
1843 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1844 resource_provider_ = FakeResourceProvider::Create(
1845 &output_surface_, shared_bitmap_manager_.get());
1847 renderer_.reset(new FakeRendererGL(&renderer_client_,
1848 &settings_,
1849 &output_surface_,
1850 resource_provider_.get()));
1853 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1855 void DrawFrame(float device_scale_factor,
1856 const gfx::Rect& device_viewport_rect) {
1857 RenderPassId render_pass_id(1, 0);
1858 RenderPass* render_pass =
1859 AddRenderPass(&render_passes_in_draw_order_, render_pass_id,
1860 device_viewport_rect, gfx::Transform());
1861 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1863 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1865 EXPECT_CALL(output_surface_,
1866 Reshape(device_viewport_rect.size(), device_scale_factor))
1867 .Times(1);
1869 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1871 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1873 renderer_->DecideRenderPassAllocationsForFrame(
1874 render_passes_in_draw_order_);
1875 renderer_->DrawFrame(&render_passes_in_draw_order_,
1876 device_scale_factor,
1877 device_viewport_rect,
1878 device_viewport_rect,
1879 false);
1882 OutputSurfaceMockContext* Context() {
1883 return static_cast<OutputSurfaceMockContext*>(
1884 static_cast<TestContextProvider*>(output_surface_.context_provider())
1885 ->TestContext3d());
1888 RendererSettings settings_;
1889 FakeOutputSurfaceClient output_surface_client_;
1890 StrictMock<MockOutputSurface> output_surface_;
1891 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1892 scoped_ptr<ResourceProvider> resource_provider_;
1893 FakeRendererClient renderer_client_;
1894 scoped_ptr<FakeRendererGL> renderer_;
1897 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1898 gfx::Rect device_viewport_rect(1, 1);
1899 DrawFrame(1.f, device_viewport_rect);
1901 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1902 renderer_->SwapBuffers(CompositorFrameMetadata());
1905 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1906 gfx::Rect device_viewport_rect(1, 1);
1908 DrawFrame(1.f, device_viewport_rect);
1909 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1910 renderer_->SwapBuffers(CompositorFrameMetadata());
1912 device_viewport_rect = gfx::Rect(2, 2);
1914 DrawFrame(2.f, device_viewport_rect);
1915 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1916 renderer_->SwapBuffers(CompositorFrameMetadata());
1918 DrawFrame(2.f, device_viewport_rect);
1919 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1920 renderer_->SwapBuffers(CompositorFrameMetadata());
1922 device_viewport_rect = gfx::Rect(1, 1);
1924 DrawFrame(1.f, device_viewport_rect);
1925 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1926 renderer_->SwapBuffers(CompositorFrameMetadata());
1929 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1930 protected:
1931 static void SyncPointCallback(int* callback_count) {
1932 ++(*callback_count);
1933 base::MessageLoop::current()->QuitWhenIdle();
1936 static void OtherCallback(int* callback_count) {
1937 ++(*callback_count);
1938 base::MessageLoop::current()->QuitWhenIdle();
1942 #if !defined(OS_ANDROID)
1943 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1944 int sync_point_callback_count = 0;
1945 int other_callback_count = 0;
1946 gpu::gles2::GLES2Interface* gl =
1947 output_surface_->context_provider()->ContextGL();
1948 gpu::ContextSupport* context_support =
1949 output_surface_->context_provider()->ContextSupport();
1951 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1953 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1954 GL_INNOCENT_CONTEXT_RESET_ARB);
1956 context_support->SignalSyncPoint(
1957 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1958 EXPECT_EQ(0, sync_point_callback_count);
1959 EXPECT_EQ(0, other_callback_count);
1961 // Make the sync point happen.
1962 gl->Finish();
1963 // Post a task after the sync point.
1964 base::ThreadTaskRunnerHandle::Get()->PostTask(
1965 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1967 base::MessageLoop::current()->Run();
1969 // The sync point shouldn't have happened since the context was lost.
1970 EXPECT_EQ(0, sync_point_callback_count);
1971 EXPECT_EQ(1, other_callback_count);
1974 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1975 int sync_point_callback_count = 0;
1976 int other_callback_count = 0;
1978 gpu::gles2::GLES2Interface* gl =
1979 output_surface_->context_provider()->ContextGL();
1980 gpu::ContextSupport* context_support =
1981 output_surface_->context_provider()->ContextSupport();
1983 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1985 context_support->SignalSyncPoint(
1986 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1987 EXPECT_EQ(0, sync_point_callback_count);
1988 EXPECT_EQ(0, other_callback_count);
1990 // Make the sync point happen.
1991 gl->Finish();
1992 // Post a task after the sync point.
1993 base::ThreadTaskRunnerHandle::Get()->PostTask(
1994 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1996 base::MessageLoop::current()->Run();
1998 // The sync point should have happened.
1999 EXPECT_EQ(1, sync_point_callback_count);
2000 EXPECT_EQ(1, other_callback_count);
2002 #endif // OS_ANDROID
2004 class TestOverlayProcessor : public OverlayProcessor {
2005 public:
2006 class Strategy : public OverlayProcessor::Strategy {
2007 public:
2008 Strategy() {}
2009 ~Strategy() override {}
2010 MOCK_METHOD3(Attempt,
2011 bool(RenderPassList* render_passes_in_draw_order,
2012 OverlayCandidateList* candidates,
2013 float device_scale_factor));
2016 explicit TestOverlayProcessor(OutputSurface* surface)
2017 : OverlayProcessor(surface) {}
2018 ~TestOverlayProcessor() override {}
2019 void Initialize() override {
2020 strategy_ = new Strategy();
2021 strategies_.push_back(scoped_ptr<OverlayProcessor::Strategy>(strategy_));
2024 Strategy* strategy_;
2027 void MailboxReleased(unsigned sync_point,
2028 bool lost_resource,
2029 BlockingTaskRunner* main_thread_task_runner) {
2032 void IgnoreCopyResult(scoped_ptr<CopyOutputResult> result) {
2035 TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
2036 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
2037 FakeOutputSurfaceClient output_surface_client;
2038 scoped_ptr<OutputSurface> output_surface(
2039 FakeOutputSurface::Create3d(context_owned.Pass()));
2040 CHECK(output_surface->BindToClient(&output_surface_client));
2042 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2043 new TestSharedBitmapManager());
2044 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2045 output_surface.get(), shared_bitmap_manager.get());
2046 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2047 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2049 RendererSettings settings;
2050 FakeRendererClient renderer_client;
2051 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2052 resource_provider.get(), mailbox_deleter.get());
2054 TestOverlayProcessor* processor =
2055 new TestOverlayProcessor(output_surface.get());
2056 processor->Initialize();
2057 renderer.SetOverlayProcessor(processor);
2059 gfx::Rect viewport_rect(1, 1);
2060 RenderPass* root_pass =
2061 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2062 viewport_rect, gfx::Transform());
2063 root_pass->has_transparent_background = false;
2064 root_pass->copy_requests.push_back(
2065 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult)));
2067 unsigned sync_point = 0;
2068 TextureMailbox mailbox =
2069 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2070 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2071 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2072 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2073 mailbox, release_callback.Pass());
2074 bool premultiplied_alpha = false;
2075 bool flipped = false;
2076 bool nearest_neighbor = false;
2077 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2079 TextureDrawQuad* overlay_quad =
2080 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2081 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2082 viewport_rect, viewport_rect, viewport_rect, resource_id,
2083 premultiplied_alpha, gfx::PointF(0, 0),
2084 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2085 flipped, nearest_neighbor);
2086 overlay_quad->set_allow_overlay(true);
2088 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2089 // Attempt will be called for each strategy in OverlayProcessor. We have
2090 // added a fake strategy, so checking for Attempt calls checks if there was
2091 // any attempt to overlay, which there shouldn't be. We can't use the quad
2092 // list because the render pass is cleaned up by DrawFrame.
2093 EXPECT_CALL(*processor->strategy_, Attempt(_, _, _)).Times(0);
2094 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2095 viewport_rect, false);
2096 Mock::VerifyAndClearExpectations(processor->strategy_);
2098 // Without a copy request Attempt() should be called once.
2099 root_pass = AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2100 viewport_rect, gfx::Transform());
2101 root_pass->has_transparent_background = false;
2103 overlay_quad = root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2104 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2105 viewport_rect, viewport_rect, viewport_rect, resource_id,
2106 premultiplied_alpha, gfx::PointF(0, 0),
2107 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2108 flipped, nearest_neighbor);
2110 EXPECT_CALL(*processor->strategy_, Attempt(_, _, _)).Times(1);
2111 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2112 viewport_rect, false);
2115 class SingleOverlayOnTopProcessor : public OverlayProcessor {
2116 public:
2117 class SingleOverlayValidator : public OverlayCandidateValidator {
2118 public:
2119 void GetStrategies(OverlayProcessor::StrategyList* strategies) override {
2120 strategies->push_back(scoped_ptr<OverlayProcessor::Strategy>(
2121 new OverlayStrategyCommon(this, new OverlayStrategySingleOnTop)));
2122 strategies->push_back(scoped_ptr<OverlayProcessor::Strategy>(
2123 new OverlayStrategyCommon(this, new OverlayStrategyUnderlay)));
2126 void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
2127 ASSERT_EQ(2U, surfaces->size());
2128 OverlayCandidate& candidate = surfaces->back();
2129 candidate.overlay_handled = true;
2133 explicit SingleOverlayOnTopProcessor(OutputSurface* surface)
2134 : OverlayProcessor(surface) {}
2136 void Initialize() override {
2137 strategies_.push_back(scoped_ptr<Strategy>(new OverlayStrategyCommon(
2138 &validator_, new OverlayStrategySingleOnTop)));
2141 SingleOverlayValidator validator_;
2144 class WaitSyncPointCountingContext : public TestWebGraphicsContext3D {
2145 public:
2146 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
2149 class MockOverlayScheduler {
2150 public:
2151 MOCK_METHOD5(Schedule,
2152 void(int plane_z_order,
2153 gfx::OverlayTransform plane_transform,
2154 unsigned overlay_texture_id,
2155 const gfx::Rect& display_bounds,
2156 const gfx::RectF& uv_rect));
2159 TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
2160 scoped_ptr<WaitSyncPointCountingContext> context_owned(
2161 new WaitSyncPointCountingContext);
2162 WaitSyncPointCountingContext* context = context_owned.get();
2164 MockOverlayScheduler overlay_scheduler;
2165 scoped_refptr<TestContextProvider> context_provider =
2166 TestContextProvider::Create(context_owned.Pass());
2167 context_provider->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2168 &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler)));
2170 FakeOutputSurfaceClient output_surface_client;
2171 scoped_ptr<OutputSurface> output_surface(
2172 FakeOutputSurface::Create3d(context_provider));
2173 CHECK(output_surface->BindToClient(&output_surface_client));
2175 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2176 new TestSharedBitmapManager());
2177 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2178 output_surface.get(), shared_bitmap_manager.get());
2179 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2180 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2182 RendererSettings settings;
2183 FakeRendererClient renderer_client;
2184 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2185 resource_provider.get(), mailbox_deleter.get());
2187 SingleOverlayOnTopProcessor* processor =
2188 new SingleOverlayOnTopProcessor(output_surface.get());
2189 processor->Initialize();
2190 renderer.SetOverlayProcessor(processor);
2192 gfx::Rect viewport_rect(1, 1);
2193 RenderPass* root_pass =
2194 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2195 viewport_rect, gfx::Transform());
2196 root_pass->has_transparent_background = false;
2198 unsigned sync_point = 29;
2199 TextureMailbox mailbox =
2200 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2201 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2202 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2203 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2204 mailbox, release_callback.Pass());
2205 bool premultiplied_alpha = false;
2206 bool flipped = false;
2207 bool nearest_neighbor = false;
2208 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2209 gfx::PointF uv_top_left(0, 0);
2210 gfx::PointF uv_bottom_right(1, 1);
2212 TextureDrawQuad* overlay_quad =
2213 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2214 SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
2215 shared_state->SetAll(gfx::Transform(), viewport_rect.size(), viewport_rect,
2216 viewport_rect, false, 1, SkXfermode::kSrcOver_Mode, 0);
2217 overlay_quad->SetNew(shared_state, viewport_rect, viewport_rect,
2218 viewport_rect, resource_id, premultiplied_alpha,
2219 uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT,
2220 vertex_opacity, flipped, nearest_neighbor);
2221 overlay_quad->set_allow_overlay(true);
2223 // Verify that overlay_quad actually gets turned into an overlay, and even
2224 // though it's not drawn, that its sync point is waited on.
2225 EXPECT_CALL(*context, waitSyncPoint(sync_point)).Times(1);
2226 EXPECT_CALL(overlay_scheduler,
2227 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, viewport_rect,
2228 BoundingRect(uv_top_left, uv_bottom_right))).Times(1);
2230 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2231 viewport_rect, false);
2234 } // namespace
2235 } // namespace cc