GPU workaround to simulate Out of Memory errors with large textures
[chromium-blink-merge.git] / cc / output / gl_renderer_unittest.cc
blob7e0f8e0f5c1a92a8c787a90898e843717475e7df
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/output/gl_renderer.h"
7 #include <set>
9 #include "cc/base/math_util.h"
10 #include "cc/output/compositor_frame_metadata.h"
11 #include "cc/resources/resource_provider.h"
12 #include "cc/test/fake_impl_proxy.h"
13 #include "cc/test/fake_layer_tree_host_impl.h"
14 #include "cc/test/fake_output_surface.h"
15 #include "cc/test/fake_output_surface_client.h"
16 #include "cc/test/fake_renderer_client.h"
17 #include "cc/test/pixel_test.h"
18 #include "cc/test/render_pass_test_common.h"
19 #include "cc/test/render_pass_test_utils.h"
20 #include "cc/test/test_shared_bitmap_manager.h"
21 #include "cc/test/test_web_graphics_context_3d.h"
22 #include "gpu/GLES2/gl2extchromium.h"
23 #include "gpu/command_buffer/client/context_support.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/skia/include/core/SkImageFilter.h"
27 #include "third_party/skia/include/core/SkMatrix.h"
28 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
29 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
30 #include "ui/gfx/transform.h"
32 using testing::_;
33 using testing::AnyNumber;
34 using testing::Args;
35 using testing::AtLeast;
36 using testing::ElementsAre;
37 using testing::Expectation;
38 using testing::InSequence;
39 using testing::Mock;
40 using testing::Return;
41 using testing::StrictMock;
43 namespace cc {
45 class GLRendererTest : public testing::Test {
46 protected:
47 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
49 RenderPassList render_passes_in_draw_order_;
52 #define EXPECT_PROGRAM_VALID(program_binding) \
53 do { \
54 EXPECT_TRUE((program_binding)->program()); \
55 EXPECT_TRUE((program_binding)->initialized()); \
56 } while (false)
58 static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
59 switch (blend_mode) {
60 case BLEND_MODE_NONE:
61 case BLEND_MODE_NORMAL:
62 return SkXfermode::kSrcOver_Mode;
63 case BLEND_MODE_SCREEN:
64 return SkXfermode::kScreen_Mode;
65 case BLEND_MODE_OVERLAY:
66 return SkXfermode::kOverlay_Mode;
67 case BLEND_MODE_DARKEN:
68 return SkXfermode::kDarken_Mode;
69 case BLEND_MODE_LIGHTEN:
70 return SkXfermode::kLighten_Mode;
71 case BLEND_MODE_COLOR_DODGE:
72 return SkXfermode::kColorDodge_Mode;
73 case BLEND_MODE_COLOR_BURN:
74 return SkXfermode::kColorBurn_Mode;
75 case BLEND_MODE_HARD_LIGHT:
76 return SkXfermode::kHardLight_Mode;
77 case BLEND_MODE_SOFT_LIGHT:
78 return SkXfermode::kSoftLight_Mode;
79 case BLEND_MODE_DIFFERENCE:
80 return SkXfermode::kDifference_Mode;
81 case BLEND_MODE_EXCLUSION:
82 return SkXfermode::kExclusion_Mode;
83 case BLEND_MODE_MULTIPLY:
84 return SkXfermode::kMultiply_Mode;
85 case BLEND_MODE_HUE:
86 return SkXfermode::kHue_Mode;
87 case BLEND_MODE_SATURATION:
88 return SkXfermode::kSaturation_Mode;
89 case BLEND_MODE_COLOR:
90 return SkXfermode::kColor_Mode;
91 case BLEND_MODE_LUMINOSITY:
92 return SkXfermode::kLuminosity_Mode;
94 return SkXfermode::kSrcOver_Mode;
97 // Explicitly named to be a friend in GLRenderer for shader access.
98 class GLRendererShaderPixelTest : public GLRendererPixelTest {
99 public:
100 void SetUp() override {
101 GLRendererPixelTest::SetUp();
102 ASSERT_FALSE(renderer()->IsContextLost());
105 void TearDown() override {
106 GLRendererPixelTest::TearDown();
107 ASSERT_FALSE(renderer()->IsContextLost());
110 void TestBasicShaders() {
111 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
112 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
113 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
114 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
117 void TestShadersWithPrecision(TexCoordPrecision precision) {
118 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
119 EXPECT_PROGRAM_VALID(
120 renderer()->GetNonPremultipliedTextureProgram(precision));
121 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision));
122 EXPECT_PROGRAM_VALID(
123 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision));
124 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
125 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision));
126 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(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()->GetTileProgram(precision, sampler));
150 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
151 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
152 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
153 EXPECT_PROGRAM_VALID(
154 renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
155 EXPECT_PROGRAM_VALID(
156 renderer()->GetTileProgramSwizzleAA(precision, sampler));
159 void TestShadersWithMasks(TexCoordPrecision precision,
160 SamplerType sampler,
161 BlendMode blend_mode,
162 bool mask_for_background) {
163 if (!renderer()->Capabilities().using_egl_image &&
164 sampler == SAMPLER_TYPE_EXTERNAL_OES) {
165 // This will likely be hit in tests due to usage of osmesa.
166 return;
169 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
170 precision, sampler, blend_mode, mask_for_background));
171 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
172 precision, sampler, blend_mode, mask_for_background));
173 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
174 precision, sampler, blend_mode, mask_for_background));
175 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
176 precision, sampler, blend_mode, mask_for_background));
180 namespace {
182 #if !defined(OS_ANDROID) && !defined(OS_WIN)
183 static const TexCoordPrecision kPrecisionList[] = {TEX_COORD_PRECISION_MEDIUM,
184 TEX_COORD_PRECISION_HIGH};
186 static const BlendMode kBlendModeList[LAST_BLEND_MODE + 1] = {
187 BLEND_MODE_NONE,
188 BLEND_MODE_NORMAL,
189 BLEND_MODE_SCREEN,
190 BLEND_MODE_OVERLAY,
191 BLEND_MODE_DARKEN,
192 BLEND_MODE_LIGHTEN,
193 BLEND_MODE_COLOR_DODGE,
194 BLEND_MODE_COLOR_BURN,
195 BLEND_MODE_HARD_LIGHT,
196 BLEND_MODE_SOFT_LIGHT,
197 BLEND_MODE_DIFFERENCE,
198 BLEND_MODE_EXCLUSION,
199 BLEND_MODE_MULTIPLY,
200 BLEND_MODE_HUE,
201 BLEND_MODE_SATURATION,
202 BLEND_MODE_COLOR,
203 BLEND_MODE_LUMINOSITY,
206 static const SamplerType kSamplerList[] = {
207 SAMPLER_TYPE_2D,
208 SAMPLER_TYPE_2D_RECT,
209 SAMPLER_TYPE_EXTERNAL_OES,
212 TEST_F(GLRendererShaderPixelTest, BasicShadersCompile) {
213 TestBasicShaders();
216 class PrecisionShaderPixelTest
217 : public GLRendererShaderPixelTest,
218 public ::testing::WithParamInterface<TexCoordPrecision> {};
220 TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
221 TestShadersWithPrecision(GetParam());
224 INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile,
225 PrecisionShaderPixelTest,
226 ::testing::ValuesIn(kPrecisionList));
228 class PrecisionBlendShaderPixelTest
229 : public GLRendererShaderPixelTest,
230 public ::testing::WithParamInterface<
231 std::tr1::tuple<TexCoordPrecision, BlendMode>> {};
233 TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
234 TestShadersWithPrecisionAndBlend(std::tr1::get<0>(GetParam()),
235 std::tr1::get<1>(GetParam()));
238 INSTANTIATE_TEST_CASE_P(
239 PrecisionBlendShadersCompile,
240 PrecisionBlendShaderPixelTest,
241 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
242 ::testing::ValuesIn(kBlendModeList)));
244 class PrecisionSamplerShaderPixelTest
245 : public GLRendererShaderPixelTest,
246 public ::testing::WithParamInterface<
247 std::tr1::tuple<TexCoordPrecision, SamplerType>> {};
249 TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
250 TestShadersWithPrecisionAndSampler(std::tr1::get<0>(GetParam()),
251 std::tr1::get<1>(GetParam()));
254 INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile,
255 PrecisionSamplerShaderPixelTest,
256 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
257 ::testing::ValuesIn(kSamplerList)));
259 class MaskShaderPixelTest
260 : public GLRendererShaderPixelTest,
261 public ::testing::WithParamInterface<
262 std::tr1::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {};
264 TEST_P(MaskShaderPixelTest, ShadersCompile) {
265 TestShadersWithMasks(
266 std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
267 std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam()));
270 INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
271 MaskShaderPixelTest,
272 ::testing::Combine(::testing::ValuesIn(kPrecisionList),
273 ::testing::ValuesIn(kSamplerList),
274 ::testing::ValuesIn(kBlendModeList),
275 ::testing::Bool()));
277 #endif
279 class FakeRendererGL : public GLRenderer {
280 public:
281 FakeRendererGL(RendererClient* client,
282 const RendererSettings* settings,
283 OutputSurface* output_surface,
284 ResourceProvider* resource_provider)
285 : GLRenderer(client,
286 settings,
287 output_surface,
288 resource_provider,
289 NULL,
290 0) {}
292 // GLRenderer methods.
294 // Changing visibility to public.
295 using GLRenderer::IsBackbufferDiscarded;
296 using GLRenderer::DoDrawQuad;
297 using GLRenderer::BeginDrawingFrame;
298 using GLRenderer::FinishDrawingQuadList;
299 using GLRenderer::stencil_enabled;
302 class GLRendererWithDefaultHarnessTest : public GLRendererTest {
303 protected:
304 GLRendererWithDefaultHarnessTest() {
305 output_surface_ =
306 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
307 CHECK(output_surface_->BindToClient(&output_surface_client_));
309 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
310 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
311 shared_bitmap_manager_.get(),
312 NULL,
313 NULL,
315 false,
316 1).Pass();
317 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
318 &settings_,
319 output_surface_.get(),
320 resource_provider_.get()));
323 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
325 RendererSettings settings_;
326 FakeOutputSurfaceClient output_surface_client_;
327 scoped_ptr<FakeOutputSurface> output_surface_;
328 FakeRendererClient renderer_client_;
329 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
330 scoped_ptr<ResourceProvider> resource_provider_;
331 scoped_ptr<FakeRendererGL> renderer_;
334 // Closing the namespace here so that GLRendererShaderTest can take advantage
335 // of the friend relationship with GLRenderer and all of the mock classes
336 // declared above it.
337 } // namespace
339 class GLRendererShaderTest : public GLRendererTest {
340 protected:
341 GLRendererShaderTest() {
342 output_surface_ = FakeOutputSurface::Create3d().Pass();
343 CHECK(output_surface_->BindToClient(&output_surface_client_));
345 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
346 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
347 shared_bitmap_manager_.get(),
348 NULL,
349 NULL,
351 false,
352 1).Pass();
353 renderer_.reset(new FakeRendererGL(&renderer_client_,
354 &settings_,
355 output_surface_.get(),
356 resource_provider_.get()));
359 void TestRenderPassProgram(TexCoordPrecision precision,
360 BlendMode blend_mode) {
361 EXPECT_PROGRAM_VALID(
362 &renderer_->render_pass_program_[precision][blend_mode]);
363 EXPECT_EQ(renderer_->render_pass_program_[precision][blend_mode].program(),
364 renderer_->program_shadow_);
367 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
368 BlendMode blend_mode) {
369 EXPECT_PROGRAM_VALID(
370 &renderer_->render_pass_color_matrix_program_[precision][blend_mode]);
371 EXPECT_EQ(
372 renderer_->render_pass_color_matrix_program_[precision][blend_mode]
373 .program(),
374 renderer_->program_shadow_);
377 void TestRenderPassMaskProgram(TexCoordPrecision precision,
378 SamplerType sampler,
379 BlendMode blend_mode) {
380 EXPECT_PROGRAM_VALID(
381 &renderer_->render_pass_mask_program_[precision]
382 [sampler]
383 [blend_mode]
384 [NO_MASK]);
385 EXPECT_EQ(
386 renderer_->render_pass_mask_program_[precision]
387 [sampler]
388 [blend_mode]
389 [NO_MASK].program(),
390 renderer_->program_shadow_);
393 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
394 SamplerType sampler,
395 BlendMode blend_mode) {
396 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_
397 [precision][sampler][blend_mode][NO_MASK]);
398 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_
399 [precision][sampler][blend_mode][NO_MASK].program(),
400 renderer_->program_shadow_);
403 void TestRenderPassProgramAA(TexCoordPrecision precision,
404 BlendMode blend_mode) {
405 EXPECT_PROGRAM_VALID(
406 &renderer_->render_pass_program_aa_[precision][blend_mode]);
407 EXPECT_EQ(
408 renderer_->render_pass_program_aa_[precision][blend_mode].program(),
409 renderer_->program_shadow_);
412 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
413 BlendMode blend_mode) {
414 EXPECT_PROGRAM_VALID(
415 &renderer_
416 ->render_pass_color_matrix_program_aa_[precision][blend_mode]);
417 EXPECT_EQ(
418 renderer_->render_pass_color_matrix_program_aa_[precision][blend_mode]
419 .program(),
420 renderer_->program_shadow_);
423 void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
424 SamplerType sampler,
425 BlendMode blend_mode) {
426 EXPECT_PROGRAM_VALID(
427 &renderer_
428 ->render_pass_mask_program_aa_
429 [precision][sampler][blend_mode][NO_MASK]);
430 EXPECT_EQ(
431 renderer_->render_pass_mask_program_aa_[precision][sampler][blend_mode]
432 [NO_MASK].program(),
433 renderer_->program_shadow_);
436 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
437 SamplerType sampler,
438 BlendMode blend_mode) {
439 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_aa_
440 [precision][sampler][blend_mode][NO_MASK]);
441 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_
442 [precision][sampler][blend_mode][NO_MASK].program(),
443 renderer_->program_shadow_);
446 void TestSolidColorProgramAA() {
447 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
448 EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
449 renderer_->program_shadow_);
452 RendererSettings settings_;
453 FakeOutputSurfaceClient output_surface_client_;
454 scoped_ptr<FakeOutputSurface> output_surface_;
455 FakeRendererClient renderer_client_;
456 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
457 scoped_ptr<ResourceProvider> resource_provider_;
458 scoped_ptr<FakeRendererGL> renderer_;
461 namespace {
463 // Test GLRenderer DiscardBackbuffer functionality:
464 // Suggest discarding framebuffer when one exists and the renderer is not
465 // visible.
466 // Expected: it is discarded and damage tracker is reset.
467 TEST_F(
468 GLRendererWithDefaultHarnessTest,
469 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
470 renderer_->SetVisible(false);
471 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
472 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
475 // Test GLRenderer DiscardBackbuffer functionality:
476 // Suggest discarding framebuffer when one exists and the renderer is visible.
477 // Expected: the allocation is ignored.
478 TEST_F(GLRendererWithDefaultHarnessTest,
479 SuggestBackbufferNoDoNothingWhenVisible) {
480 renderer_->SetVisible(true);
481 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
482 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
485 // Test GLRenderer DiscardBackbuffer functionality:
486 // Suggest discarding framebuffer when one does not exist.
487 // Expected: it does nothing.
488 TEST_F(GLRendererWithDefaultHarnessTest,
489 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
490 renderer_->SetVisible(false);
491 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
492 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
494 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
495 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
498 // Test GLRenderer DiscardBackbuffer functionality:
499 // Begin drawing a frame while a framebuffer is discarded.
500 // Expected: will recreate framebuffer.
501 TEST_F(GLRendererWithDefaultHarnessTest,
502 DiscardedBackbufferIsRecreatedForScopeDuration) {
503 gfx::Rect viewport_rect(1, 1);
504 renderer_->SetVisible(false);
505 EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
506 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
508 AddRenderPass(&render_passes_in_draw_order_,
509 RenderPassId(1, 0),
510 viewport_rect,
511 gfx::Transform());
513 renderer_->SetVisible(true);
514 renderer_->DrawFrame(&render_passes_in_draw_order_,
515 1.f,
516 viewport_rect,
517 viewport_rect,
518 false);
519 EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
521 SwapBuffers();
522 EXPECT_EQ(1u, output_surface_->num_sent_frames());
525 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
526 gfx::Rect viewport_rect(1, 1);
527 EXPECT_FALSE(renderer_->stencil_enabled());
529 output_surface_->set_has_external_stencil_test(true);
531 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
532 RenderPassId(1, 0),
533 viewport_rect,
534 gfx::Transform());
535 root_pass->has_transparent_background = false;
537 renderer_->DrawFrame(&render_passes_in_draw_order_,
538 1.f,
539 viewport_rect,
540 viewport_rect,
541 false);
542 EXPECT_TRUE(renderer_->stencil_enabled());
545 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
546 public:
547 ForbidSynchronousCallContext() {}
549 void getAttachedShaders(GLuint program,
550 GLsizei max_count,
551 GLsizei* count,
552 GLuint* shaders) override {
553 ADD_FAILURE();
555 GLint getAttribLocation(GLuint program, const GLchar* name) override {
556 ADD_FAILURE();
557 return 0;
559 void getBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
560 void getBufferParameteriv(GLenum target,
561 GLenum pname,
562 GLint* value) override {
563 ADD_FAILURE();
565 GLenum getError() override {
566 ADD_FAILURE();
567 return GL_NO_ERROR;
569 void getFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
570 void getFramebufferAttachmentParameteriv(GLenum target,
571 GLenum attachment,
572 GLenum pname,
573 GLint* value) override {
574 ADD_FAILURE();
576 void getIntegerv(GLenum pname, GLint* value) override {
577 if (pname == GL_MAX_TEXTURE_SIZE) {
578 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
579 *value = 1024;
580 } else {
581 ADD_FAILURE();
585 // We allow querying the shader compilation and program link status in debug
586 // mode, but not release.
587 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
588 #ifndef NDEBUG
589 *value = 1;
590 #else
591 ADD_FAILURE();
592 #endif
595 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
596 #ifndef NDEBUG
597 *value = 1;
598 #else
599 ADD_FAILURE();
600 #endif
603 void getRenderbufferParameteriv(GLenum target,
604 GLenum pname,
605 GLint* value) override {
606 ADD_FAILURE();
609 void getShaderPrecisionFormat(GLenum shadertype,
610 GLenum precisiontype,
611 GLint* range,
612 GLint* precision) override {
613 ADD_FAILURE();
615 void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
616 ADD_FAILURE();
618 void getTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
619 ADD_FAILURE();
621 void getUniformfv(GLuint program, GLint location, GLfloat* value) override {
622 ADD_FAILURE();
624 void getUniformiv(GLuint program, GLint location, GLint* value) override {
625 ADD_FAILURE();
627 GLint getUniformLocation(GLuint program, const GLchar* name) override {
628 ADD_FAILURE();
629 return 0;
631 void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
632 ADD_FAILURE();
634 void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
635 ADD_FAILURE();
637 GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname) override {
638 ADD_FAILURE();
639 return 0;
642 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
643 FakeOutputSurfaceClient output_surface_client;
644 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
645 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
646 CHECK(output_surface->BindToClient(&output_surface_client));
648 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
649 new TestSharedBitmapManager());
650 scoped_ptr<ResourceProvider> resource_provider(
651 ResourceProvider::Create(output_surface.get(),
652 shared_bitmap_manager.get(),
653 NULL,
654 NULL,
656 false,
657 1));
659 RendererSettings settings;
660 FakeRendererClient renderer_client;
661 FakeRendererGL renderer(&renderer_client,
662 &settings,
663 output_surface.get(),
664 resource_provider.get());
667 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
668 public:
669 LoseContextOnFirstGetContext() {}
671 void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
672 context_lost_ = true;
673 *value = 0;
676 void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
677 context_lost_ = true;
678 *value = 0;
682 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
683 FakeOutputSurfaceClient output_surface_client;
684 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
685 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
686 CHECK(output_surface->BindToClient(&output_surface_client));
688 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
689 new TestSharedBitmapManager());
690 scoped_ptr<ResourceProvider> resource_provider(
691 ResourceProvider::Create(output_surface.get(),
692 shared_bitmap_manager.get(),
693 NULL,
694 NULL,
696 false,
697 1));
699 RendererSettings settings;
700 FakeRendererClient renderer_client;
701 FakeRendererGL renderer(&renderer_client,
702 &settings,
703 output_surface.get(),
704 resource_provider.get());
707 class ClearCountingContext : public TestWebGraphicsContext3D {
708 public:
709 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
711 MOCK_METHOD3(discardFramebufferEXT,
712 void(GLenum target,
713 GLsizei numAttachments,
714 const GLenum* attachments));
715 MOCK_METHOD1(clear, void(GLbitfield mask));
718 TEST_F(GLRendererTest, OpaqueBackground) {
719 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
720 ClearCountingContext* context = context_owned.get();
722 FakeOutputSurfaceClient output_surface_client;
723 scoped_ptr<OutputSurface> output_surface(
724 FakeOutputSurface::Create3d(context_owned.Pass()));
725 CHECK(output_surface->BindToClient(&output_surface_client));
727 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
728 new TestSharedBitmapManager());
729 scoped_ptr<ResourceProvider> resource_provider(
730 ResourceProvider::Create(output_surface.get(),
731 shared_bitmap_manager.get(),
732 NULL,
733 NULL,
735 false,
736 1));
738 RendererSettings settings;
739 FakeRendererClient renderer_client;
740 FakeRendererGL renderer(&renderer_client,
741 &settings,
742 output_surface.get(),
743 resource_provider.get());
745 gfx::Rect viewport_rect(1, 1);
746 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
747 RenderPassId(1, 0),
748 viewport_rect,
749 gfx::Transform());
750 root_pass->has_transparent_background = false;
752 // On DEBUG builds, render passes with opaque background clear to blue to
753 // easily see regions that were not drawn on the screen.
754 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
755 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
756 .Times(1);
757 #ifdef NDEBUG
758 EXPECT_CALL(*context, clear(_)).Times(0);
759 #else
760 EXPECT_CALL(*context, clear(_)).Times(1);
761 #endif
762 renderer.DrawFrame(&render_passes_in_draw_order_,
763 1.f,
764 viewport_rect,
765 viewport_rect,
766 false);
767 Mock::VerifyAndClearExpectations(context);
770 TEST_F(GLRendererTest, TransparentBackground) {
771 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
772 ClearCountingContext* context = context_owned.get();
774 FakeOutputSurfaceClient output_surface_client;
775 scoped_ptr<OutputSurface> output_surface(
776 FakeOutputSurface::Create3d(context_owned.Pass()));
777 CHECK(output_surface->BindToClient(&output_surface_client));
779 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
780 new TestSharedBitmapManager());
781 scoped_ptr<ResourceProvider> resource_provider(
782 ResourceProvider::Create(output_surface.get(),
783 shared_bitmap_manager.get(),
784 NULL,
785 NULL,
787 false,
788 1));
790 RendererSettings settings;
791 FakeRendererClient renderer_client;
792 FakeRendererGL renderer(&renderer_client,
793 &settings,
794 output_surface.get(),
795 resource_provider.get());
797 gfx::Rect viewport_rect(1, 1);
798 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
799 RenderPassId(1, 0),
800 viewport_rect,
801 gfx::Transform());
802 root_pass->has_transparent_background = true;
804 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
805 EXPECT_CALL(*context, clear(_)).Times(1);
806 renderer.DrawFrame(&render_passes_in_draw_order_,
807 1.f,
808 viewport_rect,
809 viewport_rect,
810 false);
812 Mock::VerifyAndClearExpectations(context);
815 TEST_F(GLRendererTest, OffscreenOutputSurface) {
816 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
817 ClearCountingContext* context = context_owned.get();
819 FakeOutputSurfaceClient output_surface_client;
820 scoped_ptr<OutputSurface> output_surface(
821 FakeOutputSurface::CreateOffscreen(context_owned.Pass()));
822 CHECK(output_surface->BindToClient(&output_surface_client));
824 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
825 new TestSharedBitmapManager());
826 scoped_ptr<ResourceProvider> resource_provider(
827 ResourceProvider::Create(output_surface.get(),
828 shared_bitmap_manager.get(),
829 NULL,
830 NULL,
832 false,
833 1));
835 RendererSettings settings;
836 FakeRendererClient renderer_client;
837 FakeRendererGL renderer(&renderer_client,
838 &settings,
839 output_surface.get(),
840 resource_provider.get());
842 gfx::Rect viewport_rect(1, 1);
843 AddRenderPass(&render_passes_in_draw_order_,
844 RenderPassId(1, 0),
845 viewport_rect,
846 gfx::Transform());
848 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
849 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
850 .Times(1);
851 EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
852 renderer.DrawFrame(&render_passes_in_draw_order_,
853 1.f,
854 viewport_rect,
855 viewport_rect,
856 false);
857 Mock::VerifyAndClearExpectations(context);
860 class VisibilityChangeIsLastCallTrackingContext
861 : public TestWebGraphicsContext3D {
862 public:
863 VisibilityChangeIsLastCallTrackingContext()
864 : last_call_was_set_visibility_(false) {}
866 // TestWebGraphicsContext3D methods.
867 void flush() override { last_call_was_set_visibility_ = false; }
868 void deleteTexture(GLuint) override { last_call_was_set_visibility_ = false; }
869 void deleteFramebuffer(GLuint) override {
870 last_call_was_set_visibility_ = false;
872 void deleteQueryEXT(GLuint) override {
873 last_call_was_set_visibility_ = false;
875 void deleteRenderbuffer(GLuint) override {
876 last_call_was_set_visibility_ = false;
879 // Methods added for test.
880 void set_last_call_was_visibility(bool visible) {
881 DCHECK(last_call_was_set_visibility_ == false);
882 last_call_was_set_visibility_ = true;
884 bool last_call_was_set_visibility() const {
885 return last_call_was_set_visibility_;
888 private:
889 bool last_call_was_set_visibility_;
892 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
893 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
894 new VisibilityChangeIsLastCallTrackingContext);
895 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
897 scoped_refptr<TestContextProvider> provider =
898 TestContextProvider::Create(context_owned.Pass());
900 provider->support()->SetSurfaceVisibleCallback(base::Bind(
901 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
902 base::Unretained(context)));
904 FakeOutputSurfaceClient output_surface_client;
905 scoped_ptr<OutputSurface> output_surface(
906 FakeOutputSurface::Create3d(provider));
907 CHECK(output_surface->BindToClient(&output_surface_client));
909 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
910 new TestSharedBitmapManager());
911 scoped_ptr<ResourceProvider> resource_provider(
912 ResourceProvider::Create(output_surface.get(),
913 shared_bitmap_manager.get(),
914 NULL,
915 NULL,
917 false,
918 1));
920 RendererSettings settings;
921 FakeRendererClient renderer_client;
922 FakeRendererGL renderer(&renderer_client,
923 &settings,
924 output_surface.get(),
925 resource_provider.get());
927 gfx::Rect viewport_rect(1, 1);
928 AddRenderPass(&render_passes_in_draw_order_,
929 RenderPassId(1, 0),
930 viewport_rect,
931 gfx::Transform());
933 // Ensure that the call to SetSurfaceVisible is the last call issue to the
934 // GPU process, after glFlush is called, and after the RendererClient's
935 // SetManagedMemoryPolicy is called. Plumb this tracking between both the
936 // RenderClient and the Context by giving them both a pointer to a variable on
937 // the stack.
938 renderer.SetVisible(true);
939 renderer.DrawFrame(&render_passes_in_draw_order_,
940 1.f,
941 viewport_rect,
942 viewport_rect,
943 false);
944 renderer.SetVisible(false);
945 EXPECT_TRUE(context->last_call_was_set_visibility());
948 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
949 public:
950 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
951 test_capabilities_.gpu.egl_image_external = true;
954 MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
955 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
956 MOCK_METHOD4(drawElements,
957 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
959 virtual void activeTexture(GLenum texture) {
960 EXPECT_NE(texture, active_texture_);
961 active_texture_ = texture;
964 GLenum active_texture() const { return active_texture_; }
966 private:
967 GLenum active_texture_;
970 TEST_F(GLRendererTest, ActiveTextureState) {
971 scoped_ptr<TextureStateTrackingContext> context_owned(
972 new TextureStateTrackingContext);
973 TextureStateTrackingContext* context = context_owned.get();
975 FakeOutputSurfaceClient output_surface_client;
976 scoped_ptr<OutputSurface> output_surface(
977 FakeOutputSurface::Create3d(context_owned.Pass()));
978 CHECK(output_surface->BindToClient(&output_surface_client));
980 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
981 new TestSharedBitmapManager());
982 scoped_ptr<ResourceProvider> resource_provider(
983 ResourceProvider::Create(output_surface.get(),
984 shared_bitmap_manager.get(),
985 NULL,
986 NULL,
988 false,
989 1));
991 RendererSettings settings;
992 FakeRendererClient renderer_client;
993 FakeRendererGL renderer(&renderer_client,
994 &settings,
995 output_surface.get(),
996 resource_provider.get());
998 // During initialization we are allowed to set any texture parameters.
999 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
1001 RenderPassId id(1, 1);
1002 TestRenderPass* root_pass = AddRenderPass(
1003 &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
1004 root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
1005 RenderPassId(2, 1));
1007 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1009 // Set up expected texture filter state transitions that match the quads
1010 // created in AppendOneOfEveryQuadType().
1011 Mock::VerifyAndClearExpectations(context);
1013 InSequence sequence;
1015 // The sync points for all quads are waited on first. This sync point is
1016 // for a texture quad drawn later in the frame.
1017 EXPECT_CALL(*context,
1018 waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
1019 .Times(1);
1021 // yuv_quad is drawn with the default linear filter.
1022 EXPECT_CALL(*context, drawElements(_, _, _, _));
1024 // tile_quad is drawn with GL_NEAREST because it is not transformed or
1025 // scaled.
1026 EXPECT_CALL(
1027 *context,
1028 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
1029 EXPECT_CALL(
1030 *context,
1031 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
1032 EXPECT_CALL(*context, drawElements(_, _, _, _));
1034 // transformed_tile_quad uses GL_LINEAR.
1035 EXPECT_CALL(*context, drawElements(_, _, _, _));
1037 // scaled_tile_quad also uses GL_LINEAR.
1038 EXPECT_CALL(*context, drawElements(_, _, _, _));
1040 // The remaining quads also use GL_LINEAR because nearest neighbor
1041 // filtering is currently only used with tile quads.
1042 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(7);
1045 gfx::Rect viewport_rect(100, 100);
1046 renderer.DrawFrame(&render_passes_in_draw_order_,
1047 1.f,
1048 viewport_rect,
1049 viewport_rect,
1050 false);
1051 Mock::VerifyAndClearExpectations(context);
1054 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
1055 public:
1056 MOCK_METHOD1(clear, void(GLbitfield mask));
1057 MOCK_METHOD4(drawElements,
1058 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1061 TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
1062 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
1063 new NoClearRootRenderPassMockContext);
1064 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
1066 FakeOutputSurfaceClient output_surface_client;
1067 scoped_ptr<OutputSurface> output_surface(
1068 FakeOutputSurface::Create3d(mock_context_owned.Pass()));
1069 CHECK(output_surface->BindToClient(&output_surface_client));
1071 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1072 new TestSharedBitmapManager());
1073 scoped_ptr<ResourceProvider> resource_provider(
1074 ResourceProvider::Create(output_surface.get(),
1075 shared_bitmap_manager.get(),
1076 NULL,
1077 NULL,
1079 false,
1080 1));
1082 RendererSettings settings;
1083 settings.should_clear_root_render_pass = false;
1085 FakeRendererClient renderer_client;
1086 FakeRendererGL renderer(&renderer_client,
1087 &settings,
1088 output_surface.get(),
1089 resource_provider.get());
1091 gfx::Rect viewport_rect(10, 10);
1093 RenderPassId root_pass_id(1, 0);
1094 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1095 root_pass_id,
1096 viewport_rect,
1097 gfx::Transform());
1098 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1100 RenderPassId child_pass_id(2, 0);
1101 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
1102 child_pass_id,
1103 viewport_rect,
1104 gfx::Transform());
1105 AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
1107 AddRenderPassQuad(root_pass, child_pass);
1109 #ifdef NDEBUG
1110 GLint clear_bits = GL_COLOR_BUFFER_BIT;
1111 #else
1112 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1113 #endif
1115 // First render pass is not the root one, clearing should happen.
1116 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
1118 Expectation first_render_pass =
1119 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
1121 // The second render pass is the root one, clearing should be prevented.
1122 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
1123 first_render_pass);
1125 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
1126 first_render_pass);
1128 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1129 renderer.DrawFrame(&render_passes_in_draw_order_,
1130 1.f,
1131 viewport_rect,
1132 viewport_rect,
1133 false);
1135 // In multiple render passes all but the root pass should clear the
1136 // framebuffer.
1137 Mock::VerifyAndClearExpectations(&mock_context);
1140 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
1141 public:
1142 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
1144 void clear(GLbitfield) override { EXPECT_FALSE(scissor_enabled_); }
1146 void enable(GLenum cap) override {
1147 if (cap == GL_SCISSOR_TEST)
1148 scissor_enabled_ = true;
1151 void disable(GLenum cap) override {
1152 if (cap == GL_SCISSOR_TEST)
1153 scissor_enabled_ = false;
1156 private:
1157 bool scissor_enabled_;
1160 TEST_F(GLRendererTest, ScissorTestWhenClearing) {
1161 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
1162 new ScissorTestOnClearCheckingContext);
1164 FakeOutputSurfaceClient output_surface_client;
1165 scoped_ptr<OutputSurface> output_surface(
1166 FakeOutputSurface::Create3d(context_owned.Pass()));
1167 CHECK(output_surface->BindToClient(&output_surface_client));
1169 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1170 new TestSharedBitmapManager());
1171 scoped_ptr<ResourceProvider> resource_provider(
1172 ResourceProvider::Create(output_surface.get(),
1173 shared_bitmap_manager.get(),
1174 NULL,
1175 NULL,
1177 false,
1178 1));
1180 RendererSettings settings;
1181 FakeRendererClient renderer_client;
1182 FakeRendererGL renderer(&renderer_client,
1183 &settings,
1184 output_surface.get(),
1185 resource_provider.get());
1186 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1188 gfx::Rect viewport_rect(1, 1);
1190 gfx::Rect grand_child_rect(25, 25);
1191 RenderPassId grand_child_pass_id(3, 0);
1192 TestRenderPass* grand_child_pass =
1193 AddRenderPass(&render_passes_in_draw_order_,
1194 grand_child_pass_id,
1195 grand_child_rect,
1196 gfx::Transform());
1197 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
1199 gfx::Rect child_rect(50, 50);
1200 RenderPassId child_pass_id(2, 0);
1201 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
1202 child_pass_id,
1203 child_rect,
1204 gfx::Transform());
1205 AddQuad(child_pass, child_rect, SK_ColorBLUE);
1207 RenderPassId root_pass_id(1, 0);
1208 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1209 root_pass_id,
1210 viewport_rect,
1211 gfx::Transform());
1212 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1214 AddRenderPassQuad(root_pass, child_pass);
1215 AddRenderPassQuad(child_pass, grand_child_pass);
1217 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1218 renderer.DrawFrame(&render_passes_in_draw_order_,
1219 1.f,
1220 viewport_rect,
1221 viewport_rect,
1222 false);
1225 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1226 public:
1227 DiscardCheckingContext() : discarded_(0) {
1228 set_have_post_sub_buffer(true);
1229 set_have_discard_framebuffer(true);
1232 void discardFramebufferEXT(GLenum target,
1233 GLsizei numAttachments,
1234 const GLenum* attachments) override {
1235 ++discarded_;
1238 int discarded() const { return discarded_; }
1239 void reset() { discarded_ = 0; }
1241 private:
1242 int discarded_;
1245 class NonReshapableOutputSurface : public FakeOutputSurface {
1246 public:
1247 explicit NonReshapableOutputSurface(
1248 scoped_ptr<TestWebGraphicsContext3D> context3d)
1249 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
1250 false) {
1251 surface_size_ = gfx::Size(500, 500);
1253 void Reshape(const gfx::Size& size, float scale_factor) override {}
1254 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
1257 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
1258 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1259 DiscardCheckingContext* context = context_owned.get();
1261 FakeOutputSurfaceClient output_surface_client;
1262 scoped_ptr<NonReshapableOutputSurface> output_surface(
1263 new NonReshapableOutputSurface(context_owned.Pass()));
1264 CHECK(output_surface->BindToClient(&output_surface_client));
1265 output_surface->set_fixed_size(gfx::Size(100, 100));
1267 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1268 new TestSharedBitmapManager());
1269 scoped_ptr<ResourceProvider> resource_provider(
1270 ResourceProvider::Create(output_surface.get(),
1271 shared_bitmap_manager.get(),
1272 NULL,
1273 NULL,
1275 false,
1276 1));
1278 RendererSettings settings;
1279 settings.partial_swap_enabled = true;
1280 FakeRendererClient renderer_client;
1281 FakeRendererGL renderer(&renderer_client,
1282 &settings,
1283 output_surface.get(),
1284 resource_provider.get());
1285 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1287 gfx::Rect viewport_rect(100, 100);
1288 gfx::Rect clip_rect(100, 100);
1291 // Partial frame, should not discard.
1292 RenderPassId root_pass_id(1, 0);
1293 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1294 root_pass_id,
1295 viewport_rect,
1296 gfx::Transform());
1297 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1298 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
1300 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1301 renderer.DrawFrame(&render_passes_in_draw_order_,
1302 1.f,
1303 viewport_rect,
1304 clip_rect,
1305 false);
1306 EXPECT_EQ(0, context->discarded());
1307 context->reset();
1310 // Full frame, should discard.
1311 RenderPassId root_pass_id(1, 0);
1312 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1313 root_pass_id,
1314 viewport_rect,
1315 gfx::Transform());
1316 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1317 root_pass->damage_rect = root_pass->output_rect;
1319 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1320 renderer.DrawFrame(&render_passes_in_draw_order_,
1321 1.f,
1322 viewport_rect,
1323 clip_rect,
1324 false);
1325 EXPECT_EQ(1, context->discarded());
1326 context->reset();
1329 // Full frame, external scissor is set, should not discard.
1330 output_surface->set_has_external_stencil_test(true);
1331 RenderPassId root_pass_id(1, 0);
1332 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1333 root_pass_id,
1334 viewport_rect,
1335 gfx::Transform());
1336 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1337 root_pass->damage_rect = root_pass->output_rect;
1338 root_pass->has_transparent_background = false;
1340 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1341 renderer.DrawFrame(&render_passes_in_draw_order_,
1342 1.f,
1343 viewport_rect,
1344 clip_rect,
1345 false);
1346 EXPECT_EQ(0, context->discarded());
1347 context->reset();
1348 output_surface->set_has_external_stencil_test(false);
1351 // Full frame, clipped, should not discard.
1352 clip_rect = gfx::Rect(10, 10, 10, 10);
1353 RenderPassId root_pass_id(1, 0);
1354 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1355 root_pass_id,
1356 viewport_rect,
1357 gfx::Transform());
1358 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1359 root_pass->damage_rect = root_pass->output_rect;
1361 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1362 renderer.DrawFrame(&render_passes_in_draw_order_,
1363 1.f,
1364 viewport_rect,
1365 clip_rect,
1366 false);
1367 EXPECT_EQ(0, context->discarded());
1368 context->reset();
1371 // Full frame, doesn't cover the surface, should not discard.
1372 viewport_rect = gfx::Rect(10, 10, 10, 10);
1373 RenderPassId root_pass_id(1, 0);
1374 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1375 root_pass_id,
1376 viewport_rect,
1377 gfx::Transform());
1378 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1379 root_pass->damage_rect = root_pass->output_rect;
1381 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1382 renderer.DrawFrame(&render_passes_in_draw_order_,
1383 1.f,
1384 viewport_rect,
1385 clip_rect,
1386 false);
1387 EXPECT_EQ(0, context->discarded());
1388 context->reset();
1391 // Full frame, doesn't cover the surface (no offset), should not discard.
1392 clip_rect = gfx::Rect(100, 100);
1393 viewport_rect = gfx::Rect(50, 50);
1394 RenderPassId root_pass_id(1, 0);
1395 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1396 root_pass_id,
1397 viewport_rect,
1398 gfx::Transform());
1399 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1400 root_pass->damage_rect = root_pass->output_rect;
1402 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1403 renderer.DrawFrame(&render_passes_in_draw_order_,
1404 1.f,
1405 viewport_rect,
1406 clip_rect,
1407 false);
1408 EXPECT_EQ(0, context->discarded());
1409 context->reset();
1413 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1414 public:
1415 MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
1416 MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
1419 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
1420 // In Android WebView, the OutputSurface is unable to respect reshape() calls
1421 // and maintains a fixed size. This test verifies that glViewport and
1422 // glScissor's Y coordinate is flipped correctly in this environment, and that
1423 // the glViewport can be at a nonzero origin within the surface.
1424 scoped_ptr<FlippedScissorAndViewportContext> context_owned(
1425 new FlippedScissorAndViewportContext);
1427 // We expect exactly one call to viewport on this context and exactly two
1428 // to scissor (one to scissor the clear, one to scissor the quad draw).
1429 EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100));
1430 EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100));
1431 EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20));
1433 FakeOutputSurfaceClient output_surface_client;
1434 scoped_ptr<OutputSurface> output_surface(
1435 new NonReshapableOutputSurface(context_owned.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(
1441 ResourceProvider::Create(output_surface.get(),
1442 shared_bitmap_manager.get(),
1443 NULL,
1444 NULL,
1446 false,
1447 1));
1449 RendererSettings settings;
1450 FakeRendererClient renderer_client;
1451 FakeRendererGL renderer(&renderer_client,
1452 &settings,
1453 output_surface.get(),
1454 resource_provider.get());
1455 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1457 gfx::Rect device_viewport_rect(10, 10, 100, 100);
1458 gfx::Rect viewport_rect(device_viewport_rect.size());
1459 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1461 RenderPassId root_pass_id(1, 0);
1462 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
1463 root_pass_id,
1464 viewport_rect,
1465 gfx::Transform());
1466 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1468 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1469 renderer.DrawFrame(&render_passes_in_draw_order_,
1470 1.f,
1471 device_viewport_rect,
1472 device_viewport_rect,
1473 false);
1476 TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
1477 // When using render-to-FBO to display the surface, all rendering is done
1478 // to a non-zero FBO. Make sure that the framebuffer is always restored to
1479 // the correct framebuffer during rendering, if changed.
1480 // Note: there is one path that will set it to 0, but that is after the render
1481 // has finished.
1482 FakeOutputSurfaceClient output_surface_client;
1483 scoped_ptr<FakeOutputSurface> output_surface(
1484 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
1485 CHECK(output_surface->BindToClient(&output_surface_client));
1487 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
1488 new TestSharedBitmapManager());
1489 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
1490 output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
1491 1));
1493 RendererSettings settings;
1494 FakeRendererClient renderer_client;
1495 FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
1496 resource_provider.get());
1497 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1499 gfx::Rect device_viewport_rect(0, 0, 100, 100);
1500 gfx::Rect viewport_rect(device_viewport_rect.size());
1501 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1503 RenderPassId root_pass_id(1, 0);
1504 TestRenderPass* root_pass =
1505 AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
1506 gfx::Transform());
1507 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
1509 unsigned fbo;
1510 gpu::gles2::GLES2Interface* gl =
1511 output_surface->context_provider()->ContextGL();
1512 gl->GenFramebuffers(1, &fbo);
1513 output_surface->set_framebuffer(fbo);
1515 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1516 renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect,
1517 device_viewport_rect, false);
1519 int bound_fbo;
1520 gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
1521 EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
1524 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
1525 gfx::Rect viewport_rect(1, 1);
1527 gfx::Rect child_rect(50, 50);
1528 RenderPassId child_pass_id(2, 0);
1529 TestRenderPass* child_pass;
1531 RenderPassId root_pass_id(1, 0);
1532 TestRenderPass* root_pass;
1534 ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
1535 gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
1536 ResourceProvider::TEXTURE_HINT_IMMUTABLE,
1537 resource_provider_->best_texture_format());
1538 resource_provider_->AllocateForTesting(mask);
1540 SkScalar matrix[20];
1541 float amount = 0.5f;
1542 matrix[0] = 0.213f + 0.787f * amount;
1543 matrix[1] = 0.715f - 0.715f * amount;
1544 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1545 matrix[3] = matrix[4] = 0;
1546 matrix[5] = 0.213f - 0.213f * amount;
1547 matrix[6] = 0.715f + 0.285f * amount;
1548 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1549 matrix[8] = matrix[9] = 0;
1550 matrix[10] = 0.213f - 0.213f * amount;
1551 matrix[11] = 0.715f - 0.715f * amount;
1552 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1553 matrix[13] = matrix[14] = 0;
1554 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1555 matrix[18] = 1;
1556 skia::RefPtr<SkColorFilter> color_filter(
1557 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1558 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
1559 SkColorFilterImageFilter::Create(color_filter.get(), NULL));
1560 FilterOperations filters;
1561 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1563 gfx::Transform transform_causing_aa;
1564 transform_causing_aa.Rotate(20.0);
1566 for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
1567 BlendMode blend_mode = static_cast<BlendMode>(i);
1568 SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
1569 settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
1570 // RenderPassProgram
1571 render_passes_in_draw_order_.clear();
1572 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1573 child_pass_id,
1574 child_rect,
1575 gfx::Transform());
1577 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1578 root_pass_id,
1579 viewport_rect,
1580 gfx::Transform());
1582 AddRenderPassQuad(root_pass,
1583 child_pass,
1585 FilterOperations(),
1586 gfx::Transform(),
1587 xfer_mode);
1589 renderer_->DecideRenderPassAllocationsForFrame(
1590 render_passes_in_draw_order_);
1591 renderer_->DrawFrame(&render_passes_in_draw_order_,
1592 1.f,
1593 viewport_rect,
1594 viewport_rect,
1595 false);
1596 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1598 // RenderPassColorMatrixProgram
1599 render_passes_in_draw_order_.clear();
1601 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1602 child_pass_id,
1603 child_rect,
1604 transform_causing_aa);
1606 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1607 root_pass_id,
1608 viewport_rect,
1609 gfx::Transform());
1611 AddRenderPassQuad(
1612 root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
1614 renderer_->DecideRenderPassAllocationsForFrame(
1615 render_passes_in_draw_order_);
1616 renderer_->DrawFrame(&render_passes_in_draw_order_,
1617 1.f,
1618 viewport_rect,
1619 viewport_rect,
1620 false);
1621 TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1623 // RenderPassMaskProgram
1624 render_passes_in_draw_order_.clear();
1626 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1627 child_pass_id,
1628 child_rect,
1629 gfx::Transform());
1631 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1632 root_pass_id,
1633 viewport_rect,
1634 gfx::Transform());
1636 AddRenderPassQuad(root_pass,
1637 child_pass,
1638 mask,
1639 FilterOperations(),
1640 gfx::Transform(),
1641 xfer_mode);
1643 renderer_->DecideRenderPassAllocationsForFrame(
1644 render_passes_in_draw_order_);
1645 renderer_->DrawFrame(&render_passes_in_draw_order_,
1646 1.f,
1647 viewport_rect,
1648 viewport_rect,
1649 false);
1650 TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1651 blend_mode);
1653 // RenderPassMaskColorMatrixProgram
1654 render_passes_in_draw_order_.clear();
1656 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1657 child_pass_id,
1658 child_rect,
1659 gfx::Transform());
1661 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1662 root_pass_id,
1663 viewport_rect,
1664 gfx::Transform());
1666 AddRenderPassQuad(
1667 root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
1669 renderer_->DecideRenderPassAllocationsForFrame(
1670 render_passes_in_draw_order_);
1671 renderer_->DrawFrame(&render_passes_in_draw_order_,
1672 1.f,
1673 viewport_rect,
1674 viewport_rect,
1675 false);
1676 TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
1677 SAMPLER_TYPE_2D, blend_mode);
1679 // RenderPassProgramAA
1680 render_passes_in_draw_order_.clear();
1682 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1683 child_pass_id,
1684 child_rect,
1685 transform_causing_aa);
1687 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1688 root_pass_id,
1689 viewport_rect,
1690 gfx::Transform());
1692 AddRenderPassQuad(root_pass,
1693 child_pass,
1695 FilterOperations(),
1696 transform_causing_aa,
1697 xfer_mode);
1699 renderer_->DecideRenderPassAllocationsForFrame(
1700 render_passes_in_draw_order_);
1701 renderer_->DrawFrame(&render_passes_in_draw_order_,
1702 1.f,
1703 viewport_rect,
1704 viewport_rect,
1705 false);
1706 TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1708 // RenderPassColorMatrixProgramAA
1709 render_passes_in_draw_order_.clear();
1711 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1712 child_pass_id,
1713 child_rect,
1714 transform_causing_aa);
1716 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1717 root_pass_id,
1718 viewport_rect,
1719 gfx::Transform());
1721 AddRenderPassQuad(
1722 root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
1724 renderer_->DecideRenderPassAllocationsForFrame(
1725 render_passes_in_draw_order_);
1726 renderer_->DrawFrame(&render_passes_in_draw_order_,
1727 1.f,
1728 viewport_rect,
1729 viewport_rect,
1730 false);
1731 TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
1733 // RenderPassMaskProgramAA
1734 render_passes_in_draw_order_.clear();
1736 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1737 child_pass_id,
1738 child_rect,
1739 transform_causing_aa);
1741 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1742 root_pass_id,
1743 viewport_rect,
1744 gfx::Transform());
1746 AddRenderPassQuad(root_pass,
1747 child_pass,
1748 mask,
1749 FilterOperations(),
1750 transform_causing_aa,
1751 xfer_mode);
1753 renderer_->DecideRenderPassAllocationsForFrame(
1754 render_passes_in_draw_order_);
1755 renderer_->DrawFrame(&render_passes_in_draw_order_,
1756 1.f,
1757 viewport_rect,
1758 viewport_rect,
1759 false);
1760 TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
1761 blend_mode);
1763 // RenderPassMaskColorMatrixProgramAA
1764 render_passes_in_draw_order_.clear();
1766 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1767 child_pass_id,
1768 child_rect,
1769 transform_causing_aa);
1771 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1772 root_pass_id,
1773 viewport_rect,
1774 transform_causing_aa);
1776 AddRenderPassQuad(
1777 root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
1779 renderer_->DecideRenderPassAllocationsForFrame(
1780 render_passes_in_draw_order_);
1781 renderer_->DrawFrame(&render_passes_in_draw_order_,
1782 1.f,
1783 viewport_rect,
1784 viewport_rect,
1785 false);
1786 TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
1787 SAMPLER_TYPE_2D, blend_mode);
1791 // At this time, the AA code path cannot be taken if the surface's rect would
1792 // project incorrectly by the given transform, because of w<0 clipping.
1793 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
1794 gfx::Rect child_rect(50, 50);
1795 RenderPassId child_pass_id(2, 0);
1796 TestRenderPass* child_pass;
1798 gfx::Rect viewport_rect(1, 1);
1799 RenderPassId root_pass_id(1, 0);
1800 TestRenderPass* root_pass;
1802 gfx::Transform transform_preventing_aa;
1803 transform_preventing_aa.ApplyPerspectiveDepth(40.0);
1804 transform_preventing_aa.RotateAboutYAxis(-20.0);
1805 transform_preventing_aa.Scale(30.0, 1.0);
1807 // Verify that the test transform and test rect actually do cause the clipped
1808 // flag to trigger. Otherwise we are not testing the intended scenario.
1809 bool clipped = false;
1810 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
1811 ASSERT_TRUE(clipped);
1813 child_pass = AddRenderPass(&render_passes_in_draw_order_,
1814 child_pass_id,
1815 child_rect,
1816 transform_preventing_aa);
1818 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1819 root_pass_id,
1820 viewport_rect,
1821 gfx::Transform());
1823 AddRenderPassQuad(root_pass,
1824 child_pass,
1826 FilterOperations(),
1827 transform_preventing_aa,
1828 SkXfermode::kSrcOver_Mode);
1830 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1831 renderer_->DrawFrame(&render_passes_in_draw_order_,
1832 1.f,
1833 viewport_rect,
1834 viewport_rect,
1835 false);
1837 // If use_aa incorrectly ignores clipping, it will use the
1838 // RenderPassProgramAA shader instead of the RenderPassProgram.
1839 TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
1842 TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
1843 gfx::Rect viewport_rect(1, 1);
1844 RenderPassId root_pass_id(1, 0);
1845 TestRenderPass* root_pass;
1847 gfx::Transform pixel_aligned_transform_causing_aa;
1848 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
1849 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
1851 root_pass = AddRenderPass(&render_passes_in_draw_order_,
1852 root_pass_id,
1853 viewport_rect,
1854 gfx::Transform());
1855 AddTransformedQuad(root_pass,
1856 viewport_rect,
1857 SK_ColorYELLOW,
1858 pixel_aligned_transform_causing_aa);
1860 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
1861 renderer_->DrawFrame(&render_passes_in_draw_order_,
1862 1.f,
1863 viewport_rect,
1864 viewport_rect,
1865 false);
1867 TestSolidColorProgramAA();
1870 class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
1871 public:
1872 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
1874 // Specifically override methods even if they are unused (used in conjunction
1875 // with StrictMock). We need to make sure that GLRenderer does not issue
1876 // framebuffer-related GLuint calls directly. Instead these are supposed to go
1877 // through the OutputSurface abstraction.
1878 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
1879 MOCK_METHOD3(reshapeWithScaleFactor,
1880 void(int width, int height, float scale_factor));
1881 MOCK_METHOD4(drawElements,
1882 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
1885 class MockOutputSurface : public OutputSurface {
1886 public:
1887 MockOutputSurface()
1888 : OutputSurface(
1889 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
1890 new StrictMock<OutputSurfaceMockContext>))) {
1891 surface_size_ = gfx::Size(100, 100);
1893 virtual ~MockOutputSurface() {}
1895 MOCK_METHOD0(EnsureBackbuffer, void());
1896 MOCK_METHOD0(DiscardBackbuffer, void());
1897 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
1898 MOCK_METHOD0(BindFramebuffer, void());
1899 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
1902 class MockOutputSurfaceTest : public GLRendererTest {
1903 protected:
1904 virtual void SetUp() {
1905 FakeOutputSurfaceClient output_surface_client_;
1906 CHECK(output_surface_.BindToClient(&output_surface_client_));
1908 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1909 resource_provider_ = ResourceProvider::Create(&output_surface_,
1910 shared_bitmap_manager_.get(),
1911 NULL,
1912 NULL,
1914 false,
1915 1).Pass();
1917 renderer_.reset(new FakeRendererGL(&renderer_client_,
1918 &settings_,
1919 &output_surface_,
1920 resource_provider_.get()));
1923 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1925 void DrawFrame(float device_scale_factor,
1926 const gfx::Rect& device_viewport_rect) {
1927 RenderPassId render_pass_id(1, 0);
1928 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
1929 render_pass_id,
1930 device_viewport_rect,
1931 gfx::Transform());
1932 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
1934 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
1936 EXPECT_CALL(output_surface_,
1937 Reshape(device_viewport_rect.size(), device_scale_factor))
1938 .Times(1);
1940 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
1942 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
1944 renderer_->DecideRenderPassAllocationsForFrame(
1945 render_passes_in_draw_order_);
1946 renderer_->DrawFrame(&render_passes_in_draw_order_,
1947 device_scale_factor,
1948 device_viewport_rect,
1949 device_viewport_rect,
1950 false);
1953 OutputSurfaceMockContext* Context() {
1954 return static_cast<OutputSurfaceMockContext*>(
1955 static_cast<TestContextProvider*>(output_surface_.context_provider())
1956 ->TestContext3d());
1959 RendererSettings settings_;
1960 FakeOutputSurfaceClient output_surface_client_;
1961 StrictMock<MockOutputSurface> output_surface_;
1962 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
1963 scoped_ptr<ResourceProvider> resource_provider_;
1964 FakeRendererClient renderer_client_;
1965 scoped_ptr<FakeRendererGL> renderer_;
1968 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
1969 gfx::Rect device_viewport_rect(1, 1);
1970 DrawFrame(1.f, device_viewport_rect);
1972 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1973 renderer_->SwapBuffers(CompositorFrameMetadata());
1976 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1977 gfx::Rect device_viewport_rect(1, 1);
1979 DrawFrame(1.f, device_viewport_rect);
1980 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1981 renderer_->SwapBuffers(CompositorFrameMetadata());
1983 device_viewport_rect = gfx::Rect(2, 2);
1985 DrawFrame(2.f, device_viewport_rect);
1986 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1987 renderer_->SwapBuffers(CompositorFrameMetadata());
1989 DrawFrame(2.f, device_viewport_rect);
1990 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1991 renderer_->SwapBuffers(CompositorFrameMetadata());
1993 device_viewport_rect = gfx::Rect(1, 1);
1995 DrawFrame(1.f, device_viewport_rect);
1996 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1997 renderer_->SwapBuffers(CompositorFrameMetadata());
2000 class GLRendererTestSyncPoint : public GLRendererPixelTest {
2001 protected:
2002 static void SyncPointCallback(int* callback_count) {
2003 ++(*callback_count);
2004 base::MessageLoop::current()->QuitWhenIdle();
2007 static void OtherCallback(int* callback_count) {
2008 ++(*callback_count);
2009 base::MessageLoop::current()->QuitWhenIdle();
2013 #if !defined(OS_ANDROID)
2014 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
2015 int sync_point_callback_count = 0;
2016 int other_callback_count = 0;
2017 gpu::gles2::GLES2Interface* gl =
2018 output_surface_->context_provider()->ContextGL();
2019 gpu::ContextSupport* context_support =
2020 output_surface_->context_provider()->ContextSupport();
2022 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
2024 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
2025 GL_INNOCENT_CONTEXT_RESET_ARB);
2027 context_support->SignalSyncPoint(
2028 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
2029 EXPECT_EQ(0, sync_point_callback_count);
2030 EXPECT_EQ(0, other_callback_count);
2032 // Make the sync point happen.
2033 gl->Finish();
2034 // Post a task after the sync point.
2035 base::MessageLoop::current()->PostTask(
2036 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
2038 base::MessageLoop::current()->Run();
2040 // The sync point shouldn't have happened since the context was lost.
2041 EXPECT_EQ(0, sync_point_callback_count);
2042 EXPECT_EQ(1, other_callback_count);
2045 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
2046 int sync_point_callback_count = 0;
2047 int other_callback_count = 0;
2049 gpu::gles2::GLES2Interface* gl =
2050 output_surface_->context_provider()->ContextGL();
2051 gpu::ContextSupport* context_support =
2052 output_surface_->context_provider()->ContextSupport();
2054 uint32 sync_point = gl->InsertSyncPointCHROMIUM();
2056 context_support->SignalSyncPoint(
2057 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
2058 EXPECT_EQ(0, sync_point_callback_count);
2059 EXPECT_EQ(0, other_callback_count);
2061 // Make the sync point happen.
2062 gl->Finish();
2063 // Post a task after the sync point.
2064 base::MessageLoop::current()->PostTask(
2065 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
2067 base::MessageLoop::current()->Run();
2069 // The sync point should have happened.
2070 EXPECT_EQ(1, sync_point_callback_count);
2071 EXPECT_EQ(1, other_callback_count);
2073 #endif // OS_ANDROID
2075 } // namespace
2076 } // namespace cc