Add ICU message format support
[chromium-blink-merge.git] / cc / output / gl_renderer_unittest.cc
blobc3866d7d38f816a6696f36edf6c35f0ad3b3d11c
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/gl_renderer.h"
7 #include <set>
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "cc/base/math_util.h"
13 #include "cc/output/compositor_frame_metadata.h"
14 #include "cc/output/copy_output_request.h"
15 #include "cc/output/copy_output_result.h"
16 #include "cc/output/overlay_strategy_single_on_top.h"
17 #include "cc/output/texture_mailbox_deleter.h"
18 #include "cc/quads/texture_draw_quad.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/test/fake_impl_proxy.h"
21 #include "cc/test/fake_layer_tree_host_impl.h"
22 #include "cc/test/fake_output_surface.h"
23 #include "cc/test/fake_output_surface_client.h"
24 #include "cc/test/fake_renderer_client.h"
25 #include "cc/test/fake_resource_provider.h"
26 #include "cc/test/pixel_test.h"
27 #include "cc/test/render_pass_test_common.h"
28 #include "cc/test/render_pass_test_utils.h"
29 #include "cc/test/test_shared_bitmap_manager.h"
30 #include "cc/test/test_web_graphics_context_3d.h"
31 #include "gpu/GLES2/gl2extchromium.h"
32 #include "gpu/command_buffer/client/context_support.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/skia/include/core/SkImageFilter.h"
36 #include "third_party/skia/include/core/SkMatrix.h"
37 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
38 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
39 #include "ui/gfx/transform.h"
41 using testing::_;
42 using testing::AnyNumber;
43 using testing::Args;
44 using testing::AtLeast;
45 using testing::ElementsAre;
46 using testing::Expectation;
47 using testing::InSequence;
48 using testing::Mock;
49 using testing::Return;
50 using testing::StrictMock;
52 namespace cc {
54 class GLRendererTest : public testing::Test {
55 protected:
56 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
58 RenderPassList render_passes_in_draw_order_;
61 #define EXPECT_PROGRAM_VALID(program_binding) \
62 do { \
63 EXPECT_TRUE((program_binding)->program()); \
64 EXPECT_TRUE((program_binding)->initialized()); \
65 } while (false)
67 static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
68 switch (blend_mode) {
69 case BLEND_MODE_NONE:
70 case BLEND_MODE_NORMAL:
71 return SkXfermode::kSrcOver_Mode;
72 case BLEND_MODE_SCREEN:
73 return SkXfermode::kScreen_Mode;
74 case BLEND_MODE_OVERLAY:
75 return SkXfermode::kOverlay_Mode;
76 case BLEND_MODE_DARKEN:
77 return SkXfermode::kDarken_Mode;
78 case BLEND_MODE_LIGHTEN:
79 return SkXfermode::kLighten_Mode;
80 case BLEND_MODE_COLOR_DODGE:
81 return SkXfermode::kColorDodge_Mode;
82 case BLEND_MODE_COLOR_BURN:
83 return SkXfermode::kColorBurn_Mode;
84 case BLEND_MODE_HARD_LIGHT:
85 return SkXfermode::kHardLight_Mode;
86 case BLEND_MODE_SOFT_LIGHT:
87 return SkXfermode::kSoftLight_Mode;
88 case BLEND_MODE_DIFFERENCE:
89 return SkXfermode::kDifference_Mode;
90 case BLEND_MODE_EXCLUSION:
91 return SkXfermode::kExclusion_Mode;
92 case BLEND_MODE_MULTIPLY:
93 return SkXfermode::kMultiply_Mode;
94 case BLEND_MODE_HUE:
95 return SkXfermode::kHue_Mode;
96 case BLEND_MODE_SATURATION:
97 return SkXfermode::kSaturation_Mode;
98 case BLEND_MODE_COLOR:
99 return SkXfermode::kColor_Mode;
100 case BLEND_MODE_LUMINOSITY:
101 return SkXfermode::kLuminosity_Mode;
103 return SkXfermode::kSrcOver_Mode;
106 // Explicitly named to be a friend in GLRenderer for shader access.
107 class GLRendererShaderPixelTest : public GLRendererPixelTest {
108 public:
109 void SetUp() override {
110 GLRendererPixelTest::SetUp();
111 ASSERT_FALSE(renderer()->IsContextLost());
114 void TearDown() override {
115 GLRendererPixelTest::TearDown();
116 ASSERT_FALSE(renderer()->IsContextLost());
119 void TestBasicShaders() {
120 EXPECT_PROGRAM_VALID(renderer()->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 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
549 RenderPassId(1, 0),
550 viewport_rect,
551 gfx::Transform());
552 root_pass->has_transparent_background = false;
554 renderer_->DrawFrame(&render_passes_in_draw_order_,
555 1.f,
556 viewport_rect,
557 viewport_rect,
558 false);
559 EXPECT_TRUE(renderer_->stencil_enabled());
562 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
563 public:
564 ForbidSynchronousCallContext() {}
566 void getAttachedShaders(GLuint program,
567 GLsizei max_count,
568 GLsizei* count,
569 GLuint* shaders) override {
570 ADD_FAILURE();
572 GLint getAttribLocation(GLuint program, const GLchar* name) override {
573 ADD_FAILURE();
574 return 0;
576 void getBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
577 void getBufferParameteriv(GLenum target,
578 GLenum pname,
579 GLint* value) override {
580 ADD_FAILURE();
582 GLenum getError() override {
583 ADD_FAILURE();
584 return GL_NO_ERROR;
586 void getFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
587 void getFramebufferAttachmentParameteriv(GLenum target,
588 GLenum attachment,
589 GLenum pname,
590 GLint* value) override {
591 ADD_FAILURE();
593 void getIntegerv(GLenum pname, GLint* value) override {
594 if (pname == GL_MAX_TEXTURE_SIZE) {
595 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
596 *value = 1024;
597 } else {
598 ADD_FAILURE();
602 // We allow querying the shader compilation and program link status in debug
603 // mode, but not release.
604 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
605 #ifndef NDEBUG
606 *value = 1;
607 #else
608 ADD_FAILURE();
609 #endif
612 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
613 #ifndef NDEBUG
614 *value = 1;
615 #else
616 ADD_FAILURE();
617 #endif
620 void getRenderbufferParameteriv(GLenum target,
621 GLenum pname,
622 GLint* value) override {
623 ADD_FAILURE();
626 void getShaderPrecisionFormat(GLenum shadertype,
627 GLenum precisiontype,
628 GLint* range,
629 GLint* precision) override {
630 ADD_FAILURE();
632 void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
633 ADD_FAILURE();
635 void getTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
636 ADD_FAILURE();
638 void getUniformfv(GLuint program, GLint location, GLfloat* value) override {
639 ADD_FAILURE();
641 void getUniformiv(GLuint program, GLint location, GLint* value) override {
642 ADD_FAILURE();
644 GLint getUniformLocation(GLuint program, const GLchar* name) override {
645 ADD_FAILURE();
646 return 0;
648 void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
649 ADD_FAILURE();
651 void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
652 ADD_FAILURE();
654 GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname) override {
655 ADD_FAILURE();
656 return 0;
659 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
660 FakeOutputSurfaceClient output_surface_client;
661 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
662 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
663 CHECK(output_surface->BindToClient(&output_surface_client));
665 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
666 new TestSharedBitmapManager());
667 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
668 output_surface.get(), shared_bitmap_manager.get());
670 RendererSettings settings;
671 FakeRendererClient renderer_client;
672 FakeRendererGL renderer(&renderer_client,
673 &settings,
674 output_surface.get(),
675 resource_provider.get());
678 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
679 public:
680 LoseContextOnFirstGetContext() {}
682 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
683 context_lost_ = true;
684 *value = 0;
687 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
688 context_lost_ = true;
689 *value = 0;
693 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
694 FakeOutputSurfaceClient output_surface_client;
695 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
696 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
697 CHECK(output_surface->BindToClient(&output_surface_client));
699 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
700 new TestSharedBitmapManager());
701 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
702 output_surface.get(), shared_bitmap_manager.get());
704 RendererSettings settings;
705 FakeRendererClient renderer_client;
706 FakeRendererGL renderer(&renderer_client,
707 &settings,
708 output_surface.get(),
709 resource_provider.get());
712 class ClearCountingContext : public TestWebGraphicsContext3D {
713 public:
714 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
716 MOCK_METHOD3(discardFramebufferEXT,
717 void(GLenum target,
718 GLsizei numAttachments,
719 const GLenum* attachments));
720 MOCK_METHOD1(clear, void(GLbitfield mask));
723 TEST_F(GLRendererTest, OpaqueBackground) {
724 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
725 ClearCountingContext* context = context_owned.get();
727 FakeOutputSurfaceClient output_surface_client;
728 scoped_ptr<OutputSurface> output_surface(
729 FakeOutputSurface::Create3d(context_owned.Pass()));
730 CHECK(output_surface->BindToClient(&output_surface_client));
732 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
733 new TestSharedBitmapManager());
734 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
735 output_surface.get(), shared_bitmap_manager.get());
737 RendererSettings settings;
738 FakeRendererClient renderer_client;
739 FakeRendererGL renderer(&renderer_client,
740 &settings,
741 output_surface.get(),
742 resource_provider.get());
744 gfx::Rect viewport_rect(1, 1);
745 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
746 RenderPassId(1, 0),
747 viewport_rect,
748 gfx::Transform());
749 root_pass->has_transparent_background = false;
751 // On DEBUG builds, render passes with opaque background clear to blue to
752 // easily see regions that were not drawn on the screen.
753 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
754 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
755 .Times(1);
756 #ifdef NDEBUG
757 EXPECT_CALL(*context, clear(_)).Times(0);
758 #else
759 EXPECT_CALL(*context, clear(_)).Times(1);
760 #endif
761 renderer.DrawFrame(&render_passes_in_draw_order_,
762 1.f,
763 viewport_rect,
764 viewport_rect,
765 false);
766 Mock::VerifyAndClearExpectations(context);
769 TEST_F(GLRendererTest, TransparentBackground) {
770 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
771 ClearCountingContext* context = context_owned.get();
773 FakeOutputSurfaceClient output_surface_client;
774 scoped_ptr<OutputSurface> output_surface(
775 FakeOutputSurface::Create3d(context_owned.Pass()));
776 CHECK(output_surface->BindToClient(&output_surface_client));
778 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
779 new TestSharedBitmapManager());
780 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
781 output_surface.get(), shared_bitmap_manager.get());
783 RendererSettings settings;
784 FakeRendererClient renderer_client;
785 FakeRendererGL renderer(&renderer_client,
786 &settings,
787 output_surface.get(),
788 resource_provider.get());
790 gfx::Rect viewport_rect(1, 1);
791 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
792 RenderPassId(1, 0),
793 viewport_rect,
794 gfx::Transform());
795 root_pass->has_transparent_background = true;
797 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
798 EXPECT_CALL(*context, clear(_)).Times(1);
799 renderer.DrawFrame(&render_passes_in_draw_order_,
800 1.f,
801 viewport_rect,
802 viewport_rect,
803 false);
805 Mock::VerifyAndClearExpectations(context);
808 TEST_F(GLRendererTest, OffscreenOutputSurface) {
809 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
810 ClearCountingContext* context = context_owned.get();
812 FakeOutputSurfaceClient output_surface_client;
813 scoped_ptr<OutputSurface> output_surface(
814 FakeOutputSurface::CreateOffscreen(context_owned.Pass()));
815 CHECK(output_surface->BindToClient(&output_surface_client));
817 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
818 new TestSharedBitmapManager());
819 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
820 output_surface.get(), shared_bitmap_manager.get());
822 RendererSettings settings;
823 FakeRendererClient renderer_client;
824 FakeRendererGL renderer(&renderer_client,
825 &settings,
826 output_surface.get(),
827 resource_provider.get());
829 gfx::Rect viewport_rect(1, 1);
830 AddRenderPass(&render_passes_in_draw_order_,
831 RenderPassId(1, 0),
832 viewport_rect,
833 gfx::Transform());
835 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
836 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
837 .Times(1);
838 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
839 renderer.DrawFrame(&render_passes_in_draw_order_,
840 1.f,
841 viewport_rect,
842 viewport_rect,
843 false);
844 Mock::VerifyAndClearExpectations(context);
847 class VisibilityChangeIsLastCallTrackingContext
848 : public TestWebGraphicsContext3D {
849 public:
850 VisibilityChangeIsLastCallTrackingContext()
851 : last_call_was_set_visibility_(false) {}
853 // TestWebGraphicsContext3D methods.
854 void flush() override { last_call_was_set_visibility_ = false; }
855 void deleteTexture(GLuint) override { last_call_was_set_visibility_ = false; }
856 void deleteFramebuffer(GLuint) override {
857 last_call_was_set_visibility_ = false;
859 void deleteQueryEXT(GLuint) override {
860 last_call_was_set_visibility_ = false;
862 void deleteRenderbuffer(GLuint) override {
863 last_call_was_set_visibility_ = false;
866 // Methods added for test.
867 void set_last_call_was_visibility(bool visible) {
868 DCHECK(last_call_was_set_visibility_ == false);
869 last_call_was_set_visibility_ = true;
871 bool last_call_was_set_visibility() const {
872 return last_call_was_set_visibility_;
875 private:
876 bool last_call_was_set_visibility_;
879 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
880 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
881 new VisibilityChangeIsLastCallTrackingContext);
882 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
884 scoped_refptr<TestContextProvider> provider =
885 TestContextProvider::Create(context_owned.Pass());
887 provider->support()->SetSurfaceVisibleCallback(base::Bind(
888 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
889 base::Unretained(context)));
891 FakeOutputSurfaceClient output_surface_client;
892 scoped_ptr<OutputSurface> output_surface(
893 FakeOutputSurface::Create3d(provider));
894 CHECK(output_surface->BindToClient(&output_surface_client));
896 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
897 new TestSharedBitmapManager());
898 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
899 output_surface.get(), shared_bitmap_manager.get());
901 RendererSettings settings;
902 FakeRendererClient renderer_client;
903 FakeRendererGL renderer(&renderer_client,
904 &settings,
905 output_surface.get(),
906 resource_provider.get());
908 gfx::Rect viewport_rect(1, 1);
909 AddRenderPass(&render_passes_in_draw_order_,
910 RenderPassId(1, 0),
911 viewport_rect,
912 gfx::Transform());
914 // Ensure that the call to SetSurfaceVisible is the last call issue to the
915 // GPU process, after glFlush is called, and after the RendererClient's
916 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
917 // RenderClient and the Context by giving them both a pointer to a variable on
918 // the stack.
919 renderer.SetVisible(true);
920 renderer.DrawFrame(&render_passes_in_draw_order_,
921 1.f,
922 viewport_rect,
923 viewport_rect,
924 false);
925 renderer.SetVisible(false);
926 EXPECT_TRUE(context->last_call_was_set_visibility());
929 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
930 public:
931 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
932 test_capabilities_.gpu.egl_image_external = true;
935 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
936 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
937 MOCK_METHOD4(drawElements,
938 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
940 virtual void activeTexture(GLenum texture) {
941 EXPECT_NE(texture, active_texture_);
942 active_texture_ = texture;
945 GLenum active_texture() const { return active_texture_; }
947 private:
948 GLenum active_texture_;
951 TEST_F(GLRendererTest, ActiveTextureState) {
952 scoped_ptr<TextureStateTrackingContext> context_owned(
953 new TextureStateTrackingContext);
954 TextureStateTrackingContext* context = context_owned.get();
956 FakeOutputSurfaceClient output_surface_client;
957 scoped_ptr<OutputSurface> output_surface(
958 FakeOutputSurface::Create3d(context_owned.Pass()));
959 CHECK(output_surface->BindToClient(&output_surface_client));
961 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
962 new TestSharedBitmapManager());
963 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
964 output_surface.get(), shared_bitmap_manager.get());
966 RendererSettings settings;
967 FakeRendererClient renderer_client;
968 FakeRendererGL renderer(&renderer_client,
969 &settings,
970 output_surface.get(),
971 resource_provider.get());
973 // During initialization we are allowed to set any texture parameters.
974 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
976 TestRenderPass* root_pass =
977 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 1),
978 gfx::Rect(100, 100), gfx::Transform());
979 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
980 RenderPassId(0, 0));
982 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
984 // Set up expected texture filter state transitions that match the quads
985 // created in AppendOneOfEveryQuadType().
986 Mock::VerifyAndClearExpectations(context);
988 InSequence sequence;
990 // The sync points for all quads are waited on first. This sync point is
991 // for a texture quad drawn later in the frame.
992 EXPECT_CALL(*context,
993 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
994 .Times(1);
996 // yuv_quad is drawn with the default linear filter.
997 EXPECT_CALL(*context, drawElements(_, _, _, _));
999 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1000 // scaled.
1001 EXPECT_CALL(
1002 *context,
1003 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1004 EXPECT_CALL(
1005 *context,
1006 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1007 EXPECT_CALL(*context, drawElements(_, _, _, _));
1009 // transformed_tile_quad uses GL_LINEAR.
1010 EXPECT_CALL(*context, drawElements(_, _, _, _));
1012 // scaled_tile_quad also uses GL_LINEAR.
1013 EXPECT_CALL(*context, drawElements(_, _, _, _));
1015 // The remaining quads also use GL_LINEAR because nearest neighbor
1016 // filtering is currently only used with tile quads.
1017 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6);
1020 gfx::Rect viewport_rect(100, 100);
1021 renderer.DrawFrame(&render_passes_in_draw_order_,
1022 1.f,
1023 viewport_rect,
1024 viewport_rect,
1025 false);
1026 Mock::VerifyAndClearExpectations(context);
1029 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
1030 public:
1031 MOCK_METHOD1(clear, void(GLbitfield mask));
1032 MOCK_METHOD4(drawElements,
1033 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1036 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
1037 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
1038 new NoClearRootRenderPassMockContext);
1039 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
1041 FakeOutputSurfaceClient output_surface_client;
1042 scoped_ptr<OutputSurface> output_surface(
1043 FakeOutputSurface::Create3d(mock_context_owned.Pass()));
1044 CHECK(output_surface->BindToClient(&output_surface_client));
1046 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1047 new TestSharedBitmapManager());
1048 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1049 output_surface.get(), shared_bitmap_manager.get());
1051 RendererSettings settings;
1052 settings.should_clear_root_render_pass = false;
1054 FakeRendererClient renderer_client;
1055 FakeRendererGL renderer(&renderer_client,
1056 &settings,
1057 output_surface.get(),
1058 resource_provider.get());
1060 gfx::Rect viewport_rect(10, 10);
1062 RenderPassId child_pass_id(2, 0);
1063 TestRenderPass* child_pass =
1064 AddRenderPass(&render_passes_in_draw_order_, child_pass_id, viewport_rect,
1065 gfx::Transform());
1066 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
1068 RenderPassId root_pass_id(1, 0);
1069 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1070 root_pass_id,
1071 viewport_rect,
1072 gfx::Transform());
1073 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1076 AddRenderPassQuad(root_pass, child_pass);
1078 #ifdef NDEBUG
1079 GLint clear_bits = GL_COLOR_BUFFER_BIT;
1080 #else
1081 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1082 #endif
1084 // First render pass is not the root one, clearing should happen.
1085 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
1087 Expectation first_render_pass =
1088 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
1090 // The second render pass is the root one, clearing should be prevented.
1091 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
1092 first_render_pass);
1094 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
1095 first_render_pass);
1097 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1098 renderer.DrawFrame(&render_passes_in_draw_order_,
1099 1.f,
1100 viewport_rect,
1101 viewport_rect,
1102 false);
1104 // In multiple render passes all but the root pass should clear the
1105 // framebuffer.
1106 Mock::VerifyAndClearExpectations(&mock_context);
1109 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
1110 public:
1111 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1113 void clear(GLbitfield) override { EXPECT_FALSE(scissor_enabled_); }
1115 void enable(GLenum cap) override {
1116 if (cap == GL_SCISSOR_TEST)
1117 scissor_enabled_ = true;
1120 void disable(GLenum cap) override {
1121 if (cap == GL_SCISSOR_TEST)
1122 scissor_enabled_ = false;
1125 private:
1126 bool scissor_enabled_;
1129 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
1130 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
1131 new ScissorTestOnClearCheckingContext);
1133 FakeOutputSurfaceClient output_surface_client;
1134 scoped_ptr<OutputSurface> output_surface(
1135 FakeOutputSurface::Create3d(context_owned.Pass()));
1136 CHECK(output_surface->BindToClient(&output_surface_client));
1138 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1139 new TestSharedBitmapManager());
1140 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1141 output_surface.get(), shared_bitmap_manager.get());
1143 RendererSettings settings;
1144 FakeRendererClient renderer_client;
1145 FakeRendererGL renderer(&renderer_client,
1146 &settings,
1147 output_surface.get(),
1148 resource_provider.get());
1149 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1151 gfx::Rect viewport_rect(1, 1);
1153 gfx::Rect grand_child_rect(25, 25);
1154 RenderPassId grand_child_pass_id(3, 0);
1155 TestRenderPass* grand_child_pass =
1156 AddRenderPass(&render_passes_in_draw_order_,
1157 grand_child_pass_id,
1158 grand_child_rect,
1159 gfx::Transform());
1160 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
1162 gfx::Rect child_rect(50, 50);
1163 RenderPassId child_pass_id(2, 0);
1164 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
1165 child_pass_id,
1166 child_rect,
1167 gfx::Transform());
1168 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1170 RenderPassId root_pass_id(1, 0);
1171 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1172 root_pass_id,
1173 viewport_rect,
1174 gfx::Transform());
1175 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1177 AddRenderPassQuad(root_pass, child_pass);
1178 AddRenderPassQuad(child_pass, grand_child_pass);
1180 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1181 renderer.DrawFrame(&render_passes_in_draw_order_,
1182 1.f,
1183 viewport_rect,
1184 viewport_rect,
1185 false);
1188 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1189 public:
1190 DiscardCheckingContext() : discarded_(0) {
1191 set_have_post_sub_buffer(true);
1192 set_have_discard_framebuffer(true);
1195 void discardFramebufferEXT(GLenum target,
1196 GLsizei numAttachments,
1197 const GLenum* attachments) override {
1198 ++discarded_;
1201 int discarded() const { return discarded_; }
1202 void reset() { discarded_ = 0; }
1204 private:
1205 int discarded_;
1208 class NonReshapableOutputSurface : public FakeOutputSurface {
1209 public:
1210 explicit NonReshapableOutputSurface(
1211 scoped_ptr<TestWebGraphicsContext3D> context3d)
1212 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1213 false) {
1214 surface_size_ = gfx::Size(500, 500);
1216 void Reshape(const gfx::Size& size, float scale_factor) override {}
1217 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1220 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1221 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1222 DiscardCheckingContext* context = context_owned.get();
1224 FakeOutputSurfaceClient output_surface_client;
1225 scoped_ptr<NonReshapableOutputSurface> output_surface(
1226 new NonReshapableOutputSurface(context_owned.Pass()));
1227 CHECK(output_surface->BindToClient(&output_surface_client));
1228 output_surface->set_fixed_size(gfx::Size(100, 100));
1230 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1231 new TestSharedBitmapManager());
1232 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1233 output_surface.get(), shared_bitmap_manager.get());
1235 RendererSettings settings;
1236 settings.partial_swap_enabled = true;
1237 FakeRendererClient renderer_client;
1238 FakeRendererGL renderer(&renderer_client,
1239 &settings,
1240 output_surface.get(),
1241 resource_provider.get());
1242 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1244 gfx::Rect viewport_rect(100, 100);
1245 gfx::Rect clip_rect(100, 100);
1248 // Partial frame, should not discard.
1249 RenderPassId root_pass_id(1, 0);
1250 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1251 root_pass_id,
1252 viewport_rect,
1253 gfx::Transform());
1254 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1255 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1257 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1258 renderer.DrawFrame(&render_passes_in_draw_order_,
1259 1.f,
1260 viewport_rect,
1261 clip_rect,
1262 false);
1263 EXPECT_EQ(0, context->discarded());
1264 context->reset();
1267 // Full frame, should discard.
1268 RenderPassId root_pass_id(1, 0);
1269 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1270 root_pass_id,
1271 viewport_rect,
1272 gfx::Transform());
1273 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1274 root_pass->damage_rect = root_pass->output_rect;
1276 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1277 renderer.DrawFrame(&render_passes_in_draw_order_,
1278 1.f,
1279 viewport_rect,
1280 clip_rect,
1281 false);
1282 EXPECT_EQ(1, context->discarded());
1283 context->reset();
1286 // Full frame, external scissor is set, should not discard.
1287 output_surface->set_has_external_stencil_test(true);
1288 RenderPassId root_pass_id(1, 0);
1289 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1290 root_pass_id,
1291 viewport_rect,
1292 gfx::Transform());
1293 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1294 root_pass->damage_rect = root_pass->output_rect;
1295 root_pass->has_transparent_background = false;
1297 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1298 renderer.DrawFrame(&render_passes_in_draw_order_,
1299 1.f,
1300 viewport_rect,
1301 clip_rect,
1302 false);
1303 EXPECT_EQ(0, context->discarded());
1304 context->reset();
1305 output_surface->set_has_external_stencil_test(false);
1308 // Full frame, clipped, should not discard.
1309 clip_rect = gfx::Rect(10, 10, 10, 10);
1310 RenderPassId root_pass_id(1, 0);
1311 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1312 root_pass_id,
1313 viewport_rect,
1314 gfx::Transform());
1315 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1316 root_pass->damage_rect = root_pass->output_rect;
1318 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1319 renderer.DrawFrame(&render_passes_in_draw_order_,
1320 1.f,
1321 viewport_rect,
1322 clip_rect,
1323 false);
1324 EXPECT_EQ(0, context->discarded());
1325 context->reset();
1328 // Full frame, doesn't cover the surface, should not discard.
1329 viewport_rect = gfx::Rect(10, 10, 10, 10);
1330 RenderPassId root_pass_id(1, 0);
1331 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1332 root_pass_id,
1333 viewport_rect,
1334 gfx::Transform());
1335 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1336 root_pass->damage_rect = root_pass->output_rect;
1338 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1339 renderer.DrawFrame(&render_passes_in_draw_order_,
1340 1.f,
1341 viewport_rect,
1342 clip_rect,
1343 false);
1344 EXPECT_EQ(0, context->discarded());
1345 context->reset();
1348 // Full frame, doesn't cover the surface (no offset), should not discard.
1349 clip_rect = gfx::Rect(100, 100);
1350 viewport_rect = gfx::Rect(50, 50);
1351 RenderPassId root_pass_id(1, 0);
1352 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1353 root_pass_id,
1354 viewport_rect,
1355 gfx::Transform());
1356 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1357 root_pass->damage_rect = root_pass->output_rect;
1359 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1360 renderer.DrawFrame(&render_passes_in_draw_order_,
1361 1.f,
1362 viewport_rect,
1363 clip_rect,
1364 false);
1365 EXPECT_EQ(0, context->discarded());
1366 context->reset();
1370 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1371 public:
1372 MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
1373 MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
1376 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1377 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1378 // and maintains a fixed size. This test verifies that glViewport and
1379 // glScissor's Y coordinate is flipped correctly in this environment, and that
1380 // the glViewport can be at a nonzero origin within the surface.
1381 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1382 new FlippedScissorAndViewportContext);
1384 // We expect exactly one call to viewport on this context and exactly two
1385 // to scissor (one to scissor the clear, one to scissor the quad draw).
1386 EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100));
1387 EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100));
1388 EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20));
1390 FakeOutputSurfaceClient output_surface_client;
1391 scoped_ptr<OutputSurface> output_surface(
1392 new NonReshapableOutputSurface(context_owned.Pass()));
1393 CHECK(output_surface->BindToClient(&output_surface_client));
1395 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1396 new TestSharedBitmapManager());
1397 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1398 output_surface.get(), shared_bitmap_manager.get());
1400 RendererSettings settings;
1401 FakeRendererClient renderer_client;
1402 FakeRendererGL renderer(&renderer_client,
1403 &settings,
1404 output_surface.get(),
1405 resource_provider.get());
1406 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1408 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1409 gfx::Rect viewport_rect(device_viewport_rect.size());
1410 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1412 RenderPassId root_pass_id(1, 0);
1413 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1414 root_pass_id,
1415 viewport_rect,
1416 gfx::Transform());
1417 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1419 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1420 renderer.DrawFrame(&render_passes_in_draw_order_,
1421 1.f,
1422 device_viewport_rect,
1423 device_viewport_rect,
1424 false);
1427 TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
1428 // When using render-to-FBO to display the surface, all rendering is done
1429 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1430 // the correct framebuffer during rendering, if changed.
1431 // Note: there is one path that will set it to 0, but that is after the render
1432 // has finished.
1433 FakeOutputSurfaceClient output_surface_client;
1434 scoped_ptr<FakeOutputSurface> output_surface(
1435 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1436 CHECK(output_surface->BindToClient(&output_surface_client));
1438 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1439 new TestSharedBitmapManager());
1440 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
1441 output_surface.get(), shared_bitmap_manager.get());
1443 RendererSettings settings;
1444 FakeRendererClient renderer_client;
1445 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
1446 resource_provider.get());
1447 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1449 gfx::Rect device_viewport_rect(0, 0, 100, 100);
1450 gfx::Rect viewport_rect(device_viewport_rect.size());
1451 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1453 RenderPassId root_pass_id(1, 0);
1454 TestRenderPass* root_pass =
1455 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1456 gfx::Transform());
1457 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1459 unsigned fbo;
1460 gpu::gles2::GLES2Interface* gl =
1461 output_surface->context_provider()->ContextGL();
1462 gl->GenFramebuffers(1, &fbo);
1463 output_surface->set_framebuffer(fbo);
1465 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1466 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect,
1467 device_viewport_rect, false);
1469 int bound_fbo;
1470 gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
1471 EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
1474 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1475 gfx::Rect viewport_rect(1, 1);
1477 gfx::Rect child_rect(50, 50);
1478 RenderPassId child_pass_id(2, 0);
1479 TestRenderPass* child_pass;
1481 RenderPassId root_pass_id(1, 0);
1482 TestRenderPass* root_pass;
1484 ResourceId mask = resource_provider_->CreateResource(
1485 gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
1486 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
1487 resource_provider_->best_texture_format());
1488 resource_provider_->AllocateForTesting(mask);
1490 SkScalar matrix[20];
1491 float amount = 0.5f;
1492 matrix[0] = 0.213f + 0.787f * amount;
1493 matrix[1] = 0.715f - 0.715f * amount;
1494 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1495 matrix[3] = matrix[4] = 0;
1496 matrix[5] = 0.213f - 0.213f * amount;
1497 matrix[6] = 0.715f + 0.285f * amount;
1498 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1499 matrix[8] = matrix[9] = 0;
1500 matrix[10] = 0.213f - 0.213f * amount;
1501 matrix[11] = 0.715f - 0.715f * amount;
1502 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1503 matrix[13] = matrix[14] = 0;
1504 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1505 matrix[18] = 1;
1506 skia::RefPtr<SkColorFilter> color_filter(
1507 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1508 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1509 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1510 FilterOperations filters;
1511 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1513 gfx::Transform transform_causing_aa;
1514 transform_causing_aa.Rotate(20.0);
1516 for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
1517 BlendMode blend_mode = static_cast<BlendMode>(i);
1518 SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
1519 settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
1520 // RenderPassProgram
1521 render_passes_in_draw_order_.clear();
1522 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1523 child_pass_id,
1524 child_rect,
1525 gfx::Transform());
1527 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1528 root_pass_id,
1529 viewport_rect,
1530 gfx::Transform());
1532 AddRenderPassQuad(root_pass,
1533 child_pass,
1535 FilterOperations(),
1536 gfx::Transform(),
1537 xfer_mode);
1539 renderer_->DecideRenderPassAllocationsForFrame(
1540 render_passes_in_draw_order_);
1541 renderer_->DrawFrame(&render_passes_in_draw_order_,
1542 1.f,
1543 viewport_rect,
1544 viewport_rect,
1545 false);
1546 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1548 // RenderPassColorMatrixProgram
1549 render_passes_in_draw_order_.clear();
1551 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1552 child_pass_id,
1553 child_rect,
1554 transform_causing_aa);
1556 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1557 root_pass_id,
1558 viewport_rect,
1559 gfx::Transform());
1561 AddRenderPassQuad(
1562 root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
1564 renderer_->DecideRenderPassAllocationsForFrame(
1565 render_passes_in_draw_order_);
1566 renderer_->DrawFrame(&render_passes_in_draw_order_,
1567 1.f,
1568 viewport_rect,
1569 viewport_rect,
1570 false);
1571 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1573 // RenderPassMaskProgram
1574 render_passes_in_draw_order_.clear();
1576 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1577 child_pass_id,
1578 child_rect,
1579 gfx::Transform());
1581 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1582 root_pass_id,
1583 viewport_rect,
1584 gfx::Transform());
1586 AddRenderPassQuad(root_pass,
1587 child_pass,
1588 mask,
1589 FilterOperations(),
1590 gfx::Transform(),
1591 xfer_mode);
1593 renderer_->DecideRenderPassAllocationsForFrame(
1594 render_passes_in_draw_order_);
1595 renderer_->DrawFrame(&render_passes_in_draw_order_,
1596 1.f,
1597 viewport_rect,
1598 viewport_rect,
1599 false);
1600 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1601 blend_mode);
1603 // RenderPassMaskColorMatrixProgram
1604 render_passes_in_draw_order_.clear();
1606 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1607 child_pass_id,
1608 child_rect,
1609 gfx::Transform());
1611 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1612 root_pass_id,
1613 viewport_rect,
1614 gfx::Transform());
1616 AddRenderPassQuad(
1617 root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
1619 renderer_->DecideRenderPassAllocationsForFrame(
1620 render_passes_in_draw_order_);
1621 renderer_->DrawFrame(&render_passes_in_draw_order_,
1622 1.f,
1623 viewport_rect,
1624 viewport_rect,
1625 false);
1626 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
1627 SAMPLER_TYPE_2D, blend_mode);
1629 // RenderPassProgramAA
1630 render_passes_in_draw_order_.clear();
1632 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1633 child_pass_id,
1634 child_rect,
1635 transform_causing_aa);
1637 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1638 root_pass_id,
1639 viewport_rect,
1640 gfx::Transform());
1642 AddRenderPassQuad(root_pass,
1643 child_pass,
1645 FilterOperations(),
1646 transform_causing_aa,
1647 xfer_mode);
1649 renderer_->DecideRenderPassAllocationsForFrame(
1650 render_passes_in_draw_order_);
1651 renderer_->DrawFrame(&render_passes_in_draw_order_,
1652 1.f,
1653 viewport_rect,
1654 viewport_rect,
1655 false);
1656 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1658 // RenderPassColorMatrixProgramAA
1659 render_passes_in_draw_order_.clear();
1661 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1662 child_pass_id,
1663 child_rect,
1664 transform_causing_aa);
1666 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1667 root_pass_id,
1668 viewport_rect,
1669 gfx::Transform());
1671 AddRenderPassQuad(
1672 root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
1674 renderer_->DecideRenderPassAllocationsForFrame(
1675 render_passes_in_draw_order_);
1676 renderer_->DrawFrame(&render_passes_in_draw_order_,
1677 1.f,
1678 viewport_rect,
1679 viewport_rect,
1680 false);
1681 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1683 // RenderPassMaskProgramAA
1684 render_passes_in_draw_order_.clear();
1686 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1687 child_pass_id,
1688 child_rect,
1689 transform_causing_aa);
1691 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1692 root_pass_id,
1693 viewport_rect,
1694 gfx::Transform());
1696 AddRenderPassQuad(root_pass,
1697 child_pass,
1698 mask,
1699 FilterOperations(),
1700 transform_causing_aa,
1701 xfer_mode);
1703 renderer_->DecideRenderPassAllocationsForFrame(
1704 render_passes_in_draw_order_);
1705 renderer_->DrawFrame(&render_passes_in_draw_order_,
1706 1.f,
1707 viewport_rect,
1708 viewport_rect,
1709 false);
1710 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1711 blend_mode);
1713 // RenderPassMaskColorMatrixProgramAA
1714 render_passes_in_draw_order_.clear();
1716 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1717 child_pass_id,
1718 child_rect,
1719 transform_causing_aa);
1721 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1722 root_pass_id,
1723 viewport_rect,
1724 transform_causing_aa);
1726 AddRenderPassQuad(
1727 root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
1729 renderer_->DecideRenderPassAllocationsForFrame(
1730 render_passes_in_draw_order_);
1731 renderer_->DrawFrame(&render_passes_in_draw_order_,
1732 1.f,
1733 viewport_rect,
1734 viewport_rect,
1735 false);
1736 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
1737 SAMPLER_TYPE_2D, blend_mode);
1741 // At this time, the AA code path cannot be taken if the surface's rect would
1742 // project incorrectly by the given transform, because of w<0 clipping.
1743 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1744 gfx::Rect child_rect(50, 50);
1745 RenderPassId child_pass_id(2, 0);
1746 TestRenderPass* child_pass;
1748 gfx::Rect viewport_rect(1, 1);
1749 RenderPassId root_pass_id(1, 0);
1750 TestRenderPass* root_pass;
1752 gfx::Transform transform_preventing_aa;
1753 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1754 transform_preventing_aa.RotateAboutYAxis(-20.0);
1755 transform_preventing_aa.Scale(30.0, 1.0);
1757 // Verify that the test transform and test rect actually do cause the clipped
1758 // flag to trigger. Otherwise we are not testing the intended scenario.
1759 bool clipped = false;
1760 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1761 ASSERT_TRUE(clipped);
1763 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1764 child_pass_id,
1765 child_rect,
1766 transform_preventing_aa);
1768 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1769 root_pass_id,
1770 viewport_rect,
1771 gfx::Transform());
1773 AddRenderPassQuad(root_pass,
1774 child_pass,
1776 FilterOperations(),
1777 transform_preventing_aa,
1778 SkXfermode::kSrcOver_Mode);
1780 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1781 renderer_->DrawFrame(&render_passes_in_draw_order_,
1782 1.f,
1783 viewport_rect,
1784 viewport_rect,
1785 false);
1787 // If use_aa incorrectly ignores clipping, it will use the
1788 // RenderPassProgramAA shader instead of the RenderPassProgram.
1789 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
1792 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1793 gfx::Rect viewport_rect(1, 1);
1794 RenderPassId root_pass_id(1, 0);
1795 TestRenderPass* root_pass;
1797 gfx::Transform pixel_aligned_transform_causing_aa;
1798 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1799 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1801 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1802 root_pass_id,
1803 viewport_rect,
1804 gfx::Transform());
1805 AddTransformedQuad(root_pass,
1806 viewport_rect,
1807 SK_ColorYELLOW,
1808 pixel_aligned_transform_causing_aa);
1810 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1811 renderer_->DrawFrame(&render_passes_in_draw_order_,
1812 1.f,
1813 viewport_rect,
1814 viewport_rect,
1815 false);
1817 TestSolidColorProgramAA();
1820 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1821 public:
1822 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1824 // Specifically override methods even if they are unused (used in conjunction
1825 // with StrictMock). We need to make sure that GLRenderer does not issue
1826 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1827 // through the OutputSurface abstraction.
1828 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1829 MOCK_METHOD3(reshapeWithScaleFactor,
1830 void(int width, int height, float scale_factor));
1831 MOCK_METHOD4(drawElements,
1832 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1835 class MockOutputSurface : public OutputSurface {
1836 public:
1837 MockOutputSurface()
1838 : OutputSurface(
1839 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1840 new StrictMock<OutputSurfaceMockContext>))) {
1841 surface_size_ = gfx::Size(100, 100);
1843 virtual ~MockOutputSurface() {}
1845 MOCK_METHOD0(EnsureBackbuffer, void());
1846 MOCK_METHOD0(DiscardBackbuffer, void());
1847 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1848 MOCK_METHOD0(BindFramebuffer, void());
1849 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1852 class MockOutputSurfaceTest : public GLRendererTest {
1853 protected:
1854 virtual void SetUp() {
1855 FakeOutputSurfaceClient output_surface_client_;
1856 CHECK(output_surface_.BindToClient(&output_surface_client_));
1858 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1859 resource_provider_ = FakeResourceProvider::Create(
1860 &output_surface_, shared_bitmap_manager_.get());
1862 renderer_.reset(new FakeRendererGL(&renderer_client_,
1863 &settings_,
1864 &output_surface_,
1865 resource_provider_.get()));
1868 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1870 void DrawFrame(float device_scale_factor,
1871 const gfx::Rect& device_viewport_rect) {
1872 RenderPassId render_pass_id(1, 0);
1873 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1874 render_pass_id,
1875 device_viewport_rect,
1876 gfx::Transform());
1877 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1879 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1881 EXPECT_CALL(output_surface_,
1882 Reshape(device_viewport_rect.size(), device_scale_factor))
1883 .Times(1);
1885 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1887 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1889 renderer_->DecideRenderPassAllocationsForFrame(
1890 render_passes_in_draw_order_);
1891 renderer_->DrawFrame(&render_passes_in_draw_order_,
1892 device_scale_factor,
1893 device_viewport_rect,
1894 device_viewport_rect,
1895 false);
1898 OutputSurfaceMockContext* Context() {
1899 return static_cast<OutputSurfaceMockContext*>(
1900 static_cast<TestContextProvider*>(output_surface_.context_provider())
1901 ->TestContext3d());
1904 RendererSettings settings_;
1905 FakeOutputSurfaceClient output_surface_client_;
1906 StrictMock<MockOutputSurface> output_surface_;
1907 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1908 scoped_ptr<ResourceProvider> resource_provider_;
1909 FakeRendererClient renderer_client_;
1910 scoped_ptr<FakeRendererGL> renderer_;
1913 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1914 gfx::Rect device_viewport_rect(1, 1);
1915 DrawFrame(1.f, device_viewport_rect);
1917 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1918 renderer_->SwapBuffers(CompositorFrameMetadata());
1921 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1922 gfx::Rect device_viewport_rect(1, 1);
1924 DrawFrame(1.f, device_viewport_rect);
1925 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1926 renderer_->SwapBuffers(CompositorFrameMetadata());
1928 device_viewport_rect = gfx::Rect(2, 2);
1930 DrawFrame(2.f, device_viewport_rect);
1931 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1932 renderer_->SwapBuffers(CompositorFrameMetadata());
1934 DrawFrame(2.f, device_viewport_rect);
1935 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1936 renderer_->SwapBuffers(CompositorFrameMetadata());
1938 device_viewport_rect = gfx::Rect(1, 1);
1940 DrawFrame(1.f, device_viewport_rect);
1941 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1942 renderer_->SwapBuffers(CompositorFrameMetadata());
1945 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1946 protected:
1947 static void SyncPointCallback(int* callback_count) {
1948 ++(*callback_count);
1949 base::MessageLoop::current()->QuitWhenIdle();
1952 static void OtherCallback(int* callback_count) {
1953 ++(*callback_count);
1954 base::MessageLoop::current()->QuitWhenIdle();
1958 #if !defined(OS_ANDROID)
1959 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
1960 int sync_point_callback_count = 0;
1961 int other_callback_count = 0;
1962 gpu::gles2::GLES2Interface* gl =
1963 output_surface_->context_provider()->ContextGL();
1964 gpu::ContextSupport* context_support =
1965 output_surface_->context_provider()->ContextSupport();
1967 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
1969 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
1970 GL_INNOCENT_CONTEXT_RESET_ARB);
1972 context_support->SignalSyncPoint(
1973 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
1974 EXPECT_EQ(0, sync_point_callback_count);
1975 EXPECT_EQ(0, other_callback_count);
1977 // Make the sync point happen.
1978 gl->Finish();
1979 // Post a task after the sync point.
1980 base::ThreadTaskRunnerHandle::Get()->PostTask(
1981 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
1983 base::MessageLoop::current()->Run();
1985 // The sync point shouldn't have happened since the context was lost.
1986 EXPECT_EQ(0, sync_point_callback_count);
1987 EXPECT_EQ(1, other_callback_count);
1990 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
1991 int sync_point_callback_count = 0;
1992 int other_callback_count = 0;
1994 gpu::gles2::GLES2Interface* gl =
1995 output_surface_->context_provider()->ContextGL();
1996 gpu::ContextSupport* context_support =
1997 output_surface_->context_provider()->ContextSupport();
1999 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
2001 context_support->SignalSyncPoint(
2002 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
2003 EXPECT_EQ(0, sync_point_callback_count);
2004 EXPECT_EQ(0, other_callback_count);
2006 // Make the sync point happen.
2007 gl->Finish();
2008 // Post a task after the sync point.
2009 base::ThreadTaskRunnerHandle::Get()->PostTask(
2010 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
2012 base::MessageLoop::current()->Run();
2014 // The sync point should have happened.
2015 EXPECT_EQ(1, sync_point_callback_count);
2016 EXPECT_EQ(1, other_callback_count);
2018 #endif // OS_ANDROID
2020 class TestOverlayProcessor : public OverlayProcessor {
2021 public:
2022 class Strategy : public OverlayProcessor::Strategy {
2023 public:
2024 Strategy() {}
2025 ~Strategy() override {}
2026 MOCK_METHOD2(Attempt,
2027 bool(RenderPassList* render_passes_in_draw_order,
2028 OverlayCandidateList* candidates));
2031 explicit TestOverlayProcessor(OutputSurface* surface)
2032 : OverlayProcessor(surface) {}
2033 ~TestOverlayProcessor() override {}
2034 void Initialize() override {
2035 strategy_ = new Strategy();
2036 strategies_.push_back(scoped_ptr<OverlayProcessor::Strategy>(strategy_));
2039 Strategy* strategy_;
2042 void MailboxReleased(unsigned sync_point,
2043 bool lost_resource,
2044 BlockingTaskRunner* main_thread_task_runner) {
2047 void IgnoreCopyResult(scoped_ptr<CopyOutputResult> result) {
2050 TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
2051 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
2052 FakeOutputSurfaceClient output_surface_client;
2053 scoped_ptr<OutputSurface> output_surface(
2054 FakeOutputSurface::Create3d(context_owned.Pass()));
2055 CHECK(output_surface->BindToClient(&output_surface_client));
2057 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2058 new TestSharedBitmapManager());
2059 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2060 output_surface.get(), shared_bitmap_manager.get());
2061 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2062 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2064 RendererSettings settings;
2065 FakeRendererClient renderer_client;
2066 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2067 resource_provider.get(), mailbox_deleter.get());
2069 TestOverlayProcessor* processor =
2070 new TestOverlayProcessor(output_surface.get());
2071 processor->Initialize();
2072 renderer.SetOverlayProcessor(processor);
2074 gfx::Rect viewport_rect(1, 1);
2075 TestRenderPass* root_pass =
2076 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2077 viewport_rect, gfx::Transform());
2078 root_pass->has_transparent_background = false;
2079 root_pass->copy_requests.push_back(
2080 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreCopyResult)));
2082 unsigned sync_point = 0;
2083 TextureMailbox mailbox =
2084 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2085 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2086 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2087 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2088 mailbox, release_callback.Pass());
2089 bool premultiplied_alpha = false;
2090 bool flipped = false;
2091 bool nearest_neighbor = false;
2092 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2094 TextureDrawQuad* overlay_quad =
2095 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2096 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2097 viewport_rect, viewport_rect, viewport_rect, resource_id,
2098 premultiplied_alpha, gfx::PointF(0, 0),
2099 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2100 flipped, nearest_neighbor);
2101 overlay_quad->set_allow_overlay(true);
2103 // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
2104 // Attempt will be called for each strategy in OverlayProcessor. We have
2105 // added a fake strategy, so checking for Attempt calls checks if there was
2106 // any attempt to overlay, which there shouldn't be. We can't use the quad
2107 // list because the render pass is cleaned up by DrawFrame.
2108 EXPECT_CALL(*processor->strategy_, Attempt(_, _)).Times(0);
2109 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2110 viewport_rect, false);
2111 Mock::VerifyAndClearExpectations(processor->strategy_);
2113 // Without a copy request Attempt() should be called once.
2114 root_pass = AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2115 viewport_rect, gfx::Transform());
2116 root_pass->has_transparent_background = false;
2118 overlay_quad = root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2119 overlay_quad->SetNew(root_pass->CreateAndAppendSharedQuadState(),
2120 viewport_rect, viewport_rect, viewport_rect, resource_id,
2121 premultiplied_alpha, gfx::PointF(0, 0),
2122 gfx::PointF(1, 1), SK_ColorTRANSPARENT, vertex_opacity,
2123 flipped, nearest_neighbor);
2125 EXPECT_CALL(*processor->strategy_, Attempt(_, _)).Times(1);
2126 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2127 viewport_rect, false);
2130 class SingleOverlayOnTopProcessor : public OverlayProcessor {
2131 public:
2132 class SingleOverlayValidator : public OverlayCandidateValidator {
2133 public:
2134 void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
2135 ASSERT_EQ(2U, surfaces->size());
2136 OverlayCandidate& candidate = surfaces->back();
2137 candidate.overlay_handled = true;
2141 explicit SingleOverlayOnTopProcessor(OutputSurface* surface)
2142 : OverlayProcessor(surface) {}
2144 void Initialize() override {
2145 strategies_.push_back(
2146 scoped_ptr<Strategy>(new OverlayStrategySingleOnTop(&validator_)));
2149 SingleOverlayValidator validator_;
2152 class WaitSyncPointCountingContext : public TestWebGraphicsContext3D {
2153 public:
2154 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
2157 class MockOverlayScheduler {
2158 public:
2159 MOCK_METHOD5(Schedule,
2160 void(int plane_z_order,
2161 gfx::OverlayTransform plane_transform,
2162 unsigned overlay_texture_id,
2163 const gfx::Rect& display_bounds,
2164 const gfx::RectF& uv_rect));
2167 TEST_F(GLRendererTest, OverlaySyncPointsAreProcessed) {
2168 scoped_ptr<WaitSyncPointCountingContext> context_owned(
2169 new WaitSyncPointCountingContext);
2170 WaitSyncPointCountingContext* context = context_owned.get();
2172 MockOverlayScheduler overlay_scheduler;
2173 scoped_refptr<TestContextProvider> context_provider =
2174 TestContextProvider::Create(context_owned.Pass());
2175 context_provider->support()->SetScheduleOverlayPlaneCallback(base::Bind(
2176 &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler)));
2178 FakeOutputSurfaceClient output_surface_client;
2179 scoped_ptr<OutputSurface> output_surface(
2180 FakeOutputSurface::Create3d(context_provider));
2181 CHECK(output_surface->BindToClient(&output_surface_client));
2183 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
2184 new TestSharedBitmapManager());
2185 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
2186 output_surface.get(), shared_bitmap_manager.get());
2187 scoped_ptr<TextureMailboxDeleter> mailbox_deleter(
2188 new TextureMailboxDeleter(base::ThreadTaskRunnerHandle::Get()));
2190 RendererSettings settings;
2191 FakeRendererClient renderer_client;
2192 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
2193 resource_provider.get(), mailbox_deleter.get());
2195 SingleOverlayOnTopProcessor* processor =
2196 new SingleOverlayOnTopProcessor(output_surface.get());
2197 processor->Initialize();
2198 renderer.SetOverlayProcessor(processor);
2200 gfx::Rect viewport_rect(1, 1);
2201 TestRenderPass* root_pass =
2202 AddRenderPass(&render_passes_in_draw_order_, RenderPassId(1, 0),
2203 viewport_rect, gfx::Transform());
2204 root_pass->has_transparent_background = false;
2206 unsigned sync_point = TestRenderPass::kSyncPointForMailboxTextureQuad;
2207 TextureMailbox mailbox =
2208 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
2209 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
2210 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
2211 ResourceId resource_id = resource_provider->CreateResourceFromTextureMailbox(
2212 mailbox, release_callback.Pass());
2213 bool premultiplied_alpha = false;
2214 bool flipped = false;
2215 bool nearest_neighbor = false;
2216 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2217 gfx::PointF uv_top_left(0, 0);
2218 gfx::PointF uv_bottom_right(1, 1);
2220 TextureDrawQuad* overlay_quad =
2221 root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2222 SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
2223 shared_state->SetAll(gfx::Transform(), viewport_rect.size(), viewport_rect,
2224 viewport_rect, false, 1, SkXfermode::kSrcOver_Mode, 0);
2225 overlay_quad->SetNew(shared_state, viewport_rect, viewport_rect,
2226 viewport_rect, resource_id, premultiplied_alpha,
2227 uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT,
2228 vertex_opacity, flipped, nearest_neighbor);
2229 overlay_quad->set_allow_overlay(true);
2231 // Verify that overlay_quad actually gets turned into an overlay, and even
2232 // though it's not drawn, that its sync point is waited on.
2233 EXPECT_CALL(*context,
2234 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
2235 .Times(1);
2236 EXPECT_CALL(overlay_scheduler,
2237 Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, viewport_rect,
2238 BoundingRect(uv_top_left, uv_bottom_right))).Times(1);
2240 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_rect,
2241 viewport_rect, false);
2244 } // namespace
2245 } // namespace cc