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 "cc/output/compositor_frame_metadata.h"
8 #include "cc/resources/prioritized_resource_manager.h"
9 #include "cc/resources/resource_provider.h"
10 #include "cc/test/fake_impl_proxy.h"
11 #include "cc/test/fake_layer_tree_host_impl.h"
12 #include "cc/test/fake_output_surface.h"
13 #include "cc/test/mock_quad_culler.h"
14 #include "cc/test/pixel_test.h"
15 #include "cc/test/render_pass_test_common.h"
16 #include "cc/test/render_pass_test_utils.h"
17 #include "cc/test/test_web_graphics_context_3d.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/khronos/GLES2/gl2.h"
21 #include "third_party/skia/include/core/SkImageFilter.h"
22 #include "third_party/skia/include/core/SkMatrix.h"
23 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
24 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
25 #include "ui/gfx/transform.h"
28 using testing::AnyNumber
;
29 using testing::AtLeast
;
30 using testing::Expectation
;
31 using testing::InSequence
;
33 using testing::Return
;
34 using testing::StrictMock
;
35 using WebKit::WebGraphicsMemoryAllocation
;
36 using WebKit::WebGLId
;
37 using WebKit::WebString
;
38 using WebKit::WGC3Dbitfield
;
39 using WebKit::WGC3Dboolean
;
40 using WebKit::WGC3Dchar
;
41 using WebKit::WGC3Denum
;
42 using WebKit::WGC3Dfloat
;
43 using WebKit::WGC3Dint
;
44 using WebKit::WGC3Dintptr
;
45 using WebKit::WGC3Dsizei
;
46 using WebKit::WGC3Dsizeiptr
;
47 using WebKit::WGC3Duint
;
51 #define EXPECT_PROGRAM_VALID(program_binding) \
53 EXPECT_TRUE(program_binding->program()); \
54 EXPECT_TRUE(program_binding->initialized()); \
57 // Explicitly named to be a friend in GLRenderer for shader access.
58 class GLRendererShaderPixelTest
: public PixelTest
{
61 ASSERT_FALSE(renderer_
->IsContextLost());
62 EXPECT_PROGRAM_VALID(renderer_
->GetTileCheckerboardProgram());
63 EXPECT_PROGRAM_VALID(renderer_
->GetDebugBorderProgram());
64 EXPECT_PROGRAM_VALID(renderer_
->GetSolidColorProgram());
65 EXPECT_PROGRAM_VALID(renderer_
->GetSolidColorProgramAA());
66 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium
);
67 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh
);
68 ASSERT_FALSE(renderer_
->IsContextLost());
71 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision
) {
72 EXPECT_PROGRAM_VALID(renderer_
->GetTileProgram(precision
));
73 EXPECT_PROGRAM_VALID(renderer_
->GetTileProgramOpaque(precision
));
74 EXPECT_PROGRAM_VALID(renderer_
->GetTileProgramAA(precision
));
75 EXPECT_PROGRAM_VALID(renderer_
->GetTileProgramSwizzle(precision
));
76 EXPECT_PROGRAM_VALID(renderer_
->GetTileProgramSwizzleOpaque(precision
));
77 EXPECT_PROGRAM_VALID(renderer_
->GetTileProgramSwizzleAA(precision
));
78 EXPECT_PROGRAM_VALID(renderer_
->GetRenderPassProgram(precision
));
79 EXPECT_PROGRAM_VALID(renderer_
->GetRenderPassProgramAA(precision
));
80 EXPECT_PROGRAM_VALID(renderer_
->GetRenderPassMaskProgram(precision
));
81 EXPECT_PROGRAM_VALID(renderer_
->GetRenderPassMaskProgramAA(precision
));
83 renderer_
->GetRenderPassColorMatrixProgram(precision
));
85 renderer_
->GetRenderPassMaskColorMatrixProgramAA(precision
));
87 renderer_
->GetRenderPassColorMatrixProgramAA(precision
));
89 renderer_
->GetRenderPassMaskColorMatrixProgram(precision
));
90 EXPECT_PROGRAM_VALID(renderer_
->GetTextureProgram(precision
));
91 EXPECT_PROGRAM_VALID(renderer_
->GetTextureProgramFlip(precision
));
92 EXPECT_PROGRAM_VALID(renderer_
->GetTextureIOSurfaceProgram(precision
));
93 EXPECT_PROGRAM_VALID(renderer_
->GetVideoYUVProgram(precision
));
94 // This is unlikely to be ever true in tests due to usage of osmesa.
95 if (renderer_
->Capabilities().using_egl_image
)
96 EXPECT_PROGRAM_VALID(renderer_
->GetVideoStreamTextureProgram(precision
));
98 EXPECT_FALSE(renderer_
->GetVideoStreamTextureProgram(precision
));
104 #if !defined(OS_ANDROID)
105 TEST_F(GLRendererShaderPixelTest
, AllShadersCompile
) { TestShaders(); }
108 class FrameCountingMemoryAllocationSettingContext
109 : public TestWebGraphicsContext3D
{
111 FrameCountingMemoryAllocationSettingContext() : frame_(0) {}
113 // WebGraphicsContext3D methods.
115 // This method would normally do a glSwapBuffers under the hood.
116 virtual void prepareTexture() { frame_
++; }
117 virtual void setMemoryAllocationChangedCallbackCHROMIUM(
118 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
* callback
) {
119 memory_allocation_changed_callback_
= callback
;
121 virtual WebString
getString(WebKit::WGC3Denum name
) {
122 if (name
== GL_EXTENSIONS
)
124 "GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager "
125 "GL_CHROMIUM_discard_backbuffer");
129 // Methods added for test.
130 int frame_count() { return frame_
; }
131 void SetMemoryAllocation(WebGraphicsMemoryAllocation allocation
) {
132 memory_allocation_changed_callback_
->onMemoryAllocationChanged(allocation
);
137 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
*
138 memory_allocation_changed_callback_
;
141 class FakeRendererClient
: public RendererClient
{
144 : host_impl_(&proxy_
),
145 set_full_root_layer_damage_count_(0),
146 last_call_was_set_visibility_(0),
147 root_layer_(LayerImpl::Create(host_impl_
.active_tree(), 1)),
148 memory_allocation_limit_bytes_(
149 PrioritizedResourceManager::DefaultMemoryAllocationLimit()) {
150 root_layer_
->CreateRenderSurface();
151 RenderPass::Id render_pass_id
=
152 root_layer_
->render_surface()->RenderPassId();
153 scoped_ptr
<RenderPass
> root_render_pass
= RenderPass::Create();
154 root_render_pass
->SetNew(
155 render_pass_id
, gfx::Rect(), gfx::Rect(), gfx::Transform());
156 render_passes_in_draw_order_
.push_back(root_render_pass
.Pass());
159 // RendererClient methods.
160 virtual gfx::Size
DeviceViewportSize() const OVERRIDE
{
161 static gfx::Size
fake_size(1, 1);
164 virtual const LayerTreeSettings
& Settings() const OVERRIDE
{
165 static LayerTreeSettings fake_settings
;
166 return fake_settings
;
168 virtual void SetFullRootLayerDamage() OVERRIDE
{
169 set_full_root_layer_damage_count_
++;
171 virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy
& policy
)
173 memory_allocation_limit_bytes_
= policy
.bytes_limit_when_visible
;
175 virtual void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy
& policy
)
177 if (last_call_was_set_visibility_
)
178 *last_call_was_set_visibility_
= false;
180 virtual bool HasImplThread() const OVERRIDE
{ return false; }
181 virtual bool ShouldClearRootRenderPass() const OVERRIDE
{ return true; }
182 virtual CompositorFrameMetadata
MakeCompositorFrameMetadata() const OVERRIDE
{
183 return CompositorFrameMetadata();
185 virtual bool AllowPartialSwap() const OVERRIDE
{
189 // Methods added for test.
190 int set_full_root_layer_damage_count() const {
191 return set_full_root_layer_damage_count_
;
193 void set_last_call_was_set_visibility_pointer(
194 bool* last_call_was_set_visibility
) {
195 last_call_was_set_visibility_
= last_call_was_set_visibility
;
198 RenderPass
* root_render_pass() { return render_passes_in_draw_order_
.back(); }
199 RenderPassList
* render_passes_in_draw_order() {
200 return &render_passes_in_draw_order_
;
203 size_t memory_allocation_limit_bytes() const {
204 return memory_allocation_limit_bytes_
;
208 FakeImplProxy proxy_
;
209 FakeLayerTreeHostImpl host_impl_
;
210 int set_full_root_layer_damage_count_
;
211 bool* last_call_was_set_visibility_
;
212 scoped_ptr
<LayerImpl
> root_layer_
;
213 RenderPassList render_passes_in_draw_order_
;
214 size_t memory_allocation_limit_bytes_
;
217 class FakeRendererGL
: public GLRenderer
{
219 FakeRendererGL(RendererClient
* client
,
220 OutputSurface
* output_surface
,
221 ResourceProvider
* resource_provider
)
222 : GLRenderer(client
, output_surface
, resource_provider
, 0) {}
224 // GLRenderer methods.
226 // Changing visibility to public.
227 using GLRenderer::Initialize
;
228 using GLRenderer::IsBackbufferDiscarded
;
229 using GLRenderer::DoDrawQuad
;
230 using GLRenderer::BeginDrawingFrame
;
231 using GLRenderer::FinishDrawingQuadList
;
234 class GLRendererTest
: public testing::Test
{
237 : suggest_have_backbuffer_yes_(1, true),
238 suggest_have_backbuffer_no_(1, false),
239 output_surface_(FakeOutputSurface::Create3d(
240 scoped_ptr
<WebKit::WebGraphicsContext3D
>(
241 new FrameCountingMemoryAllocationSettingContext()))),
242 resource_provider_(ResourceProvider::Create(output_surface_
.get(), 0)),
243 renderer_(&mock_client_
,
244 output_surface_
.get(),
245 resource_provider_
.get()) {}
247 virtual void SetUp() { renderer_
.Initialize(); }
249 void SwapBuffers() { renderer_
.SwapBuffers(LatencyInfo()); }
251 FrameCountingMemoryAllocationSettingContext
* Context() {
252 return static_cast<FrameCountingMemoryAllocationSettingContext
*>(
253 output_surface_
->context3d());
256 WebGraphicsMemoryAllocation suggest_have_backbuffer_yes_
;
257 WebGraphicsMemoryAllocation suggest_have_backbuffer_no_
;
259 scoped_ptr
<OutputSurface
> output_surface_
;
260 FakeRendererClient mock_client_
;
261 scoped_ptr
<ResourceProvider
> resource_provider_
;
262 FakeRendererGL renderer_
;
265 // Closing the namespace here so that GLRendererShaderTest can take advantage
266 // of the friend relationship with GLRenderer and all of the mock classes
267 // declared above it.
270 class GLRendererShaderTest
: public testing::Test
{
272 GLRendererShaderTest()
273 : output_surface_(FakeOutputSurface::Create3d()),
274 resource_provider_(ResourceProvider::Create(output_surface_
.get(), 0)),
275 renderer_(GLRenderer::Create(&mock_client_
,
276 output_surface_
.get(),
277 resource_provider_
.get(),
280 void TestRenderPassProgram() {
281 EXPECT_PROGRAM_VALID(renderer_
->render_pass_program_
);
282 EXPECT_TRUE(renderer_
->program_shadow_
==
283 renderer_
->render_pass_program_
->program());
286 void TestRenderPassColorMatrixProgram() {
287 EXPECT_PROGRAM_VALID(renderer_
->render_pass_color_matrix_program_
);
288 EXPECT_TRUE(renderer_
->program_shadow_
==
289 renderer_
->render_pass_color_matrix_program_
->program());
292 void TestRenderPassMaskProgram() {
293 EXPECT_PROGRAM_VALID(renderer_
->render_pass_mask_program_
);
294 EXPECT_TRUE(renderer_
->program_shadow_
==
295 renderer_
->render_pass_mask_program_
->program());
298 void TestRenderPassMaskColorMatrixProgram() {
299 EXPECT_PROGRAM_VALID(renderer_
->render_pass_mask_color_matrix_program_
);
300 EXPECT_TRUE(renderer_
->program_shadow_
==
301 renderer_
->render_pass_mask_color_matrix_program_
->program());
304 void TestRenderPassProgramAA() {
305 EXPECT_PROGRAM_VALID(renderer_
->render_pass_program_aa_
);
306 EXPECT_TRUE(renderer_
->program_shadow_
==
307 renderer_
->render_pass_program_aa_
->program());
310 void TestRenderPassColorMatrixProgramAA() {
311 EXPECT_PROGRAM_VALID(renderer_
->render_pass_color_matrix_program_aa_
);
312 EXPECT_TRUE(renderer_
->program_shadow_
==
313 renderer_
->render_pass_color_matrix_program_aa_
->program());
316 void TestRenderPassMaskProgramAA() {
317 EXPECT_PROGRAM_VALID(renderer_
->render_pass_mask_program_
);
318 EXPECT_TRUE(renderer_
->program_shadow_
==
319 renderer_
->render_pass_program_aa_
->program());
322 void TestRenderPassMaskColorMatrixProgramAA() {
323 EXPECT_PROGRAM_VALID(renderer_
->render_pass_mask_color_matrix_program_aa_
);
324 EXPECT_TRUE(renderer_
->program_shadow_
==
325 renderer_
->render_pass_color_matrix_program_aa_
->program());
328 void TestSolidColorProgramAA() {
329 EXPECT_PROGRAM_VALID(renderer_
->solid_color_program_aa_
);
330 EXPECT_TRUE(renderer_
->program_shadow_
==
331 renderer_
->solid_color_program_aa_
->program());
334 scoped_ptr
<OutputSurface
> output_surface_
;
335 FakeRendererClient mock_client_
;
336 scoped_ptr
<ResourceProvider
> resource_provider_
;
337 scoped_ptr
<GLRenderer
> renderer_
;
342 // Test GLRenderer discardBackbuffer functionality:
343 // Suggest recreating framebuffer when one already exists.
344 // Expected: it does nothing.
345 TEST_F(GLRendererTest
, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing
) {
346 Context()->SetMemoryAllocation(suggest_have_backbuffer_yes_
);
347 EXPECT_EQ(0, mock_client_
.set_full_root_layer_damage_count());
348 EXPECT_FALSE(renderer_
.IsBackbufferDiscarded());
351 EXPECT_EQ(1, Context()->frame_count());
354 // Test GLRenderer DiscardBackbuffer functionality:
355 // Suggest discarding framebuffer when one exists and the renderer is not
357 // Expected: it is discarded and damage tracker is reset.
360 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible
) {
361 renderer_
.SetVisible(false);
362 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_
);
363 EXPECT_EQ(1, mock_client_
.set_full_root_layer_damage_count());
364 EXPECT_TRUE(renderer_
.IsBackbufferDiscarded());
367 // Test GLRenderer DiscardBackbuffer functionality:
368 // Suggest discarding framebuffer when one exists and the renderer is visible.
369 // Expected: the allocation is ignored.
370 TEST_F(GLRendererTest
, SuggestBackbufferNoDoNothingWhenVisible
) {
371 renderer_
.SetVisible(true);
372 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_
);
373 EXPECT_EQ(0, mock_client_
.set_full_root_layer_damage_count());
374 EXPECT_FALSE(renderer_
.IsBackbufferDiscarded());
377 // Test GLRenderer DiscardBackbuffer functionality:
378 // Suggest discarding framebuffer when one does not exist.
379 // Expected: it does nothing.
380 TEST_F(GLRendererTest
, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
) {
381 renderer_
.SetVisible(false);
382 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_
);
383 EXPECT_EQ(1, mock_client_
.set_full_root_layer_damage_count());
384 EXPECT_TRUE(renderer_
.IsBackbufferDiscarded());
386 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_
);
387 EXPECT_EQ(1, mock_client_
.set_full_root_layer_damage_count());
388 EXPECT_TRUE(renderer_
.IsBackbufferDiscarded());
391 // Test GLRenderer DiscardBackbuffer functionality:
392 // Begin drawing a frame while a framebuffer is discarded.
393 // Expected: will recreate framebuffer.
394 TEST_F(GLRendererTest
, DiscardedBackbufferIsRecreatedForScopeDuration
) {
395 renderer_
.SetVisible(false);
396 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_
);
397 EXPECT_TRUE(renderer_
.IsBackbufferDiscarded());
398 EXPECT_EQ(1, mock_client_
.set_full_root_layer_damage_count());
400 renderer_
.SetVisible(true);
401 renderer_
.DrawFrame(mock_client_
.render_passes_in_draw_order());
402 EXPECT_FALSE(renderer_
.IsBackbufferDiscarded());
405 EXPECT_EQ(1, Context()->frame_count());
408 TEST_F(GLRendererTest
, FramebufferDiscardedAfterReadbackWhenNotVisible
) {
409 renderer_
.SetVisible(false);
410 Context()->SetMemoryAllocation(suggest_have_backbuffer_no_
);
411 EXPECT_TRUE(renderer_
.IsBackbufferDiscarded());
412 EXPECT_EQ(1, mock_client_
.set_full_root_layer_damage_count());
415 renderer_
.DrawFrame(mock_client_
.render_passes_in_draw_order());
416 EXPECT_FALSE(renderer_
.IsBackbufferDiscarded());
418 renderer_
.GetFramebufferPixels(pixels
, gfx::Rect(0, 0, 1, 1));
419 EXPECT_TRUE(renderer_
.IsBackbufferDiscarded());
420 EXPECT_EQ(2, mock_client_
.set_full_root_layer_damage_count());
423 class ForbidSynchronousCallContext
: public TestWebGraphicsContext3D
{
425 ForbidSynchronousCallContext() {}
427 virtual bool getActiveAttrib(WebGLId program
,
433 virtual bool getActiveUniform(WebGLId program
,
439 virtual void getAttachedShaders(WebGLId program
,
440 WGC3Dsizei max_count
,
445 virtual WGC3Dint
getAttribLocation(WebGLId program
, const WGC3Dchar
* name
) {
449 virtual void getBooleanv(WGC3Denum pname
, WGC3Dboolean
* value
) {
452 virtual void getBufferParameteriv(WGC3Denum target
,
457 virtual Attributes
getContextAttributes() {
461 virtual WGC3Denum
getError() {
465 virtual void getFloatv(WGC3Denum pname
, WGC3Dfloat
* value
) { ADD_FAILURE(); }
466 virtual void getFramebufferAttachmentParameteriv(WGC3Denum target
,
467 WGC3Denum attachment
,
472 virtual void getIntegerv(WGC3Denum pname
, WGC3Dint
* value
) {
473 if (pname
== GL_MAX_TEXTURE_SIZE
) {
474 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
481 // We allow querying the shader compilation and program link status in debug
482 // mode, but not release.
483 virtual void getProgramiv(WebGLId program
, WGC3Denum pname
, WGC3Dint
* value
) {
491 virtual void getShaderiv(WebGLId shader
, WGC3Denum pname
, WGC3Dint
* value
) {
499 virtual WebString
getString(WGC3Denum name
) {
500 // We allow querying the extension string.
501 // FIXME: It'd be better to check that we only do this before starting any
502 // other expensive work (like starting a compilation)
503 if (name
!= GL_EXTENSIONS
)
508 virtual WebString
getProgramInfoLog(WebGLId program
) {
512 virtual void getRenderbufferParameteriv(WGC3Denum target
,
518 virtual WebString
getShaderInfoLog(WebGLId shader
) {
522 virtual void getShaderPrecisionFormat(WGC3Denum shadertype
,
523 WGC3Denum precisiontype
,
525 WGC3Dint
* precision
) {
528 virtual WebString
getShaderSource(WebGLId shader
) {
532 virtual void getTexParameterfv(WGC3Denum target
,
537 virtual void getTexParameteriv(WGC3Denum target
,
542 virtual void getUniformfv(WebGLId program
,
547 virtual void getUniformiv(WebGLId program
,
552 virtual WGC3Dint
getUniformLocation(WebGLId program
, const WGC3Dchar
* name
) {
556 virtual void getVertexAttribfv(WGC3Duint index
,
561 virtual void getVertexAttribiv(WGC3Duint index
,
566 virtual WGC3Dsizeiptr
getVertexAttribOffset(WGC3Duint index
,
573 // This test isn't using the same fixture as GLRendererTest, and you can't mix
574 // TEST() and TEST_F() with the same name, Hence LRC2.
575 TEST(GLRendererTest2
, InitializationDoesNotMakeSynchronousCalls
) {
576 FakeRendererClient mock_client
;
577 scoped_ptr
<OutputSurface
> output_surface(
578 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
579 new ForbidSynchronousCallContext
)));
580 scoped_ptr
<ResourceProvider
> resource_provider(
581 ResourceProvider::Create(output_surface
.get(), 0));
582 FakeRendererGL
renderer(
583 &mock_client
, output_surface
.get(), resource_provider
.get());
585 EXPECT_TRUE(renderer
.Initialize());
588 class LoseContextOnFirstGetContext
: public TestWebGraphicsContext3D
{
590 LoseContextOnFirstGetContext() : context_lost_(false) {}
592 virtual bool makeContextCurrent() OVERRIDE
{ return !context_lost_
; }
594 virtual void getProgramiv(WebGLId program
, WGC3Denum pname
, WGC3Dint
* value
)
596 context_lost_
= true;
600 virtual void getShaderiv(WebGLId shader
, WGC3Denum pname
, WGC3Dint
* value
)
602 context_lost_
= true;
606 virtual WGC3Denum
getGraphicsResetStatusARB() OVERRIDE
{
607 return context_lost_
? 1 : 0;
614 TEST(GLRendererTest2
, InitializationWithQuicklyLostContextDoesNotAssert
) {
615 FakeRendererClient mock_client
;
616 scoped_ptr
<OutputSurface
> output_surface(
617 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
618 new LoseContextOnFirstGetContext
)));
619 scoped_ptr
<ResourceProvider
> resource_provider(
620 ResourceProvider::Create(output_surface
.get(), 0));
621 FakeRendererGL
renderer(
622 &mock_client
, output_surface
.get(), resource_provider
.get());
624 renderer
.Initialize();
627 class ContextThatDoesNotSupportMemoryManagmentExtensions
628 : public TestWebGraphicsContext3D
{
630 ContextThatDoesNotSupportMemoryManagmentExtensions() {}
632 // WebGraphicsContext3D methods.
634 // This method would normally do a glSwapBuffers under the hood.
635 virtual void prepareTexture() {}
636 virtual void setMemoryAllocationChangedCallbackCHROMIUM(
637 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
* callback
) {}
638 virtual WebString
getString(WebKit::WGC3Denum name
) { return WebString(); }
643 InitWithoutGpuMemManagerExtensionSupportShouldDefaultToNonZeroAllocation
) {
644 FakeRendererClient mock_client
;
645 scoped_ptr
<OutputSurface
> output_surface(
646 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
647 new ContextThatDoesNotSupportMemoryManagmentExtensions
)));
648 scoped_ptr
<ResourceProvider
> resource_provider(
649 ResourceProvider::Create(output_surface
.get(), 0));
650 FakeRendererGL
renderer(
651 &mock_client
, output_surface
.get(), resource_provider
.get());
653 renderer
.Initialize();
655 EXPECT_GT(mock_client
.memory_allocation_limit_bytes(), 0ul);
658 class ClearCountingContext
: public TestWebGraphicsContext3D
{
660 ClearCountingContext() : clear_(0) {}
662 virtual void clear(WGC3Dbitfield
) { clear_
++; }
664 int clear_count() const { return clear_
; }
670 TEST(GLRendererTest2
, OpaqueBackground
) {
671 FakeRendererClient mock_client
;
672 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
673 scoped_ptr
<WebKit::WebGraphicsContext3D
>(new ClearCountingContext
)));
674 ClearCountingContext
* context
=
675 static_cast<ClearCountingContext
*>(output_surface
->context3d());
676 scoped_ptr
<ResourceProvider
> resource_provider(
677 ResourceProvider::Create(output_surface
.get(), 0));
678 FakeRendererGL
renderer(
679 &mock_client
, output_surface
.get(), resource_provider
.get());
681 mock_client
.root_render_pass()->has_transparent_background
= false;
683 EXPECT_TRUE(renderer
.Initialize());
685 renderer
.DrawFrame(mock_client
.render_passes_in_draw_order());
687 // On DEBUG builds, render passes with opaque background clear to blue to
688 // easily see regions that were not drawn on the screen.
690 EXPECT_EQ(0, context
->clear_count());
692 EXPECT_EQ(1, context
->clear_count());
696 TEST(GLRendererTest2
, TransparentBackground
) {
697 FakeRendererClient mock_client
;
698 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
699 scoped_ptr
<WebKit::WebGraphicsContext3D
>(new ClearCountingContext
)));
700 ClearCountingContext
* context
=
701 static_cast<ClearCountingContext
*>(output_surface
->context3d());
702 scoped_ptr
<ResourceProvider
> resource_provider(
703 ResourceProvider::Create(output_surface
.get(), 0));
704 FakeRendererGL
renderer(
705 &mock_client
, output_surface
.get(), resource_provider
.get());
707 mock_client
.root_render_pass()->has_transparent_background
= true;
709 EXPECT_TRUE(renderer
.Initialize());
711 renderer
.DrawFrame(mock_client
.render_passes_in_draw_order());
713 EXPECT_EQ(1, context
->clear_count());
716 class VisibilityChangeIsLastCallTrackingContext
717 : public TestWebGraphicsContext3D
{
719 VisibilityChangeIsLastCallTrackingContext()
720 : last_call_was_set_visibility_(0) {}
722 // WebGraphicsContext3D methods.
723 virtual void setVisibilityCHROMIUM(bool visible
) {
724 if (!last_call_was_set_visibility_
)
726 DCHECK(*last_call_was_set_visibility_
== false);
727 *last_call_was_set_visibility_
= true;
729 virtual void flush() {
730 if (last_call_was_set_visibility_
)
731 *last_call_was_set_visibility_
= false;
733 virtual void deleteTexture(WebGLId
) {
734 if (last_call_was_set_visibility_
)
735 *last_call_was_set_visibility_
= false;
737 virtual void deleteFramebuffer(WebGLId
) {
738 if (last_call_was_set_visibility_
)
739 *last_call_was_set_visibility_
= false;
741 virtual void deleteRenderbuffer(WebGLId
) {
742 if (last_call_was_set_visibility_
)
743 *last_call_was_set_visibility_
= false;
746 // This method would normally do a glSwapBuffers under the hood.
747 virtual WebString
getString(WebKit::WGC3Denum name
) {
748 if (name
== GL_EXTENSIONS
)
750 "GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager "
751 "GL_CHROMIUM_discard_backbuffer");
755 // Methods added for test.
756 void set_last_call_was_set_visibility_pointer(
757 bool* last_call_was_set_visibility
) {
758 last_call_was_set_visibility_
= last_call_was_set_visibility
;
762 bool* last_call_was_set_visibility_
;
765 TEST(GLRendererTest2
, VisibilityChangeIsLastCall
) {
766 FakeRendererClient mock_client
;
767 scoped_ptr
<OutputSurface
> output_surface(
768 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
769 new VisibilityChangeIsLastCallTrackingContext
)));
770 VisibilityChangeIsLastCallTrackingContext
* context
=
771 static_cast<VisibilityChangeIsLastCallTrackingContext
*>(
772 output_surface
->context3d());
773 scoped_ptr
<ResourceProvider
> resource_provider(
774 ResourceProvider::Create(output_surface
.get(), 0));
775 FakeRendererGL
renderer(
776 &mock_client
, output_surface
.get(), resource_provider
.get());
778 EXPECT_TRUE(renderer
.Initialize());
780 bool last_call_was_set_visiblity
= false;
781 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to the
782 // GPU process, after glFlush is called, and after the RendererClient's
783 // EnforceManagedMemoryPolicy is called. Plumb this tracking between both the
784 // RenderClient and the Context by giving them both a pointer to a variable on
786 context
->set_last_call_was_set_visibility_pointer(
787 &last_call_was_set_visiblity
);
788 mock_client
.set_last_call_was_set_visibility_pointer(
789 &last_call_was_set_visiblity
);
790 renderer
.SetVisible(true);
791 renderer
.DrawFrame(mock_client
.render_passes_in_draw_order());
792 renderer
.SetVisible(false);
793 EXPECT_TRUE(last_call_was_set_visiblity
);
796 class TextureStateTrackingContext
: public TestWebGraphicsContext3D
{
798 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM
) {}
800 virtual WebString
getString(WGC3Denum name
) {
801 if (name
== GL_EXTENSIONS
)
802 return WebString("GL_OES_EGL_image_external");
806 MOCK_METHOD3(texParameteri
,
807 void(WGC3Denum target
, WGC3Denum pname
, WGC3Dint param
));
808 MOCK_METHOD4(drawElements
,
812 WGC3Dintptr offset
));
814 virtual void activeTexture(WGC3Denum texture
) {
815 EXPECT_NE(texture
, active_texture_
);
816 active_texture_
= texture
;
819 WGC3Denum
active_texture() const { return active_texture_
; }
822 WGC3Denum active_texture_
;
825 TEST(GLRendererTest2
, ActiveTextureState
) {
826 FakeRendererClient fake_client
;
827 scoped_ptr
<OutputSurface
> output_surface(
828 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
829 new TextureStateTrackingContext
)));
830 TextureStateTrackingContext
* context
=
831 static_cast<TextureStateTrackingContext
*>(output_surface
->context3d());
832 scoped_ptr
<ResourceProvider
> resource_provider(
833 ResourceProvider::Create(output_surface
.get(), 0));
834 FakeRendererGL
renderer(
835 &fake_client
, output_surface
.get(), resource_provider
.get());
837 // During initialization we are allowed to set any texture parameters.
838 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
839 EXPECT_TRUE(renderer
.Initialize());
841 cc::RenderPass::Id
id(1, 1);
842 scoped_ptr
<TestRenderPass
> pass
= TestRenderPass::Create();
844 gfx::Rect(0, 0, 100, 100),
845 gfx::Rect(0, 0, 100, 100),
847 pass
->AppendOneOfEveryQuadType(resource_provider
.get(), RenderPass::Id(2, 1));
849 // Set up expected texture filter state transitions that match the quads
850 // created in AppendOneOfEveryQuadType().
851 Mock::VerifyAndClearExpectations(context
);
855 // yuv_quad is drawn with the default linear filter.
856 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
858 // tile_quad is drawn with GL_NEAREST because it is not transformed or
862 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
865 texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
866 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
868 // transformed_tile_quad uses GL_LINEAR.
869 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
871 // scaled_tile_quad also uses GL_LINEAR.
872 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
874 // The remaining quads also use GL_LINEAR because nearest neighbor
875 // filtering is currently only used with tile quads.
876 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(6);
879 cc::DirectRenderer::DrawingFrame drawing_frame
;
880 renderer
.BeginDrawingFrame(&drawing_frame
);
881 EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE0
), context
->active_texture());
883 for (cc::QuadList::BackToFrontIterator
884 it
= pass
->quad_list
.BackToFrontBegin();
885 it
!= pass
->quad_list
.BackToFrontEnd();
887 renderer
.DoDrawQuad(&drawing_frame
, *it
);
889 renderer
.FinishDrawingQuadList();
890 EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE0
), context
->active_texture());
891 Mock::VerifyAndClearExpectations(context
);
894 class NoClearRootRenderPassFakeClient
: public FakeRendererClient
{
896 virtual bool ShouldClearRootRenderPass() const OVERRIDE
{ return false; }
899 class NoClearRootRenderPassMockContext
: public TestWebGraphicsContext3D
{
901 MOCK_METHOD1(clear
, void(WGC3Dbitfield mask
));
902 MOCK_METHOD4(drawElements
,
906 WGC3Dintptr offset
));
909 TEST(GLRendererTest2
, ShouldClearRootRenderPass
) {
910 NoClearRootRenderPassFakeClient mock_client
;
911 scoped_ptr
<OutputSurface
> output_surface(
912 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
913 new NoClearRootRenderPassMockContext
)));
914 NoClearRootRenderPassMockContext
* mock_context
=
915 static_cast<NoClearRootRenderPassMockContext
*>(
916 output_surface
->context3d());
917 scoped_ptr
<ResourceProvider
> resource_provider(
918 ResourceProvider::Create(output_surface
.get(), 0));
919 FakeRendererGL
renderer(
920 &mock_client
, output_surface
.get(), resource_provider
.get());
921 EXPECT_TRUE(renderer
.Initialize());
923 gfx::Rect
viewport_rect(mock_client
.DeviceViewportSize());
924 ScopedPtrVector
<RenderPass
>& render_passes
=
925 *mock_client
.render_passes_in_draw_order();
926 render_passes
.clear();
928 RenderPass::Id
root_pass_id(1, 0);
929 TestRenderPass
* root_pass
= AddRenderPass(
930 &render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
931 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
933 RenderPass::Id
child_pass_id(2, 0);
934 TestRenderPass
* child_pass
= AddRenderPass(
935 &render_passes
, child_pass_id
, viewport_rect
, gfx::Transform());
936 AddQuad(child_pass
, viewport_rect
, SK_ColorBLUE
);
938 AddRenderPassQuad(root_pass
, child_pass
);
940 // First render pass is not the root one, clearing should happen.
941 EXPECT_CALL(*mock_context
, clear(GL_COLOR_BUFFER_BIT
)).Times(AtLeast(1));
943 Expectation first_render_pass
=
944 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(1);
946 // The second render pass is the root one, clearing should be prevented.
947 EXPECT_CALL(*mock_context
, clear(GL_COLOR_BUFFER_BIT
)).Times(0)
948 .After(first_render_pass
);
950 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
)).Times(AnyNumber())
951 .After(first_render_pass
);
953 renderer
.DecideRenderPassAllocationsForFrame(
954 *mock_client
.render_passes_in_draw_order());
955 renderer
.DrawFrame(mock_client
.render_passes_in_draw_order());
957 // In multiple render passes all but the root pass should clear the
959 Mock::VerifyAndClearExpectations(&mock_context
);
962 class ScissorTestOnClearCheckingContext
: public TestWebGraphicsContext3D
{
964 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
966 virtual void clear(WGC3Dbitfield
) { EXPECT_FALSE(scissor_enabled_
); }
968 virtual void enable(WGC3Denum cap
) {
969 if (cap
== GL_SCISSOR_TEST
)
970 scissor_enabled_
= true;
973 virtual void disable(WGC3Denum cap
) {
974 if (cap
== GL_SCISSOR_TEST
)
975 scissor_enabled_
= false;
979 bool scissor_enabled_
;
982 TEST(GLRendererTest2
, ScissorTestWhenClearing
) {
983 FakeRendererClient mock_client
;
984 scoped_ptr
<OutputSurface
> output_surface(
985 FakeOutputSurface::Create3d(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
986 new ScissorTestOnClearCheckingContext
)));
987 scoped_ptr
<ResourceProvider
> resource_provider(
988 ResourceProvider::Create(output_surface
.get(), 0));
989 FakeRendererGL
renderer(
990 &mock_client
, output_surface
.get(), resource_provider
.get());
991 EXPECT_TRUE(renderer
.Initialize());
992 EXPECT_FALSE(renderer
.Capabilities().using_partial_swap
);
994 gfx::Rect
viewport_rect(mock_client
.DeviceViewportSize());
995 ScopedPtrVector
<RenderPass
>& render_passes
=
996 *mock_client
.render_passes_in_draw_order();
997 render_passes
.clear();
999 gfx::Rect
grand_child_rect(25, 25);
1000 RenderPass::Id
grand_child_pass_id(3, 0);
1001 TestRenderPass
* grand_child_pass
= AddRenderPass(
1002 &render_passes
, grand_child_pass_id
, grand_child_rect
, gfx::Transform());
1003 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1005 gfx::Rect
child_rect(50, 50);
1006 RenderPass::Id
child_pass_id(2, 0);
1007 TestRenderPass
* child_pass
= AddRenderPass(
1008 &render_passes
, child_pass_id
, child_rect
, gfx::Transform());
1009 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1011 RenderPass::Id
root_pass_id(1, 0);
1012 TestRenderPass
* root_pass
= AddRenderPass(
1013 &render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1014 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1016 AddRenderPassQuad(root_pass
, child_pass
);
1017 AddRenderPassQuad(child_pass
, grand_child_pass
);
1019 renderer
.DecideRenderPassAllocationsForFrame(
1020 *mock_client
.render_passes_in_draw_order());
1021 renderer
.DrawFrame(mock_client
.render_passes_in_draw_order());
1024 TEST_F(GLRendererShaderTest
, DrawRenderPassQuadShaderPermutations
) {
1025 gfx::Rect
viewport_rect(mock_client_
.DeviceViewportSize());
1026 ScopedPtrVector
<RenderPass
>* render_passes
=
1027 mock_client_
.render_passes_in_draw_order();
1029 gfx::Rect
grand_child_rect(25, 25);
1030 RenderPass::Id
grand_child_pass_id(3, 0);
1031 TestRenderPass
* grand_child_pass
;
1033 gfx::Rect
child_rect(50, 50);
1034 RenderPass::Id
child_pass_id(2, 0);
1035 TestRenderPass
* child_pass
;
1037 RenderPass::Id
root_pass_id(1, 0);
1038 TestRenderPass
* root_pass
;
1040 cc::ResourceProvider::ResourceId mask
=
1041 resource_provider_
->CreateResource(gfx::Size(20, 12),
1042 resource_provider_
->best_texture_format(),
1043 ResourceProvider::TextureUsageAny
);
1044 resource_provider_
->AllocateForTesting(mask
);
1046 SkScalar matrix
[20];
1047 float amount
= 0.5f
;
1048 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1049 matrix
[1] = 0.715f
- 0.715f
* amount
;
1050 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1051 matrix
[3] = matrix
[4] = 0;
1052 matrix
[5] = 0.213f
- 0.213f
* amount
;
1053 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1054 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1055 matrix
[8] = matrix
[9] = 0;
1056 matrix
[10] = 0.213f
- 0.213f
* amount
;
1057 matrix
[11] = 0.715f
- 0.715f
* amount
;
1058 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1059 matrix
[13] = matrix
[14] = 0;
1060 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1062 skia::RefPtr
<SkColorFilter
> color_filter(
1063 skia::AdoptRef(new SkColorMatrixFilter(matrix
)));
1064 skia::RefPtr
<SkImageFilter
> filter
= skia::AdoptRef(
1065 SkColorFilterImageFilter::Create(color_filter
.get(), NULL
));
1067 gfx::Transform transform_causing_aa
;
1068 transform_causing_aa
.Rotate(20.0);
1070 // RenderPassProgram
1071 render_passes
->clear();
1073 grand_child_pass
= AddRenderPass(
1074 render_passes
, grand_child_pass_id
, grand_child_rect
, gfx::Transform());
1075 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1077 child_pass
= AddRenderPass(
1078 render_passes
, child_pass_id
, child_rect
, gfx::Transform());
1079 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1081 root_pass
= AddRenderPass(
1082 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1083 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1085 AddRenderPassQuad(root_pass
,
1088 skia::RefPtr
<SkImageFilter
>(),
1090 AddRenderPassQuad(child_pass
, grand_child_pass
);
1092 renderer_
->DecideRenderPassAllocationsForFrame(
1093 *mock_client_
.render_passes_in_draw_order());
1094 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1095 TestRenderPassProgram();
1097 // RenderPassColorMatrixProgram
1098 render_passes
->clear();
1100 grand_child_pass
= AddRenderPass(render_passes
,
1101 grand_child_pass_id
,
1103 transform_causing_aa
);
1104 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1106 child_pass
= AddRenderPass(
1107 render_passes
, child_pass_id
, child_rect
, transform_causing_aa
);
1108 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1110 root_pass
= AddRenderPass(
1111 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1112 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1114 AddRenderPassQuad(root_pass
, child_pass
, 0, filter
, gfx::Transform());
1115 AddRenderPassQuad(child_pass
, grand_child_pass
);
1117 renderer_
->DecideRenderPassAllocationsForFrame(
1118 *mock_client_
.render_passes_in_draw_order());
1119 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1120 TestRenderPassColorMatrixProgram();
1122 // RenderPassMaskProgram
1123 render_passes
->clear();
1125 grand_child_pass
= AddRenderPass(render_passes
,
1126 grand_child_pass_id
,
1129 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1131 child_pass
= AddRenderPass(
1132 render_passes
, child_pass_id
, child_rect
, gfx::Transform());
1133 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1135 root_pass
= AddRenderPass(
1136 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1137 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1139 AddRenderPassQuad(root_pass
,
1142 skia::RefPtr
<SkImageFilter
>(),
1144 AddRenderPassQuad(child_pass
, grand_child_pass
);
1146 renderer_
->DecideRenderPassAllocationsForFrame(
1147 *mock_client_
.render_passes_in_draw_order());
1148 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1149 TestRenderPassMaskProgram();
1151 // RenderPassMaskColorMatrixProgram
1152 render_passes
->clear();
1154 grand_child_pass
= AddRenderPass(
1155 render_passes
, grand_child_pass_id
, grand_child_rect
, gfx::Transform());
1156 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1158 child_pass
= AddRenderPass(
1159 render_passes
, child_pass_id
, child_rect
, gfx::Transform());
1160 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1162 root_pass
= AddRenderPass(
1163 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1164 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1166 AddRenderPassQuad(root_pass
, child_pass
, mask
, filter
, gfx::Transform());
1167 AddRenderPassQuad(child_pass
, grand_child_pass
);
1169 renderer_
->DecideRenderPassAllocationsForFrame(
1170 *mock_client_
.render_passes_in_draw_order());
1171 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1172 TestRenderPassMaskColorMatrixProgram();
1174 // RenderPassProgramAA
1175 render_passes
->clear();
1177 grand_child_pass
= AddRenderPass(render_passes
,
1178 grand_child_pass_id
,
1180 transform_causing_aa
);
1181 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1183 child_pass
= AddRenderPass(
1184 render_passes
, child_pass_id
, child_rect
, transform_causing_aa
);
1185 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1187 root_pass
= AddRenderPass(
1188 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1189 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1191 AddRenderPassQuad(root_pass
,
1194 skia::RefPtr
<SkImageFilter
>(),
1195 transform_causing_aa
);
1196 AddRenderPassQuad(child_pass
, grand_child_pass
);
1198 renderer_
->DecideRenderPassAllocationsForFrame(
1199 *mock_client_
.render_passes_in_draw_order());
1200 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1201 TestRenderPassProgramAA();
1203 // RenderPassColorMatrixProgramAA
1204 render_passes
->clear();
1206 grand_child_pass
= AddRenderPass(render_passes
,
1207 grand_child_pass_id
,
1209 transform_causing_aa
);
1210 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1212 child_pass
= AddRenderPass(
1213 render_passes
, child_pass_id
, child_rect
, transform_causing_aa
);
1214 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1216 root_pass
= AddRenderPass(
1217 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1218 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1220 AddRenderPassQuad(root_pass
, child_pass
, 0, filter
, transform_causing_aa
);
1221 AddRenderPassQuad(child_pass
, grand_child_pass
);
1223 renderer_
->DecideRenderPassAllocationsForFrame(
1224 *mock_client_
.render_passes_in_draw_order());
1225 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1226 TestRenderPassColorMatrixProgramAA();
1228 // RenderPassMaskProgramAA
1229 render_passes
->clear();
1231 grand_child_pass
= AddRenderPass(render_passes
,
1232 grand_child_pass_id
,
1234 transform_causing_aa
);
1235 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1237 child_pass
= AddRenderPass(render_passes
, child_pass_id
, child_rect
,
1238 transform_causing_aa
);
1239 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1241 root_pass
= AddRenderPass(render_passes
, root_pass_id
, viewport_rect
,
1243 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1245 AddRenderPassQuad(root_pass
, child_pass
, mask
, skia::RefPtr
<SkImageFilter
>(),
1246 transform_causing_aa
);
1247 AddRenderPassQuad(child_pass
, grand_child_pass
);
1249 renderer_
->DecideRenderPassAllocationsForFrame(
1250 *mock_client_
.render_passes_in_draw_order());
1251 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1252 TestRenderPassMaskProgramAA();
1254 // RenderPassMaskColorMatrixProgramAA
1255 render_passes
->clear();
1257 grand_child_pass
= AddRenderPass(render_passes
,
1258 grand_child_pass_id
,
1260 transform_causing_aa
);
1261 AddClippedQuad(grand_child_pass
, grand_child_rect
, SK_ColorYELLOW
);
1263 child_pass
= AddRenderPass(render_passes
, child_pass_id
, child_rect
,
1264 transform_causing_aa
);
1265 AddQuad(child_pass
, child_rect
, SK_ColorBLUE
);
1267 root_pass
= AddRenderPass(render_passes
, root_pass_id
, viewport_rect
,
1268 transform_causing_aa
);
1269 AddQuad(root_pass
, viewport_rect
, SK_ColorGREEN
);
1271 AddRenderPassQuad(root_pass
, child_pass
, mask
, filter
, transform_causing_aa
);
1272 AddRenderPassQuad(child_pass
, grand_child_pass
);
1274 renderer_
->DecideRenderPassAllocationsForFrame(
1275 *mock_client_
.render_passes_in_draw_order());
1276 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1277 TestRenderPassMaskColorMatrixProgramAA();
1280 TEST_F(GLRendererShaderTest
, DrawSolidColorShader
) {
1281 gfx::Rect
viewport_rect(mock_client_
.DeviceViewportSize());
1282 ScopedPtrVector
<RenderPass
>* render_passes
=
1283 mock_client_
.render_passes_in_draw_order();
1285 RenderPass::Id
root_pass_id(1, 0);
1286 TestRenderPass
* root_pass
;
1288 gfx::Transform pixel_aligned_transform_causing_aa
;
1289 pixel_aligned_transform_causing_aa
.Translate(25.5f
, 25.5f
);
1290 pixel_aligned_transform_causing_aa
.Scale(0.5f
, 0.5f
);
1292 render_passes
->clear();
1294 root_pass
= AddRenderPass(
1295 render_passes
, root_pass_id
, viewport_rect
, gfx::Transform());
1296 AddTransformedQuad(root_pass
,
1299 pixel_aligned_transform_causing_aa
);
1301 renderer_
->DecideRenderPassAllocationsForFrame(
1302 *mock_client_
.render_passes_in_draw_order());
1303 renderer_
->DrawFrame(mock_client_
.render_passes_in_draw_order());
1305 TestSolidColorProgramAA();
1308 class OutputSurfaceMockContext
: public TestWebGraphicsContext3D
{
1310 // Specifically override methods even if they are unused (used in conjunction
1311 // with StrictMock). We need to make sure that GLRenderer does not issue
1312 // framebuffer-related GL calls directly. Instead these are supposed to go
1313 // through the OutputSurface abstraction.
1314 MOCK_METHOD0(ensureBackbufferCHROMIUM
, void());
1315 MOCK_METHOD0(discardBackbufferCHROMIUM
, void());
1316 MOCK_METHOD2(bindFramebuffer
, void(WGC3Denum target
, WebGLId framebuffer
));
1317 MOCK_METHOD0(prepareTexture
, void());
1318 MOCK_METHOD2(reshape
, void(int width
, int height
));
1319 MOCK_METHOD4(drawElements
,
1320 void(WGC3Denum mode
,
1323 WGC3Dintptr offset
));
1325 virtual WebString
getString(WebKit::WGC3Denum name
) {
1326 if (name
== GL_EXTENSIONS
)
1328 "GL_CHROMIUM_post_sub_buffer GL_CHROMIUM_discard_backbuffer");
1333 class MockOutputSurface
: public OutputSurface
{
1336 : OutputSurface(scoped_ptr
<WebKit::WebGraphicsContext3D
>(
1337 new StrictMock
<OutputSurfaceMockContext
>)) {}
1338 virtual ~MockOutputSurface() {}
1340 MOCK_METHOD1(SendFrameToParentCompositor
, void(CompositorFrame
* frame
));
1341 MOCK_METHOD0(EnsureBackbuffer
, void());
1342 MOCK_METHOD0(DiscardBackbuffer
, void());
1343 MOCK_METHOD1(Reshape
, void(gfx::Size size
));
1344 MOCK_METHOD0(BindFramebuffer
, void());
1345 MOCK_METHOD2(PostSubBuffer
, void(gfx::Rect rect
, const LatencyInfo
&));
1346 MOCK_METHOD1(SwapBuffers
, void(const LatencyInfo
&));
1349 class MockOutputSurfaceTest
: public testing::Test
, public FakeRendererClient
{
1351 MockOutputSurfaceTest()
1352 : resource_provider_(ResourceProvider::Create(&output_surface_
, 0)),
1353 renderer_(this, &output_surface_
, resource_provider_
.get()) {}
1355 virtual void SetUp() { EXPECT_TRUE(renderer_
.Initialize()); }
1357 void SwapBuffers() { renderer_
.SwapBuffers(LatencyInfo()); }
1360 gfx::Rect
viewport_rect(DeviceViewportSize());
1361 ScopedPtrVector
<RenderPass
>* render_passes
= render_passes_in_draw_order();
1362 render_passes
->clear();
1364 RenderPass::Id
render_pass_id(1, 0);
1365 TestRenderPass
* render_pass
= AddRenderPass(
1366 render_passes
, render_pass_id
, viewport_rect
, gfx::Transform());
1367 AddQuad(render_pass
, viewport_rect
, SK_ColorGREEN
);
1369 EXPECT_CALL(output_surface_
, EnsureBackbuffer()).WillRepeatedly(Return());
1371 EXPECT_CALL(output_surface_
, Reshape(_
)).Times(1);
1373 EXPECT_CALL(output_surface_
, BindFramebuffer()).Times(1);
1375 EXPECT_CALL(*Context(), drawElements(_
, _
, _
, _
)).Times(1);
1377 renderer_
.DecideRenderPassAllocationsForFrame(
1378 *render_passes_in_draw_order());
1379 renderer_
.DrawFrame(render_passes_in_draw_order());
1382 OutputSurfaceMockContext
* Context() {
1383 return static_cast<OutputSurfaceMockContext
*>(output_surface_
.context3d());
1386 StrictMock
<MockOutputSurface
> output_surface_
;
1387 scoped_ptr
<ResourceProvider
> resource_provider_
;
1388 FakeRendererGL renderer_
;
1391 TEST_F(MockOutputSurfaceTest
, DrawFrameAndSwap
) {
1394 EXPECT_CALL(output_surface_
, SwapBuffers(_
)).Times(1);
1395 renderer_
.SwapBuffers(LatencyInfo());
1398 class MockOutputSurfaceTestWithPartialSwap
: public MockOutputSurfaceTest
{
1400 virtual const LayerTreeSettings
& Settings() const OVERRIDE
{
1401 static LayerTreeSettings fake_settings
;
1402 fake_settings
.partial_swap_enabled
= true;
1403 return fake_settings
;
1407 TEST_F(MockOutputSurfaceTestWithPartialSwap
, DrawFrameAndSwap
) {
1410 EXPECT_CALL(output_surface_
, PostSubBuffer(_
, _
)).Times(1);
1411 renderer_
.SwapBuffers(LatencyInfo());
1414 class MockOutputSurfaceTestWithSendCompositorFrame
1415 : public MockOutputSurfaceTest
{
1417 virtual const LayerTreeSettings
& Settings() const OVERRIDE
{
1418 static LayerTreeSettings fake_settings
;
1419 fake_settings
.compositor_frame_message
= true;
1420 return fake_settings
;
1424 TEST_F(MockOutputSurfaceTestWithSendCompositorFrame
, DrawFrame
) {
1425 EXPECT_CALL(output_surface_
, SendFrameToParentCompositor(_
)).Times(1);