Roll WebRTC 9745:9761, Libjingle 9742:9761
[chromium-blink-merge.git] / cc / output / gl_renderer_unittest.cc
blob882e46fc0d52cdc31d938f3740d9d88a27b2a3db
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_utils.h"
28 #include "cc/test/test_shared_bitmap_manager.h"
29 #include "cc/test/test_web_graphics_context_3d.h"
30 #include "gpu/GLES2/gl2extchromium.h"
31 #include "gpu/command_buffer/client/context_support.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "third_party/skia/include/core/SkImageFilter.h"
35 #include "third_party/skia/include/core/SkMatrix.h"
36 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
37 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
38 #include "ui/gfx/transform.h"
40 using testing::_;
41 using testing::AnyNumber;
42 using testing::Args;
43 using testing::AtLeast;
44 using testing::ElementsAre;
45 using testing::Expectation;
46 using testing::InSequence;
47 using testing::Mock;
48 using testing::Return;
49 using testing::StrictMock;
51 namespace cc {
53 class GLRendererTest : public testing::Test {
54 protected:
55 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
57 RenderPassList render_passes_in_draw_order_;
60 #define EXPECT_PROGRAM_VALID(program_binding) \
61 do { \
62 EXPECT_TRUE((program_binding)->program()); \
63 EXPECT_TRUE((program_binding)->initialized()); \
64 } while (false)
66 static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
67 switch (blend_mode) {
68 case BLEND_MODE_NONE:
69 case BLEND_MODE_NORMAL:
70 return SkXfermode::kSrcOver_Mode;
71 case BLEND_MODE_SCREEN:
72 return SkXfermode::kScreen_Mode;
73 case BLEND_MODE_OVERLAY:
74 return SkXfermode::kOverlay_Mode;
75 case BLEND_MODE_DARKEN:
76 return SkXfermode::kDarken_Mode;
77 case BLEND_MODE_LIGHTEN:
78 return SkXfermode::kLighten_Mode;
79 case BLEND_MODE_COLOR_DODGE:
80 return SkXfermode::kColorDodge_Mode;
81 case BLEND_MODE_COLOR_BURN:
82 return SkXfermode::kColorBurn_Mode;
83 case BLEND_MODE_HARD_LIGHT:
84 return SkXfermode::kHardLight_Mode;
85 case BLEND_MODE_SOFT_LIGHT:
86 return SkXfermode::kSoftLight_Mode;
87 case BLEND_MODE_DIFFERENCE:
88 return SkXfermode::kDifference_Mode;
89 case BLEND_MODE_EXCLUSION:
90 return SkXfermode::kExclusion_Mode;
91 case BLEND_MODE_MULTIPLY:
92 return SkXfermode::kMultiply_Mode;
93 case BLEND_MODE_HUE:
94 return SkXfermode::kHue_Mode;
95 case BLEND_MODE_SATURATION:
96 return SkXfermode::kSaturation_Mode;
97 case BLEND_MODE_COLOR:
98 return SkXfermode::kColor_Mode;
99 case BLEND_MODE_LUMINOSITY:
100 return SkXfermode::kLuminosity_Mode;
102 return SkXfermode::kSrcOver_Mode;
105 // Explicitly named to be a friend in GLRenderer for shader access.
106 class GLRendererShaderPixelTest : public GLRendererPixelTest {
107 public:
108 void SetUp() override {
109 GLRendererPixelTest::SetUp();
110 ASSERT_FALSE(renderer()->IsContextLost());
113 void TearDown() override {
114 GLRendererPixelTest::TearDown();
115 ASSERT_FALSE(renderer()->IsContextLost());
118 void TestBasicShaders() {
119 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
120 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
121 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
124 void TestShadersWithPrecision(TexCoordPrecision precision) {
125 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
126 if (renderer()->Capabilities().using_egl_image)
127 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
128 else
129 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
132 void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision,
133 BlendMode blend_mode) {
134 EXPECT_PROGRAM_VALID(
135 renderer()->GetRenderPassProgram(precision, blend_mode));
136 EXPECT_PROGRAM_VALID(
137 renderer()->GetRenderPassProgramAA(precision, blend_mode));
140 void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision,
141 SamplerType sampler) {
142 if (!renderer()->Capabilities().using_egl_image &&
143 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
144 // This will likely be hit in tests due to usage of osmesa.
145 return;
148 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision, sampler));
149 EXPECT_PROGRAM_VALID(
150 renderer()->GetNonPremultipliedTextureProgram(precision, sampler));
151 EXPECT_PROGRAM_VALID(
152 renderer()->GetTextureBackgroundProgram(precision, sampler));
153 EXPECT_PROGRAM_VALID(
154 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision,
155 sampler));
157 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
158 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
159 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
160 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
161 EXPECT_PROGRAM_VALID(
162 renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
163 EXPECT_PROGRAM_VALID(
164 renderer()->GetTileProgramSwizzleAA(precision, sampler));
165 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision, sampler));
166 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision, sampler));
169 void TestShadersWithMasks(TexCoordPrecision precision,
170 SamplerType sampler,
171 BlendMode blend_mode,
172 bool mask_for_background) {
173 if (!renderer()->Capabilities().using_egl_image &&
174 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
175 // This will likely be hit in tests due to usage of osmesa.
176 return;
179 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
180 precision, sampler, blend_mode, mask_for_background));
181 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
182 precision, sampler, blend_mode, mask_for_background));
183 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
184 precision, sampler, blend_mode, mask_for_background));
185 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
186 precision, sampler, blend_mode, mask_for_background));
190 namespace {
192 #if !defined(OS_ANDROID) && !defined(OS_WIN)
193 static const TexCoordPrecision kPrecisionList[] = {TEX_COORD_PRECISION_MEDIUM,
194 TEX_COORD_PRECISION_HIGH};
196 static const BlendMode kBlendModeList[LAST_BLEND_MODE + 1] = {
197 BLEND_MODE_NONE,
198 BLEND_MODE_NORMAL,
199 BLEND_MODE_SCREEN,
200 BLEND_MODE_OVERLAY,
201 BLEND_MODE_DARKEN,
202 BLEND_MODE_LIGHTEN,
203 BLEND_MODE_COLOR_DODGE,
204 BLEND_MODE_COLOR_BURN,
205 BLEND_MODE_HARD_LIGHT,
206 BLEND_MODE_SOFT_LIGHT,
207 BLEND_MODE_DIFFERENCE,
208 BLEND_MODE_EXCLUSION,
209 BLEND_MODE_MULTIPLY,
210 BLEND_MODE_HUE,
211 BLEND_MODE_SATURATION,
212 BLEND_MODE_COLOR,
213 BLEND_MODE_LUMINOSITY,
216 static const SamplerType kSamplerList[] = {
217 SAMPLER_TYPE_2D,
218 SAMPLER_TYPE_2D_RECT,
219 SAMPLER_TYPE_EXTERNAL_OES,
222 TEST_F(GLRendererShaderPixelTest, BasicShadersCompile) {
223 TestBasicShaders();
226 class PrecisionShaderPixelTest
227 : public GLRendererShaderPixelTest,
228 public ::testing::WithParamInterface<TexCoordPrecision> {};
230 TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
231 TestShadersWithPrecision(GetParam());
234 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile,
235 PrecisionShaderPixelTest,
236 ::testing::ValuesIn(kPrecisionList));
238 class PrecisionBlendShaderPixelTest
239 : public GLRendererShaderPixelTest,
240 public ::testing::WithParamInterface<
241 std::tr1::tuple<TexCoordPrecision, BlendMode>> {};
243 TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
244 TestShadersWithPrecisionAndBlend(std::tr1::get<0>(GetParam()),
245 std::tr1::get<1>(GetParam()));
248 INSTANTIATE_TEST_CASE_P(
249 PrecisionBlendShadersCompile,
250 PrecisionBlendShaderPixelTest,
251 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
252 ::testing::ValuesIn(kBlendModeList)));
254 class PrecisionSamplerShaderPixelTest
255 : public GLRendererShaderPixelTest,
256 public ::testing::WithParamInterface<
257 std::tr1::tuple<TexCoordPrecision, SamplerType>> {};
259 TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
260 TestShadersWithPrecisionAndSampler(std::tr1::get<0>(GetParam()),
261 std::tr1::get<1>(GetParam()));
264 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile,
265 PrecisionSamplerShaderPixelTest,
266 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
267 ::testing::ValuesIn(kSamplerList)));
269 class MaskShaderPixelTest
270 : public GLRendererShaderPixelTest,
271 public ::testing::WithParamInterface<
272 std::tr1::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {};
274 TEST_P(MaskShaderPixelTest, ShadersCompile) {
275 TestShadersWithMasks(
276 std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
277 std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam()));
280 INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
281 MaskShaderPixelTest,
282 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
283 ::testing::ValuesIn(kSamplerList),
284 ::testing::ValuesIn(kBlendModeList),
285 ::testing::Bool()));
287 #endif
289 class FakeRendererGL : public GLRenderer {
290 public:
291 FakeRendererGL(RendererClient* client,
292 const RendererSettings* settings,
293 OutputSurface* output_surface,
294 ResourceProvider* resource_provider)
295 : GLRenderer(client,
296 settings,
297 output_surface,
298 resource_provider,
299 NULL,
300 0) {}
302 FakeRendererGL(RendererClient* client,
303 const RendererSettings* settings,
304 OutputSurface* output_surface,
305 ResourceProvider* resource_provider,
306 TextureMailboxDeleter* texture_mailbox_deleter)
307 : GLRenderer(client,
308 settings,
309 output_surface,
310 resource_provider,
311 texture_mailbox_deleter,
312 0) {}
314 void SetOverlayProcessor(OverlayProcessor* processor) {
315 overlay_processor_.reset(processor);
318 // GLRenderer methods.
320 // Changing visibility to public.
321 using GLRenderer::IsBackbufferDiscarded;
322 using GLRenderer::DoDrawQuad;
323 using GLRenderer::BeginDrawingFrame;
324 using GLRenderer::FinishDrawingQuadList;
325 using GLRenderer::stencil_enabled;
328 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
329 protected:
330 GLRendererWithDefaultHarnessTest() {
331 output_surface_ =
332 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
333 CHECK(output_surface_->BindToClient(&output_surface_client_));
335 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
336 resource_provider_ = FakeResourceProvider::Create(
337 output_surface_.get(), shared_bitmap_manager_.get());
338 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
339 &settings_,
340 output_surface_.get(),
341 resource_provider_.get()));
344 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
346 RendererSettings settings_;
347 FakeOutputSurfaceClient output_surface_client_;
348 scoped_ptr<FakeOutputSurface> output_surface_;
349 FakeRendererClient renderer_client_;
350 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
351 scoped_ptr<ResourceProvider> resource_provider_;
352 scoped_ptr<FakeRendererGL> renderer_;
355 // Closing the namespace here so that GLRendererShaderTest can take advantage
356 // of the friend relationship with GLRenderer and all of the mock classes
357 // declared above it.
358 } // namespace
360 class GLRendererShaderTest : public GLRendererTest {
361 protected:
362 GLRendererShaderTest() {
363 output_surface_ = FakeOutputSurface::Create3d().Pass();
364 CHECK(output_surface_->BindToClient(&output_surface_client_));
366 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
367 resource_provider_ = FakeResourceProvider::Create(
368 output_surface_.get(), shared_bitmap_manager_.get());
369 renderer_.reset(new FakeRendererGL(&renderer_client_,
370 &settings_,
371 output_surface_.get(),
372 resource_provider_.get()));
375 void TestRenderPassProgram(TexCoordPrecision precision,
376 BlendMode blend_mode) {
377 EXPECT_PROGRAM_VALID(
378 &renderer_->render_pass_program_[precision][blend_mode]);
379 EXPECT_EQ(renderer_->render_pass_program_[precision][blend_mode].program(),
380 renderer_->program_shadow_);
383 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
384 BlendMode blend_mode) {
385 EXPECT_PROGRAM_VALID(
386 &renderer_->render_pass_color_matrix_program_[precision][blend_mode]);
387 EXPECT_EQ(
388 renderer_->render_pass_color_matrix_program_[precision][blend_mode]
389 .program(),
390 renderer_->program_shadow_);
393 void TestRenderPassMaskProgram(TexCoordPrecision precision,
394 SamplerType sampler,
395 BlendMode blend_mode) {
396 EXPECT_PROGRAM_VALID(
397 &renderer_->render_pass_mask_program_[precision]
398 [sampler]
399 [blend_mode]
400 [NO_MASK]);
401 EXPECT_EQ(
402 renderer_->render_pass_mask_program_[precision]
403 [sampler]
404 [blend_mode]
405 [NO_MASK].program(),
406 renderer_->program_shadow_);
409 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
410 SamplerType sampler,
411 BlendMode blend_mode) {
412 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_
413 [precision][sampler][blend_mode][NO_MASK]);
414 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_
415 [precision][sampler][blend_mode][NO_MASK].program(),
416 renderer_->program_shadow_);
419 void TestRenderPassProgramAA(TexCoordPrecision precision,
420 BlendMode blend_mode) {
421 EXPECT_PROGRAM_VALID(
422 &renderer_->render_pass_program_aa_[precision][blend_mode]);
423 EXPECT_EQ(
424 renderer_->render_pass_program_aa_[precision][blend_mode].program(),
425 renderer_->program_shadow_);
428 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
429 BlendMode blend_mode) {
430 EXPECT_PROGRAM_VALID(
431 &renderer_
432 ->render_pass_color_matrix_program_aa_[precision][blend_mode]);
433 EXPECT_EQ(
434 renderer_->render_pass_color_matrix_program_aa_[precision][blend_mode]
435 .program(),
436 renderer_->program_shadow_);
439 void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
440 SamplerType sampler,
441 BlendMode blend_mode) {
442 EXPECT_PROGRAM_VALID(
443 &renderer_
444 ->render_pass_mask_program_aa_
445 [precision][sampler][blend_mode][NO_MASK]);
446 EXPECT_EQ(
447 renderer_->render_pass_mask_program_aa_[precision][sampler][blend_mode]
448 [NO_MASK].program(),
449 renderer_->program_shadow_);
452 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
453 SamplerType sampler,
454 BlendMode blend_mode) {
455 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_aa_
456 [precision][sampler][blend_mode][NO_MASK]);
457 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_
458 [precision][sampler][blend_mode][NO_MASK].program(),
459 renderer_->program_shadow_);
462 void TestSolidColorProgramAA() {
463 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
464 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
465 renderer_->program_shadow_);
468 RendererSettings settings_;
469 FakeOutputSurfaceClient output_surface_client_;
470 scoped_ptr<FakeOutputSurface> output_surface_;
471 FakeRendererClient renderer_client_;
472 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
473 scoped_ptr<ResourceProvider> resource_provider_;
474 scoped_ptr<FakeRendererGL> renderer_;
477 namespace {
479 // Test GLRenderer DiscardBackbuffer functionality:
480 // Suggest discarding framebuffer when one exists and the renderer is not
481 // visible.
482 // Expected: it is discarded and damage tracker is reset.
483 TEST_F(
484 GLRendererWithDefaultHarnessTest,
485 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
486 renderer_->SetVisible(false);
487 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
488 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
491 // Test GLRenderer DiscardBackbuffer functionality:
492 // Suggest discarding framebuffer when one exists and the renderer is visible.
493 // Expected: the allocation is ignored.
494 TEST_F(GLRendererWithDefaultHarnessTest,
495 SuggestBackbufferNoDoNothingWhenVisible) {
496 renderer_->SetVisible(true);
497 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
498 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
501 // Test GLRenderer DiscardBackbuffer functionality:
502 // Suggest discarding framebuffer when one does not exist.
503 // Expected: it does nothing.
504 TEST_F(GLRendererWithDefaultHarnessTest,
505 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
506 renderer_->SetVisible(false);
507 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
508 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
510 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
511 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
514 // Test GLRenderer DiscardBackbuffer functionality:
515 // Begin drawing a frame while a framebuffer is discarded.
516 // Expected: will recreate framebuffer.
517 TEST_F(GLRendererWithDefaultHarnessTest,
518 DiscardedBackbufferIsRecreatedForScopeDuration) {
519 gfx::Rect viewport_rect(1, 1);
520 renderer_->SetVisible(false);
521 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
522 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
524 AddRenderPass(&render_passes_in_draw_order_,
525 RenderPassId(1, 0),
526 viewport_rect,
527 gfx::Transform());
529 renderer_->SetVisible(true);
530 renderer_->DrawFrame(&render_passes_in_draw_order_,
531 1.f,
532 viewport_rect,
533 viewport_rect,
534 false);
535 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
537 SwapBuffers();
538 EXPECT_EQ(1u, output_surface_->num_sent_frames());
541 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
542 gfx::Rect viewport_rect(1, 1);
543 EXPECT_FALSE(renderer_->stencil_enabled());
545 output_surface_->set_has_external_stencil_test(true);
547 RenderPass* root_pass =
548 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
549 viewport_rect, gfx::Transform());
550 root_pass->has_transparent_background = false;
552 renderer_->DrawFrame(&render_passes_in_draw_order_,
553 1.f,
554 viewport_rect,
555 viewport_rect,
556 false);
557 EXPECT_TRUE(renderer_->stencil_enabled());
560 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
561 public:
562 ForbidSynchronousCallContext() {}
564 void getAttachedShaders(GLuint program,
565 GLsizei max_count,
566 GLsizei* count,
567 GLuint* shaders) override {
568 ADD_FAILURE();
570 GLint getAttribLocation(GLuint program, const GLchar* name) override {
571 ADD_FAILURE();
572 return 0;
574 void getBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
575 void getBufferParameteriv(GLenum target,
576 GLenum pname,
577 GLint* value) override {
578 ADD_FAILURE();
580 GLenum getError() override {
581 ADD_FAILURE();
582 return GL_NO_ERROR;
584 void getFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
585 void getFramebufferAttachmentParameteriv(GLenum target,
586 GLenum attachment,
587 GLenum pname,
588 GLint* value) override {
589 ADD_FAILURE();
591 void getIntegerv(GLenum pname, GLint* value) override {
592 if (pname == GL_MAX_TEXTURE_SIZE) {
593 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
594 *value = 1024;
595 } else {
596 ADD_FAILURE();
600 // We allow querying the shader compilation and program link status in debug
601 // mode, but not release.
602 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
603 #ifndef NDEBUG
604 *value = 1;
605 #else
606 ADD_FAILURE();
607 #endif
610 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
611 #ifndef NDEBUG
612 *value = 1;
613 #else
614 ADD_FAILURE();
615 #endif
618 void getRenderbufferParameteriv(GLenum target,
619 GLenum pname,
620 GLint* value) override {
621 ADD_FAILURE();
624 void getShaderPrecisionFormat(GLenum shadertype,
625 GLenum precisiontype,
626 GLint* range,
627 GLint* precision) override {
628 ADD_FAILURE();
630 void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
631 ADD_FAILURE();
633 void getTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
634 ADD_FAILURE();
636 void getUniformfv(GLuint program, GLint location, GLfloat* value) override {
637 ADD_FAILURE();
639 void getUniformiv(GLuint program, GLint location, GLint* value) override {
640 ADD_FAILURE();
642 GLint getUniformLocation(GLuint program, const GLchar* name) override {
643 ADD_FAILURE();
644 return 0;
646 void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
647 ADD_FAILURE();
649 void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
650 ADD_FAILURE();
652 GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname) override {
653 ADD_FAILURE();
654 return 0;
657 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
658 FakeOutputSurfaceClient output_surface_client;
659 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
660 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
661 CHECK(output_surface->BindToClient(&output_surface_client));
663 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
664 new TestSharedBitmapManager());
665 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
666 output_surface.get(), shared_bitmap_manager.get());
668 RendererSettings settings;
669 FakeRendererClient renderer_client;
670 FakeRendererGL renderer(&renderer_client,
671 &settings,
672 output_surface.get(),
673 resource_provider.get());
676 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
677 public:
678 LoseContextOnFirstGetContext() {}
680 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
681 context_lost_ = true;
682 *value = 0;
685 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
686 context_lost_ = true;
687 *value = 0;
691 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
692 FakeOutputSurfaceClient output_surface_client;
693 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
694 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
695 CHECK(output_surface->BindToClient(&output_surface_client));
697 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
698 new TestSharedBitmapManager());
699 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
700 output_surface.get(), shared_bitmap_manager.get());
702 RendererSettings settings;
703 FakeRendererClient renderer_client;
704 FakeRendererGL renderer(&renderer_client,
705 &settings,
706 output_surface.get(),
707 resource_provider.get());
710 class ClearCountingContext : public TestWebGraphicsContext3D {
711 public:
712 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
714 MOCK_METHOD3(discardFramebufferEXT,
715 void(GLenum target,
716 GLsizei numAttachments,
717 const GLenum* attachments));
718 MOCK_METHOD1(clear, void(GLbitfield mask));
721 TEST_F(GLRendererTest, OpaqueBackground) {
722 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
723 ClearCountingContext* context = context_owned.get();
725 FakeOutputSurfaceClient output_surface_client;
726 scoped_ptr<OutputSurface> output_surface(
727 FakeOutputSurface::Create3d(context_owned.Pass()));
728 CHECK(output_surface->BindToClient(&output_surface_client));
730 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
731 new TestSharedBitmapManager());
732 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
733 output_surface.get(), shared_bitmap_manager.get());
735 RendererSettings settings;
736 FakeRendererClient renderer_client;
737 FakeRendererGL renderer(&renderer_client,
738 &settings,
739 output_surface.get(),
740 resource_provider.get());
742 gfx::Rect viewport_rect(1, 1);
743 RenderPass* root_pass =
744 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
745 viewport_rect, gfx::Transform());
746 root_pass->has_transparent_background = false;
748 // On DEBUG builds, render passes with opaque background clear to blue to
749 // easily see regions that were not drawn on the screen.
750 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
751 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
752 .Times(1);
753 #ifdef NDEBUG
754 EXPECT_CALL(*context, clear(_)).Times(0);
755 #else
756 EXPECT_CALL(*context, clear(_)).Times(1);
757 #endif
758 renderer.DrawFrame(&render_passes_in_draw_order_,
759 1.f,
760 viewport_rect,
761 viewport_rect,
762 false);
763 Mock::VerifyAndClearExpectations(context);
766 TEST_F(GLRendererTest, TransparentBackground) {
767 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
768 ClearCountingContext* context = context_owned.get();
770 FakeOutputSurfaceClient output_surface_client;
771 scoped_ptr<OutputSurface> output_surface(
772 FakeOutputSurface::Create3d(context_owned.Pass()));
773 CHECK(output_surface->BindToClient(&output_surface_client));
775 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
776 new TestSharedBitmapManager());
777 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
778 output_surface.get(), shared_bitmap_manager.get());
780 RendererSettings settings;
781 FakeRendererClient renderer_client;
782 FakeRendererGL renderer(&renderer_client,
783 &settings,
784 output_surface.get(),
785 resource_provider.get());
787 gfx::Rect viewport_rect(1, 1);
788 RenderPass* root_pass =
789 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
790 viewport_rect, gfx::Transform());
791 root_pass->has_transparent_background = true;
793 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
794 EXPECT_CALL(*context, clear(_)).Times(1);
795 renderer.DrawFrame(&render_passes_in_draw_order_,
796 1.f,
797 viewport_rect,
798 viewport_rect,
799 false);
801 Mock::VerifyAndClearExpectations(context);
804 TEST_F(GLRendererTest, OffscreenOutputSurface) {
805 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
806 ClearCountingContext* context = context_owned.get();
808 FakeOutputSurfaceClient output_surface_client;
809 scoped_ptr<OutputSurface> output_surface(
810 FakeOutputSurface::CreateOffscreen(context_owned.Pass()));
811 CHECK(output_surface->BindToClient(&output_surface_client));
813 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
814 new TestSharedBitmapManager());
815 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
816 output_surface.get(), shared_bitmap_manager.get());
818 RendererSettings settings;
819 FakeRendererClient renderer_client;
820 FakeRendererGL renderer(&renderer_client,
821 &settings,
822 output_surface.get(),
823 resource_provider.get());
825 gfx::Rect viewport_rect(1, 1);
826 AddRenderPass(&render_passes_in_draw_order_,
827 RenderPassId(1, 0),
828 viewport_rect,
829 gfx::Transform());
831 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
832 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
833 .Times(1);
834 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
835 renderer.DrawFrame(&render_passes_in_draw_order_,
836 1.f,
837 viewport_rect,
838 viewport_rect,
839 false);
840 Mock::VerifyAndClearExpectations(context);
843 class VisibilityChangeIsLastCallTrackingContext
844 : public TestWebGraphicsContext3D {
845 public:
846 VisibilityChangeIsLastCallTrackingContext()
847 : last_call_was_set_visibility_(false) {}
849 // TestWebGraphicsContext3D methods.
850 void flush() override { last_call_was_set_visibility_ = false; }
851 void deleteTexture(GLuint) override { last_call_was_set_visibility_ = false; }
852 void deleteFramebuffer(GLuint) override {
853 last_call_was_set_visibility_ = false;
855 void deleteQueryEXT(GLuint) override {
856 last_call_was_set_visibility_ = false;
858 void deleteRenderbuffer(GLuint) override {
859 last_call_was_set_visibility_ = false;
862 // Methods added for test.
863 void set_last_call_was_visibility(bool visible) {
864 DCHECK(last_call_was_set_visibility_ == false);
865 last_call_was_set_visibility_ = true;
867 bool last_call_was_set_visibility() const {
868 return last_call_was_set_visibility_;
871 private:
872 bool last_call_was_set_visibility_;
875 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
876 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
877 new VisibilityChangeIsLastCallTrackingContext);
878 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
880 scoped_refptr<TestContextProvider> provider =
881 TestContextProvider::Create(context_owned.Pass());
883 provider->support()->SetSurfaceVisibleCallback(base::Bind(
884 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
885 base::Unretained(context)));
887 FakeOutputSurfaceClient output_surface_client;
888 scoped_ptr<OutputSurface> output_surface(
889 FakeOutputSurface::Create3d(provider));
890 CHECK(output_surface->BindToClient(&output_surface_client));
892 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
893 new TestSharedBitmapManager());
894 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
895 output_surface.get(), shared_bitmap_manager.get());
897 RendererSettings settings;
898 FakeRendererClient renderer_client;
899 FakeRendererGL renderer(&renderer_client,
900 &settings,
901 output_surface.get(),
902 resource_provider.get());
904 gfx::Rect viewport_rect(1, 1);
905 AddRenderPass(&render_passes_in_draw_order_,
906 RenderPassId(1, 0),
907 viewport_rect,
908 gfx::Transform());
910 // Ensure that the call to SetSurfaceVisible is the last call issue to the
911 // GPU process, after glFlush is called, and after the RendererClient's
912 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
913 // RenderClient and the Context by giving them both a pointer to a variable on
914 // the stack.
915 renderer.SetVisible(true);
916 renderer.DrawFrame(&render_passes_in_draw_order_,
917 1.f,
918 viewport_rect,
919 viewport_rect,
920 false);
921 renderer.SetVisible(false);
922 EXPECT_TRUE(context->last_call_was_set_visibility());
925 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
926 public:
927 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
928 test_capabilities_.gpu.egl_image_external = true;
931 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
932 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
933 MOCK_METHOD4(drawElements,
934 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
936 virtual void activeTexture(GLenum texture) {
937 EXPECT_NE(texture, active_texture_);
938 active_texture_ = texture;
941 GLenum active_texture() const { return active_texture_; }
943 private:
944 GLenum active_texture_;
947 TEST_F(GLRendererTest, ActiveTextureState) {
948 scoped_ptr<TextureStateTrackingContext> context_owned(
949 new TextureStateTrackingContext);
950 TextureStateTrackingContext* context = context_owned.get();
952 FakeOutputSurfaceClient output_surface_client;
953 scoped_ptr<OutputSurface> output_surface(
954 FakeOutputSurface::Create3d(context_owned.Pass()));
955 CHECK(output_surface->BindToClient(&output_surface_client));
957 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
958 new TestSharedBitmapManager());
959 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
960 output_surface.get(), shared_bitmap_manager.get());
962 RendererSettings settings;
963 FakeRendererClient renderer_client;
964 FakeRendererGL renderer(&renderer_client,
965 &settings,
966 output_surface.get(),
967 resource_provider.get());
969 // During initialization we are allowed to set any texture parameters.
970 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
972 RenderPass* root_pass =
973 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 1),
974 gfx::Rect(100, 100), gfx::Transform());
975 uint32_t mailbox_sync_point;
976 AddOneOfEveryQuadType(root_pass, resource_provider.get(), RenderPassId(0, 0),
977 &mailbox_sync_point);
979 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
981 // Set up expected texture filter state transitions that match the quads
982 // created in AppendOneOfEveryQuadType().
983 Mock::VerifyAndClearExpectations(context);
985 InSequence sequence;
987 // The sync points for all quads are waited on first. This sync point is
988 // for a texture quad drawn later in the frame.
989 EXPECT_CALL(*context, waitSyncPoint(mailbox_sync_point)).Times(1);
991 // yuv_quad is drawn with the default linear filter.
992 EXPECT_CALL(*context, drawElements(_, _, _, _));
994 // tile_quad is drawn with GL_NEAREST because it is not transformed or
995 // scaled.
996 EXPECT_CALL(
997 *context,
998 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
999 EXPECT_CALL(
1000 *context,
1001 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1002 EXPECT_CALL(*context, drawElements(_, _, _, _));
1004 // transformed_tile_quad uses GL_LINEAR.
1005 EXPECT_CALL(*context, drawElements(_, _, _, _));
1007 // scaled_tile_quad also uses GL_LINEAR.
1008 EXPECT_CALL(*context, drawElements(_, _, _, _));
1010 // The remaining quads also use GL_LINEAR because nearest neighbor
1011 // filtering is currently only used with tile quads.
1012 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6);
1015 gfx::Rect viewport_rect(100, 100);
1016 renderer.DrawFrame(&render_passes_in_draw_order_,
1017 1.f,
1018 viewport_rect,
1019 viewport_rect,
1020 false);
1021 Mock::VerifyAndClearExpectations(context);
1024 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
1025 public:
1026 MOCK_METHOD1(clear, void(GLbitfield mask));
1027 MOCK_METHOD4(drawElements,
1028 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1031 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
1032 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
1033 new NoClearRootRenderPassMockContext);
1034 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
1036 FakeOutputSurfaceClient output_surface_client;
1037 scoped_ptr<OutputSurface> output_surface(
1038 FakeOutputSurface::Create3d(mock_context_owned.Pass()));
1039 CHECK(output_surface->BindToClient(&output_surface_client));
1041 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1042 new TestSharedBitmapManager());
1043 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1044 output_surface.get(), shared_bitmap_manager.get());
1046 RendererSettings settings;
1047 settings.should_clear_root_render_pass = false;
1049 FakeRendererClient renderer_client;
1050 FakeRendererGL renderer(&renderer_client,
1051 &settings,
1052 output_surface.get(),
1053 resource_provider.get());
1055 gfx::Rect viewport_rect(10, 10);
1057 RenderPassId child_pass_id(2, 0);
1058 RenderPass* child_pass =
1059 AddRenderPass(&render_passes_in_draw_order_, child_pass_id, viewport_rect,
1060 gfx::Transform());
1061 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
1063 RenderPassId root_pass_id(1, 0);
1064 RenderPass* root_pass =
1065 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1066 gfx::Transform());
1067 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1070 AddRenderPassQuad(root_pass, child_pass);
1072 #ifdef NDEBUG
1073 GLint clear_bits = GL_COLOR_BUFFER_BIT;
1074 #else
1075 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1076 #endif
1078 // First render pass is not the root one, clearing should happen.
1079 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
1081 Expectation first_render_pass =
1082 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
1084 // The second render pass is the root one, clearing should be prevented.
1085 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
1086 first_render_pass);
1088 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
1089 first_render_pass);
1091 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1092 renderer.DrawFrame(&render_passes_in_draw_order_,
1093 1.f,
1094 viewport_rect,
1095 viewport_rect,
1096 false);
1098 // In multiple render passes all but the root pass should clear the
1099 // framebuffer.
1100 Mock::VerifyAndClearExpectations(&mock_context);
1103 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
1104 public:
1105 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1107 void clear(GLbitfield) override { EXPECT_FALSE(scissor_enabled_); }
1109 void enable(GLenum cap) override {
1110 if (cap == GL_SCISSOR_TEST)
1111 scissor_enabled_ = true;
1114 void disable(GLenum cap) override {
1115 if (cap == GL_SCISSOR_TEST)
1116 scissor_enabled_ = false;
1119 private:
1120 bool scissor_enabled_;
1123 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
1124 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
1125 new ScissorTestOnClearCheckingContext);
1127 FakeOutputSurfaceClient output_surface_client;
1128 scoped_ptr<OutputSurface> output_surface(
1129 FakeOutputSurface::Create3d(context_owned.Pass()));
1130 CHECK(output_surface->BindToClient(&output_surface_client));
1132 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1133 new TestSharedBitmapManager());
1134 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1135 output_surface.get(), shared_bitmap_manager.get());
1137 RendererSettings settings;
1138 FakeRendererClient renderer_client;
1139 FakeRendererGL renderer(&renderer_client,
1140 &settings,
1141 output_surface.get(),
1142 resource_provider.get());
1143 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1145 gfx::Rect viewport_rect(1, 1);
1147 gfx::Rect grand_child_rect(25, 25);
1148 RenderPassId grand_child_pass_id(3, 0);
1149 RenderPass* grand_child_pass =
1150 AddRenderPass(&render_passes_in_draw_order_, grand_child_pass_id,
1151 grand_child_rect, gfx::Transform());
1152 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
1154 gfx::Rect child_rect(50, 50);
1155 RenderPassId child_pass_id(2, 0);
1156 RenderPass* child_pass =
1157 AddRenderPass(&render_passes_in_draw_order_, child_pass_id, child_rect,
1158 gfx::Transform());
1159 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1161 RenderPassId root_pass_id(1, 0);
1162 RenderPass* root_pass =
1163 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1164 gfx::Transform());
1165 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1167 AddRenderPassQuad(root_pass, child_pass);
1168 AddRenderPassQuad(child_pass, grand_child_pass);
1170 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1171 renderer.DrawFrame(&render_passes_in_draw_order_,
1172 1.f,
1173 viewport_rect,
1174 viewport_rect,
1175 false);
1178 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1179 public:
1180 DiscardCheckingContext() : discarded_(0) {
1181 set_have_post_sub_buffer(true);
1182 set_have_discard_framebuffer(true);
1185 void discardFramebufferEXT(GLenum target,
1186 GLsizei numAttachments,
1187 const GLenum* attachments) override {
1188 ++discarded_;
1191 int discarded() const { return discarded_; }
1192 void reset() { discarded_ = 0; }
1194 private:
1195 int discarded_;
1198 class NonReshapableOutputSurface : public FakeOutputSurface {
1199 public:
1200 explicit NonReshapableOutputSurface(
1201 scoped_ptr<TestWebGraphicsContext3D> context3d)
1202 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1203 false) {
1204 surface_size_ = gfx::Size(500, 500);
1206 void Reshape(const gfx::Size& size, float scale_factor) override {}
1207 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1210 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1211 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1212 DiscardCheckingContext* context = context_owned.get();
1214 FakeOutputSurfaceClient output_surface_client;
1215 scoped_ptr<NonReshapableOutputSurface> output_surface(
1216 new NonReshapableOutputSurface(context_owned.Pass()));
1217 CHECK(output_surface->BindToClient(&output_surface_client));
1218 output_surface->set_fixed_size(gfx::Size(100, 100));
1220 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1221 new TestSharedBitmapManager());
1222 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1223 output_surface.get(), shared_bitmap_manager.get());
1225 RendererSettings settings;
1226 settings.partial_swap_enabled = true;
1227 FakeRendererClient renderer_client;
1228 FakeRendererGL renderer(&renderer_client,
1229 &settings,
1230 output_surface.get(),
1231 resource_provider.get());
1232 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1234 gfx::Rect viewport_rect(100, 100);
1235 gfx::Rect clip_rect(100, 100);
1238 // Partial frame, should not discard.
1239 RenderPassId root_pass_id(1, 0);
1240 RenderPass* root_pass =
1241 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1242 viewport_rect, gfx::Transform());
1243 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1244 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1246 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1247 renderer.DrawFrame(&render_passes_in_draw_order_,
1248 1.f,
1249 viewport_rect,
1250 clip_rect,
1251 false);
1252 EXPECT_EQ(0, context->discarded());
1253 context->reset();
1256 // Full frame, should discard.
1257 RenderPassId root_pass_id(1, 0);
1258 RenderPass* root_pass =
1259 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1260 viewport_rect, gfx::Transform());
1261 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1262 root_pass->damage_rect = root_pass->output_rect;
1264 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1265 renderer.DrawFrame(&render_passes_in_draw_order_,
1266 1.f,
1267 viewport_rect,
1268 clip_rect,
1269 false);
1270 EXPECT_EQ(1, context->discarded());
1271 context->reset();
1274 // Full frame, external scissor is set, should not discard.
1275 output_surface->set_has_external_stencil_test(true);
1276 RenderPassId root_pass_id(1, 0);
1277 RenderPass* root_pass =
1278 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1279 viewport_rect, gfx::Transform());
1280 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1281 root_pass->damage_rect = root_pass->output_rect;
1282 root_pass->has_transparent_background = false;
1284 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1285 renderer.DrawFrame(&render_passes_in_draw_order_,
1286 1.f,
1287 viewport_rect,
1288 clip_rect,
1289 false);
1290 EXPECT_EQ(0, context->discarded());
1291 context->reset();
1292 output_surface->set_has_external_stencil_test(false);
1295 // Full frame, clipped, should not discard.
1296 clip_rect = gfx::Rect(10, 10, 10, 10);
1297 RenderPassId root_pass_id(1, 0);
1298 RenderPass* root_pass =
1299 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1300 viewport_rect, gfx::Transform());
1301 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1302 root_pass->damage_rect = root_pass->output_rect;
1304 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1305 renderer.DrawFrame(&render_passes_in_draw_order_,
1306 1.f,
1307 viewport_rect,
1308 clip_rect,
1309 false);
1310 EXPECT_EQ(0, context->discarded());
1311 context->reset();
1314 // Full frame, doesn't cover the surface, should not discard.
1315 viewport_rect = gfx::Rect(10, 10, 10, 10);
1316 RenderPassId root_pass_id(1, 0);
1317 RenderPass* root_pass =
1318 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1319 viewport_rect, gfx::Transform());
1320 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1321 root_pass->damage_rect = root_pass->output_rect;
1323 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1324 renderer.DrawFrame(&render_passes_in_draw_order_,
1325 1.f,
1326 viewport_rect,
1327 clip_rect,
1328 false);
1329 EXPECT_EQ(0, context->discarded());
1330 context->reset();
1333 // Full frame, doesn't cover the surface (no offset), should not discard.
1334 clip_rect = gfx::Rect(100, 100);
1335 viewport_rect = gfx::Rect(50, 50);
1336 RenderPassId root_pass_id(1, 0);
1337 RenderPass* root_pass =
1338 AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
1339 viewport_rect, gfx::Transform());
1340 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1341 root_pass->damage_rect = root_pass->output_rect;
1343 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1344 renderer.DrawFrame(&render_passes_in_draw_order_,
1345 1.f,
1346 viewport_rect,
1347 clip_rect,
1348 false);
1349 EXPECT_EQ(0, context->discarded());
1350 context->reset();
1354 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1355 public:
1356 MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
1357 MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
1360 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1361 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1362 // and maintains a fixed size. This test verifies that glViewport and
1363 // glScissor's Y coordinate is flipped correctly in this environment, and that
1364 // the glViewport can be at a nonzero origin within the surface.
1365 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1366 new FlippedScissorAndViewportContext);
1368 // We expect exactly one call to viewport on this context and exactly two
1369 // to scissor (one to scissor the clear, one to scissor the quad draw).
1370 EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100));
1371 EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100));
1372 EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20));
1374 FakeOutputSurfaceClient output_surface_client;
1375 scoped_ptr<OutputSurface> output_surface(
1376 new NonReshapableOutputSurface(context_owned.Pass()));
1377 CHECK(output_surface->BindToClient(&output_surface_client));
1379 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1380 new TestSharedBitmapManager());
1381 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1382 output_surface.get(), shared_bitmap_manager.get());
1384 RendererSettings settings;
1385 FakeRendererClient renderer_client;
1386 FakeRendererGL renderer(&renderer_client,
1387 &settings,
1388 output_surface.get(),
1389 resource_provider.get());
1390 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1392 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1393 gfx::Rect viewport_rect(device_viewport_rect.size());
1394 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1396 RenderPassId root_pass_id(1, 0);
1397 RenderPass* root_pass =
1398 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1399 gfx::Transform());
1400 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1402 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1403 renderer.DrawFrame(&render_passes_in_draw_order_,
1404 1.f,
1405 device_viewport_rect,
1406 device_viewport_rect,
1407 false);
1410 TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
1411 // When using render-to-FBO to display the surface, all rendering is done
1412 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1413 // the correct framebuffer during rendering, if changed.
1414 // Note: there is one path that will set it to 0, but that is after the render
1415 // has finished.
1416 FakeOutputSurfaceClient output_surface_client;
1417 scoped_ptr<FakeOutputSurface> output_surface(
1418 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1419 CHECK(output_surface->BindToClient(&output_surface_client));
1421 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1422 new TestSharedBitmapManager());
1423 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1424 output_surface.get(), shared_bitmap_manager.get());
1426 RendererSettings settings;
1427 FakeRendererClient renderer_client;
1428 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
1429 resource_provider.get());
1430 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1432 gfx::Rect device_viewport_rect(0, 0, 100, 100);
1433 gfx::Rect viewport_rect(device_viewport_rect.size());
1434 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1436 RenderPassId root_pass_id(1, 0);
1437 RenderPass* root_pass =
1438 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1439 gfx::Transform());
1440 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1442 unsigned fbo;
1443 gpu::gles2::GLES2Interface* gl =
1444 output_surface->context_provider()->ContextGL();
1445 gl->GenFramebuffers(1, &fbo);
1446 output_surface->set_framebuffer(fbo);
1448 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1449 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect,
1450 device_viewport_rect, false);
1452 int bound_fbo;
1453 gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
1454 EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
1457 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1458 gfx::Rect viewport_rect(1, 1);
1460 gfx::Rect child_rect(50, 50);
1461 RenderPassId child_pass_id(2, 0);
1462 RenderPass* child_pass;
1464 RenderPassId root_pass_id(1, 0);
1465 RenderPass* root_pass;
1467 ResourceId mask = resource_provider_->CreateResource(
1468 gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
1469 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
1470 resource_provider_->best_texture_format());
1471 resource_provider_->AllocateForTesting(mask);
1473 SkScalar matrix[20];
1474 float amount = 0.5f;
1475 matrix[0] = 0.213f + 0.787f * amount;
1476 matrix[1] = 0.715f - 0.715f * amount;
1477 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1478 matrix[3] = matrix[4] = 0;
1479 matrix[5] = 0.213f - 0.213f * amount;
1480 matrix[6] = 0.715f + 0.285f * amount;
1481 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1482 matrix[8] = matrix[9] = 0;
1483 matrix[10] = 0.213f - 0.213f * amount;
1484 matrix[11] = 0.715f - 0.715f * amount;
1485 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1486 matrix[13] = matrix[14] = 0;
1487 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1488 matrix[18] = 1;
1489 skia::RefPtr<SkColorFilter> color_filter(
1490 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1491 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1492 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1493 FilterOperations filters;
1494 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1496 gfx::Transform transform_causing_aa;
1497 transform_causing_aa.Rotate(20.0);
1499 for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
1500 BlendMode blend_mode = static_cast<BlendMode>(i);
1501 SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
1502 settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
1503 // RenderPassProgram
1504 render_passes_in_draw_order_.clear();
1505 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1506 child_pass_id,
1507 child_rect,
1508 gfx::Transform());
1510 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1511 root_pass_id,
1512 viewport_rect,
1513 gfx::Transform());
1515 AddRenderPassQuad(root_pass,
1516 child_pass,
1518 FilterOperations(),
1519 gfx::Transform(),
1520 xfer_mode);
1522 renderer_->DecideRenderPassAllocationsForFrame(
1523 render_passes_in_draw_order_);
1524 renderer_->DrawFrame(&render_passes_in_draw_order_,
1525 1.f,
1526 viewport_rect,
1527 viewport_rect,
1528 false);
1529 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1531 // RenderPassColorMatrixProgram
1532 render_passes_in_draw_order_.clear();
1534 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1535 child_pass_id,
1536 child_rect,
1537 transform_causing_aa);
1539 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1540 root_pass_id,
1541 viewport_rect,
1542 gfx::Transform());
1544 AddRenderPassQuad(
1545 root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
1547 renderer_->DecideRenderPassAllocationsForFrame(
1548 render_passes_in_draw_order_);
1549 renderer_->DrawFrame(&render_passes_in_draw_order_,
1550 1.f,
1551 viewport_rect,
1552 viewport_rect,
1553 false);
1554 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1556 // RenderPassMaskProgram
1557 render_passes_in_draw_order_.clear();
1559 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1560 child_pass_id,
1561 child_rect,
1562 gfx::Transform());
1564 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1565 root_pass_id,
1566 viewport_rect,
1567 gfx::Transform());
1569 AddRenderPassQuad(root_pass,
1570 child_pass,
1571 mask,
1572 FilterOperations(),
1573 gfx::Transform(),
1574 xfer_mode);
1576 renderer_->DecideRenderPassAllocationsForFrame(
1577 render_passes_in_draw_order_);
1578 renderer_->DrawFrame(&render_passes_in_draw_order_,
1579 1.f,
1580 viewport_rect,
1581 viewport_rect,
1582 false);
1583 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1584 blend_mode);
1586 // RenderPassMaskColorMatrixProgram
1587 render_passes_in_draw_order_.clear();
1589 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1590 child_pass_id,
1591 child_rect,
1592 gfx::Transform());
1594 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1595 root_pass_id,
1596 viewport_rect,
1597 gfx::Transform());
1599 AddRenderPassQuad(
1600 root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
1602 renderer_->DecideRenderPassAllocationsForFrame(
1603 render_passes_in_draw_order_);
1604 renderer_->DrawFrame(&render_passes_in_draw_order_,
1605 1.f,
1606 viewport_rect,
1607 viewport_rect,
1608 false);
1609 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
1610 SAMPLER_TYPE_2D, blend_mode);
1612 // RenderPassProgramAA
1613 render_passes_in_draw_order_.clear();
1615 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1616 child_pass_id,
1617 child_rect,
1618 transform_causing_aa);
1620 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1621 root_pass_id,
1622 viewport_rect,
1623 gfx::Transform());
1625 AddRenderPassQuad(root_pass,
1626 child_pass,
1628 FilterOperations(),
1629 transform_causing_aa,
1630 xfer_mode);
1632 renderer_->DecideRenderPassAllocationsForFrame(
1633 render_passes_in_draw_order_);
1634 renderer_->DrawFrame(&render_passes_in_draw_order_,
1635 1.f,
1636 viewport_rect,
1637 viewport_rect,
1638 false);
1639 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1641 // RenderPassColorMatrixProgramAA
1642 render_passes_in_draw_order_.clear();
1644 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1645 child_pass_id,
1646 child_rect,
1647 transform_causing_aa);
1649 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1650 root_pass_id,
1651 viewport_rect,
1652 gfx::Transform());
1654 AddRenderPassQuad(
1655 root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
1657 renderer_->DecideRenderPassAllocationsForFrame(
1658 render_passes_in_draw_order_);
1659 renderer_->DrawFrame(&render_passes_in_draw_order_,
1660 1.f,
1661 viewport_rect,
1662 viewport_rect,
1663 false);
1664 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1666 // RenderPassMaskProgramAA
1667 render_passes_in_draw_order_.clear();
1669 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1670 child_pass_id,
1671 child_rect,
1672 transform_causing_aa);
1674 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1675 root_pass_id,
1676 viewport_rect,
1677 gfx::Transform());
1679 AddRenderPassQuad(root_pass,
1680 child_pass,
1681 mask,
1682 FilterOperations(),
1683 transform_causing_aa,
1684 xfer_mode);
1686 renderer_->DecideRenderPassAllocationsForFrame(
1687 render_passes_in_draw_order_);
1688 renderer_->DrawFrame(&render_passes_in_draw_order_,
1689 1.f,
1690 viewport_rect,
1691 viewport_rect,
1692 false);
1693 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1694 blend_mode);
1696 // RenderPassMaskColorMatrixProgramAA
1697 render_passes_in_draw_order_.clear();
1699 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1700 child_pass_id,
1701 child_rect,
1702 transform_causing_aa);
1704 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1705 root_pass_id,
1706 viewport_rect,
1707 transform_causing_aa);
1709 AddRenderPassQuad(
1710 root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
1712 renderer_->DecideRenderPassAllocationsForFrame(
1713 render_passes_in_draw_order_);
1714 renderer_->DrawFrame(&render_passes_in_draw_order_,
1715 1.f,
1716 viewport_rect,
1717 viewport_rect,
1718 false);
1719 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
1720 SAMPLER_TYPE_2D, blend_mode);
1724 // At this time, the AA code path cannot be taken if the surface's rect would
1725 // project incorrectly by the given transform, because of w<0 clipping.
1726 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1727 gfx::Rect child_rect(50, 50);
1728 RenderPassId child_pass_id(2, 0);
1729 RenderPass* child_pass;
1731 gfx::Rect viewport_rect(1, 1);
1732 RenderPassId root_pass_id(1, 0);
1733 RenderPass* root_pass;
1735 gfx::Transform transform_preventing_aa;
1736 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1737 transform_preventing_aa.RotateAboutYAxis(-20.0);
1738 transform_preventing_aa.Scale(30.0, 1.0);
1740 // Verify that the test transform and test rect actually do cause the clipped
1741 // flag to trigger. Otherwise we are not testing the intended scenario.
1742 bool clipped = false;
1743 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1744 ASSERT_TRUE(clipped);
1746 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1747 child_pass_id,
1748 child_rect,
1749 transform_preventing_aa);
1751 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1752 root_pass_id,
1753 viewport_rect,
1754 gfx::Transform());
1756 AddRenderPassQuad(root_pass,
1757 child_pass,
1759 FilterOperations(),
1760 transform_preventing_aa,
1761 SkXfermode::kSrcOver_Mode);
1763 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1764 renderer_->DrawFrame(&render_passes_in_draw_order_,
1765 1.f,
1766 viewport_rect,
1767 viewport_rect,
1768 false);
1770 // If use_aa incorrectly ignores clipping, it will use the
1771 // RenderPassProgramAA shader instead of the RenderPassProgram.
1772 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
1775 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1776 gfx::Rect viewport_rect(1, 1);
1777 RenderPassId root_pass_id(1, 0);
1778 RenderPass* root_pass;
1780 gfx::Transform pixel_aligned_transform_causing_aa;
1781 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1782 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1784 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1785 root_pass_id,
1786 viewport_rect,
1787 gfx::Transform());
1788 AddTransformedQuad(root_pass,
1789 viewport_rect,
1790 SK_ColorYELLOW,
1791 pixel_aligned_transform_causing_aa);
1793 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1794 renderer_->DrawFrame(&render_passes_in_draw_order_,
1795 1.f,
1796 viewport_rect,
1797 viewport_rect,
1798 false);
1800 TestSolidColorProgramAA();
1803 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1804 public:
1805 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1807 // Specifically override methods even if they are unused (used in conjunction
1808 // with StrictMock). We need to make sure that GLRenderer does not issue
1809 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1810 // through the OutputSurface abstraction.
1811 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1812 MOCK_METHOD3(reshapeWithScaleFactor,
1813 void(int width, int height, float scale_factor));
1814 MOCK_METHOD4(drawElements,
1815 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1818 class MockOutputSurface : public OutputSurface {
1819 public:
1820 MockOutputSurface()
1821 : OutputSurface(
1822 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1823 new StrictMock<OutputSurfaceMockContext>))) {
1824 surface_size_ = gfx::Size(100, 100);
1826 virtual ~MockOutputSurface() {}
1828 MOCK_METHOD0(EnsureBackbuffer, void());
1829 MOCK_METHOD0(DiscardBackbuffer, void());
1830 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1831 MOCK_METHOD0(BindFramebuffer, void());
1832 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1835 class MockOutputSurfaceTest : public GLRendererTest {
1836 protected:
1837 virtual void SetUp() {
1838 FakeOutputSurfaceClient output_surface_client_;
1839 CHECK(output_surface_.BindToClient(&output_surface_client_));
1841 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1842 resource_provider_ = FakeResourceProvider::Create(
1843 &output_surface_, shared_bitmap_manager_.get());
1845 renderer_.reset(new FakeRendererGL(&renderer_client_,
1846 &settings_,
1847 &output_surface_,
1848 resource_provider_.get()));
1851 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1853 void DrawFrame(float device_scale_factor,
1854 const gfx::Rect& device_viewport_rect) {
1855 RenderPassId render_pass_id(1, 0);
1856 RenderPass* render_pass =
1857 AddRenderPass(&render_passes_in_draw_order_, render_pass_id,
1858 device_viewport_rect, gfx::Transform());
1859 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1861 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1863 EXPECT_CALL(output_surface_,
1864 Reshape(device_viewport_rect.size(), device_scale_factor))
1865 .Times(1);
1867 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1869 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1871 renderer_->DecideRenderPassAllocationsForFrame(
1872 render_passes_in_draw_order_);
1873 renderer_->DrawFrame(&render_passes_in_draw_order_,
1874 device_scale_factor,
1875 device_viewport_rect,
1876 device_viewport_rect,
1877 false);
1880 OutputSurfaceMockContext* Context() {
1881 return static_cast<OutputSurfaceMockContext*>(
1882 static_cast<TestContextProvider*>(output_surface_.context_provider())
1883 ->TestContext3d());
1886 RendererSettings settings_;
1887 FakeOutputSurfaceClient output_surface_client_;
1888 StrictMock<MockOutputSurface> output_surface_;
1889 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1890 scoped_ptr<ResourceProvider> resource_provider_;
1891 FakeRendererClient renderer_client_;
1892 scoped_ptr<FakeRendererGL> renderer_;
1895 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1896 gfx::Rect device_viewport_rect(1, 1);
1897 DrawFrame(1.f, device_viewport_rect);
1899 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1900 renderer_->SwapBuffers(CompositorFrameMetadata());
1903 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1904 gfx::Rect device_viewport_rect(1, 1);
1906 DrawFrame(1.f, device_viewport_rect);
1907 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1908 renderer_->SwapBuffers(CompositorFrameMetadata());
1910 device_viewport_rect = gfx::Rect(2, 2);
1912 DrawFrame(2.f, device_viewport_rect);
1913 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1914 renderer_->SwapBuffers(CompositorFrameMetadata());
1916 DrawFrame(2.f, device_viewport_rect);
1917 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1918 renderer_->SwapBuffers(CompositorFrameMetadata());
1920 device_viewport_rect = gfx::Rect(1, 1);
1922 DrawFrame(1.f, device_viewport_rect);
1923 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1924 renderer_->SwapBuffers(CompositorFrameMetadata());
1927 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1928 protected:
1929 static void SyncPointCallback(int* callback_count) {
1930 ++(*callback_count);
1931 base::MessageLoop::current()->QuitWhenIdle();
1934 static void OtherCallback(int* callback_count) {
1935 ++(*callback_count);
1936 base::MessageLoop::current()->QuitWhenIdle();
1940 #if !defined(OS_ANDROID)
1941 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1942 int sync_point_callback_count = 0;
1943 int other_callback_count = 0;
1944 gpu::gles2::GLES2Interface* gl =
1945 output_surface_->context_provider()->ContextGL();
1946 gpu::ContextSupport* context_support =
1947 output_surface_->context_provider()->ContextSupport();
1949 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1951 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1952 GL_INNOCENT_CONTEXT_RESET_ARB);
1954 context_support->SignalSyncPoint(
1955 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1956 EXPECT_EQ(0, sync_point_callback_count);
1957 EXPECT_EQ(0, other_callback_count);
1959 // Make the sync point happen.
1960 gl->Finish();
1961 // Post a task after the sync point.
1962 base::ThreadTaskRunnerHandle::Get()->PostTask(
1963 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1965 base::MessageLoop::current()->Run();
1967 // The sync point shouldn't have happened since the context was lost.
1968 EXPECT_EQ(0, sync_point_callback_count);
1969 EXPECT_EQ(1, other_callback_count);
1972 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1973 int sync_point_callback_count = 0;
1974 int other_callback_count = 0;
1976 gpu::gles2::GLES2Interface* gl =
1977 output_surface_->context_provider()->ContextGL();
1978 gpu::ContextSupport* context_support =
1979 output_surface_->context_provider()->ContextSupport();
1981 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1983 context_support->SignalSyncPoint(
1984 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1985 EXPECT_EQ(0, sync_point_callback_count);
1986 EXPECT_EQ(0, other_callback_count);
1988 // Make the sync point happen.
1989 gl->Finish();
1990 // Post a task after the sync point.
1991 base::ThreadTaskRunnerHandle::Get()->PostTask(
1992 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1994 base::MessageLoop::current()->Run();
1996 // The sync point should have happened.
1997 EXPECT_EQ(1, sync_point_callback_count);
1998 EXPECT_EQ(1, other_callback_count);
2000 #endif // OS_ANDROID
2002 class TestOverlayProcessor : public OverlayProcessor {
2003 public:
2004 class Strategy : public OverlayProcessor::Strategy {
2005 public:
2006 Strategy() {}
2007 ~Strategy() override {}
2008 MOCK_METHOD2(Attempt,
2009 bool(RenderPassList* render_passes_in_draw_order,
2010 OverlayCandidateList* candidates));
2013 explicit TestOverlayProcessor(OutputSurface* surface)
2014 : OverlayProcessor(surface) {}
2015 ~TestOverlayProcessor() override {}
2016 void Initialize() override {
2017 strategy_ = new Strategy();
2018 strategies_.push_back(scoped_ptr<OverlayProcessor::Strategy>(strategy_));
2021 Strategy* strategy_;
2024 void MailboxReleased(unsigned sync_point,
2025 bool lost_resource,
2026 BlockingTaskRunner* main_thread_task_runner) {
2029 void IgnoreCopyResult(scoped_ptr<CopyOutputResult> result) {
2032 TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
2033 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
2034 FakeOutputSurfaceClient output_surface_client;
2035 scoped_ptr<OutputSurface> output_surface(
2036 FakeOutputSurface::Create3d(context_owned.Pass()));
2037 CHECK(output_surface->BindToClient(&output_surface_client));
2039 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2040 new TestSharedBitmapManager());
2041 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2042 output_surface.get(), shared_bitmap_manager.get());
2043 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2044 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2046 RendererSettings settings;
2047 FakeRendererClient renderer_client;
2048 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2049 resource_provider.get(), mailbox_deleter.get());
2051 TestOverlayProcessor* processor =
2052 new TestOverlayProcessor(output_surface.get());
2053 processor->Initialize();
2054 renderer.SetOverlayProcessor(processor);
2056 gfx::Rect viewport_rect(1, 1);
2057 RenderPass* root_pass =
2058 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2059 viewport_rect, gfx::Transform());
2060 root_pass->has_transparent_background = false;
2061 root_pass->copy_requests.push_back(
2062 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult)));
2064 unsigned sync_point = 0;
2065 TextureMailbox mailbox =
2066 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2067 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2068 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2069 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2070 mailbox, release_callback.Pass());
2071 bool premultiplied_alpha = false;
2072 bool flipped = false;
2073 bool nearest_neighbor = false;
2074 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2076 TextureDrawQuad* overlay_quad =
2077 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2078 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2079 viewport_rect, viewport_rect, viewport_rect, resource_id,
2080 premultiplied_alpha, gfx::PointF(0, 0),
2081 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2082 flipped, nearest_neighbor);
2083 overlay_quad->set_allow_overlay(true);
2085 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2086 // Attempt will be called for each strategy in OverlayProcessor. We have
2087 // added a fake strategy, so checking for Attempt calls checks if there was
2088 // any attempt to overlay, which there shouldn't be. We can't use the quad
2089 // list because the render pass is cleaned up by DrawFrame.
2090 EXPECT_CALL(*processor->strategy_, Attempt(_, _)).Times(0);
2091 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2092 viewport_rect, false);
2093 Mock::VerifyAndClearExpectations(processor->strategy_);
2095 // Without a copy request Attempt() should be called once.
2096 root_pass = AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2097 viewport_rect, gfx::Transform());
2098 root_pass->has_transparent_background = false;
2100 overlay_quad = root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2101 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2102 viewport_rect, viewport_rect, viewport_rect, resource_id,
2103 premultiplied_alpha, gfx::PointF(0, 0),
2104 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2105 flipped, nearest_neighbor);
2107 EXPECT_CALL(*processor->strategy_, Attempt(_, _)).Times(1);
2108 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2109 viewport_rect, false);
2112 class SingleOverlayOnTopProcessor : public OverlayProcessor {
2113 public:
2114 class SingleOverlayValidator : public OverlayCandidateValidator {
2115 public:
2116 void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
2117 ASSERT_EQ(2U, surfaces->size());
2118 OverlayCandidate& candidate = surfaces->back();
2119 candidate.overlay_handled = true;
2123 explicit SingleOverlayOnTopProcessor(OutputSurface* surface)
2124 : OverlayProcessor(surface) {}
2126 void Initialize() override {
2127 strategies_.push_back(
2128 scoped_ptr<Strategy>(new OverlayStrategySingleOnTop(&validator_)));
2131 SingleOverlayValidator validator_;
2134 class WaitSyncPointCountingContext : public TestWebGraphicsContext3D {
2135 public:
2136 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
2139 class MockOverlayScheduler {
2140 public:
2141 MOCK_METHOD5(Schedule,
2142 void(int plane_z_order,
2143 gfx::OverlayTransform plane_transform,
2144 unsigned overlay_texture_id,
2145 const gfx::Rect& display_bounds,
2146 const gfx::RectF& uv_rect));
2149 TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
2150 scoped_ptr<WaitSyncPointCountingContext> context_owned(
2151 new WaitSyncPointCountingContext);
2152 WaitSyncPointCountingContext* context = context_owned.get();
2154 MockOverlayScheduler overlay_scheduler;
2155 scoped_refptr<TestContextProvider> context_provider =
2156 TestContextProvider::Create(context_owned.Pass());
2157 context_provider->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2158 &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler)));
2160 FakeOutputSurfaceClient output_surface_client;
2161 scoped_ptr<OutputSurface> output_surface(
2162 FakeOutputSurface::Create3d(context_provider));
2163 CHECK(output_surface->BindToClient(&output_surface_client));
2165 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2166 new TestSharedBitmapManager());
2167 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2168 output_surface.get(), shared_bitmap_manager.get());
2169 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2170 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2172 RendererSettings settings;
2173 FakeRendererClient renderer_client;
2174 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2175 resource_provider.get(), mailbox_deleter.get());
2177 SingleOverlayOnTopProcessor* processor =
2178 new SingleOverlayOnTopProcessor(output_surface.get());
2179 processor->Initialize();
2180 renderer.SetOverlayProcessor(processor);
2182 gfx::Rect viewport_rect(1, 1);
2183 RenderPass* root_pass =
2184 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2185 viewport_rect, gfx::Transform());
2186 root_pass->has_transparent_background = false;
2188 unsigned sync_point = 29;
2189 TextureMailbox mailbox =
2190 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2191 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2192 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2193 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2194 mailbox, release_callback.Pass());
2195 bool premultiplied_alpha = false;
2196 bool flipped = false;
2197 bool nearest_neighbor = false;
2198 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2199 gfx::PointF uv_top_left(0, 0);
2200 gfx::PointF uv_bottom_right(1, 1);
2202 TextureDrawQuad* overlay_quad =
2203 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2204 SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
2205 shared_state->SetAll(gfx::Transform(), viewport_rect.size(), viewport_rect,
2206 viewport_rect, false, 1, SkXfermode::kSrcOver_Mode, 0);
2207 overlay_quad->SetNew(shared_state, viewport_rect, viewport_rect,
2208 viewport_rect, resource_id, premultiplied_alpha,
2209 uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT,
2210 vertex_opacity, flipped, nearest_neighbor);
2211 overlay_quad->set_allow_overlay(true);
2213 // Verify that overlay_quad actually gets turned into an overlay, and even
2214 // though it's not drawn, that its sync point is waited on.
2215 EXPECT_CALL(*context, waitSyncPoint(sync_point)).Times(1);
2216 EXPECT_CALL(overlay_scheduler,
2217 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, viewport_rect,
2218 BoundingRect(uv_top_left, uv_bottom_right))).Times(1);
2220 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2221 viewport_rect, false);
2224 } // namespace
2225 } // namespace cc