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/gl_renderer.h"
7 #include "cc/draw_quad.h"
8 #include "cc/prioritized_resource_manager.h"
9 #include "cc/resource_provider.h"
10 #include "cc/test/fake_web_compositor_output_surface.h"
11 #include "cc/test/fake_web_graphics_context_3d.h"
12 #include "cc/test/render_pass_test_common.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/khronos/GLES2/gl2.h"
16 #include "ui/gfx/transform.h"
18 using namespace WebKit
;
19 using namespace WebKitTests
;
22 using testing::AnyNumber
;
23 using testing::InSequence
;
29 class FrameCountingMemoryAllocationSettingContext
: public FakeWebGraphicsContext3D
{
31 FrameCountingMemoryAllocationSettingContext() : m_frame(0) { }
33 // WebGraphicsContext3D methods.
35 // This method would normally do a glSwapBuffers under the hood.
36 virtual void prepareTexture() { m_frame
++; }
37 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
* callback
) { m_memoryAllocationChangedCallback
= callback
; }
38 virtual WebString
getString(WebKit::WGC3Denum name
)
40 if (name
== GL_EXTENSIONS
)
41 return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager GL_CHROMIUM_discard_framebuffer");
45 // Methods added for test.
46 int frameCount() { return m_frame
; }
47 void setMemoryAllocation(WebGraphicsMemoryAllocation allocation
)
49 m_memoryAllocationChangedCallback
->onMemoryAllocationChanged(allocation
);
54 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
* m_memoryAllocationChangedCallback
;
57 class FakeRendererClient
: public RendererClient
{
60 : m_setFullRootLayerDamageCount(0)
61 , m_lastCallWasSetVisibility(0)
62 , m_rootLayer(LayerImpl::create(1))
63 , m_memoryAllocationLimitBytes(PrioritizedResourceManager::defaultMemoryAllocationLimit())
65 m_rootLayer
->createRenderSurface();
66 RenderPass::Id renderPassId
= m_rootLayer
->renderSurface()->renderPassId();
67 scoped_ptr
<RenderPass
> rootRenderPass
= RenderPass::Create();
68 rootRenderPass
->SetNew(renderPassId
, gfx::Rect(), gfx::Rect(), gfx::Transform());
69 m_renderPassesInDrawOrder
.push_back(rootRenderPass
.get());
70 m_renderPasses
.set(renderPassId
, rootRenderPass
.Pass());
73 // RendererClient methods.
74 virtual const gfx::Size
& deviceViewportSize() const OVERRIDE
{ static gfx::Size
fakeSize(1, 1); return fakeSize
; }
75 virtual const LayerTreeSettings
& settings() const OVERRIDE
{ static LayerTreeSettings fakeSettings
; return fakeSettings
; }
76 virtual void didLoseContext() OVERRIDE
{ }
77 virtual void onSwapBuffersComplete() OVERRIDE
{ }
78 virtual void setFullRootLayerDamage() OVERRIDE
{ m_setFullRootLayerDamageCount
++; }
79 virtual void setManagedMemoryPolicy(const ManagedMemoryPolicy
& policy
) OVERRIDE
{ m_memoryAllocationLimitBytes
= policy
.bytesLimitWhenVisible
; }
80 virtual void enforceManagedMemoryPolicy(const ManagedMemoryPolicy
& policy
) OVERRIDE
{ if (m_lastCallWasSetVisibility
) *m_lastCallWasSetVisibility
= false; }
81 virtual bool hasImplThread() const OVERRIDE
{ return false; }
83 // Methods added for test.
84 int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCount
; }
85 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility
) { m_lastCallWasSetVisibility
= lastCallWasSetVisibility
; }
87 RenderPass
* rootRenderPass() { return m_renderPassesInDrawOrder
.back(); }
88 RenderPassList
& renderPassesInDrawOrder() { return m_renderPassesInDrawOrder
; }
89 RenderPassIdHashMap
& renderPasses() { return m_renderPasses
; }
91 size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBytes
; }
94 int m_setFullRootLayerDamageCount
;
95 bool* m_lastCallWasSetVisibility
;
96 scoped_ptr
<LayerImpl
> m_rootLayer
;
97 RenderPassList m_renderPassesInDrawOrder
;
98 RenderPassIdHashMap m_renderPasses
;
99 size_t m_memoryAllocationLimitBytes
;
102 class FakeRendererGL
: public GLRenderer
{
104 FakeRendererGL(RendererClient
* client
, ResourceProvider
* resourceProvider
) : GLRenderer(client
, resourceProvider
) { }
106 // GLRenderer methods.
108 // Changing visibility to public.
109 using GLRenderer::initialize
;
110 using GLRenderer::isFramebufferDiscarded
;
111 using GLRenderer::drawQuad
;
112 using GLRenderer::beginDrawingFrame
;
113 using GLRenderer::finishDrawingQuadList
;
116 class GLRendererTest
: public testing::Test
{
119 : m_suggestHaveBackbufferYes(1, true)
120 , m_suggestHaveBackbufferNo(1, false)
121 , m_context(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new FrameCountingMemoryAllocationSettingContext())))
122 , m_resourceProvider(ResourceProvider::create(m_context
.get()))
123 , m_renderer(&m_mockClient
, m_resourceProvider
.get())
129 m_renderer
.initialize();
134 m_renderer
.swapBuffers();
137 FrameCountingMemoryAllocationSettingContext
* context() { return static_cast<FrameCountingMemoryAllocationSettingContext
*>(m_context
->context3D()); }
139 WebGraphicsMemoryAllocation m_suggestHaveBackbufferYes
;
140 WebGraphicsMemoryAllocation m_suggestHaveBackbufferNo
;
142 scoped_ptr
<GraphicsContext
> m_context
;
143 FakeRendererClient m_mockClient
;
144 scoped_ptr
<ResourceProvider
> m_resourceProvider
;
145 FakeRendererGL m_renderer
;
148 // Test GLRenderer discardFramebuffer functionality:
149 // Suggest recreating framebuffer when one already exists.
150 // Expected: it does nothing.
151 TEST_F(GLRendererTest
, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing
)
153 context()->setMemoryAllocation(m_suggestHaveBackbufferYes
);
154 EXPECT_EQ(0, m_mockClient
.setFullRootLayerDamageCount());
155 EXPECT_FALSE(m_renderer
.isFramebufferDiscarded());
158 EXPECT_EQ(1, context()->frameCount());
161 // Test GLRenderer discardFramebuffer functionality:
162 // Suggest discarding framebuffer when one exists and the renderer is not visible.
163 // Expected: it is discarded and damage tracker is reset.
164 TEST_F(GLRendererTest
, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerWhileNotVisible
)
166 m_renderer
.setVisible(false);
167 context()->setMemoryAllocation(m_suggestHaveBackbufferNo
);
168 EXPECT_EQ(1, m_mockClient
.setFullRootLayerDamageCount());
169 EXPECT_TRUE(m_renderer
.isFramebufferDiscarded());
172 // Test GLRenderer discardFramebuffer functionality:
173 // Suggest discarding framebuffer when one exists and the renderer is visible.
174 // Expected: the allocation is ignored.
175 TEST_F(GLRendererTest
, SuggestBackbufferNoDoNothingWhenVisible
)
177 m_renderer
.setVisible(true);
178 context()->setMemoryAllocation(m_suggestHaveBackbufferNo
);
179 EXPECT_EQ(0, m_mockClient
.setFullRootLayerDamageCount());
180 EXPECT_FALSE(m_renderer
.isFramebufferDiscarded());
184 // Test GLRenderer discardFramebuffer functionality:
185 // Suggest discarding framebuffer when one does not exist.
186 // Expected: it does nothing.
187 TEST_F(GLRendererTest
, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing
)
189 m_renderer
.setVisible(false);
190 context()->setMemoryAllocation(m_suggestHaveBackbufferNo
);
191 EXPECT_EQ(1, m_mockClient
.setFullRootLayerDamageCount());
192 EXPECT_TRUE(m_renderer
.isFramebufferDiscarded());
194 context()->setMemoryAllocation(m_suggestHaveBackbufferNo
);
195 EXPECT_EQ(1, m_mockClient
.setFullRootLayerDamageCount());
196 EXPECT_TRUE(m_renderer
.isFramebufferDiscarded());
199 // Test GLRenderer discardFramebuffer functionality:
200 // Begin drawing a frame while a framebuffer is discarded.
201 // Expected: will recreate framebuffer.
202 TEST_F(GLRendererTest
, DiscardedBackbufferIsRecreatedForScopeDuration
)
204 m_renderer
.setVisible(false);
205 context()->setMemoryAllocation(m_suggestHaveBackbufferNo
);
206 EXPECT_TRUE(m_renderer
.isFramebufferDiscarded());
207 EXPECT_EQ(1, m_mockClient
.setFullRootLayerDamageCount());
209 m_renderer
.setVisible(true);
210 m_renderer
.drawFrame(m_mockClient
.renderPassesInDrawOrder(), m_mockClient
.renderPasses());
211 EXPECT_FALSE(m_renderer
.isFramebufferDiscarded());
214 EXPECT_EQ(1, context()->frameCount());
217 TEST_F(GLRendererTest
, FramebufferDiscardedAfterReadbackWhenNotVisible
)
219 m_renderer
.setVisible(false);
220 context()->setMemoryAllocation(m_suggestHaveBackbufferNo
);
221 EXPECT_TRUE(m_renderer
.isFramebufferDiscarded());
222 EXPECT_EQ(1, m_mockClient
.setFullRootLayerDamageCount());
225 m_renderer
.drawFrame(m_mockClient
.renderPassesInDrawOrder(), m_mockClient
.renderPasses());
226 EXPECT_FALSE(m_renderer
.isFramebufferDiscarded());
228 m_renderer
.getFramebufferPixels(pixels
, gfx::Rect(0, 0, 1, 1));
229 EXPECT_TRUE(m_renderer
.isFramebufferDiscarded());
230 EXPECT_EQ(2, m_mockClient
.setFullRootLayerDamageCount());
233 class ForbidSynchronousCallContext
: public FakeWebGraphicsContext3D
{
235 ForbidSynchronousCallContext() { }
237 virtual bool getActiveAttrib(WebGLId program
, WGC3Duint index
, ActiveInfo
&) { ADD_FAILURE(); return false; }
238 virtual bool getActiveUniform(WebGLId program
, WGC3Duint index
, ActiveInfo
&) { ADD_FAILURE(); return false; }
239 virtual void getAttachedShaders(WebGLId program
, WGC3Dsizei maxCount
, WGC3Dsizei
* count
, WebGLId
* shaders
) { ADD_FAILURE(); }
240 virtual WGC3Dint
getAttribLocation(WebGLId program
, const WGC3Dchar
* name
) { ADD_FAILURE(); return 0; }
241 virtual void getBooleanv(WGC3Denum pname
, WGC3Dboolean
* value
) { ADD_FAILURE(); }
242 virtual void getBufferParameteriv(WGC3Denum target
, WGC3Denum pname
, WGC3Dint
* value
) { ADD_FAILURE(); }
243 virtual Attributes
getContextAttributes() { ADD_FAILURE(); return m_attrs
; }
244 virtual WGC3Denum
getError() { ADD_FAILURE(); return 0; }
245 virtual void getFloatv(WGC3Denum pname
, WGC3Dfloat
* value
) { ADD_FAILURE(); }
246 virtual void getFramebufferAttachmentParameteriv(WGC3Denum target
, WGC3Denum attachment
, WGC3Denum pname
, WGC3Dint
* value
) { ADD_FAILURE(); }
247 virtual void getIntegerv(WGC3Denum pname
, WGC3Dint
* value
)
249 if (pname
== GL_MAX_TEXTURE_SIZE
)
250 *value
= 1024; // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
255 // We allow querying the shader compilation and program link status in debug mode, but not release.
256 virtual void getProgramiv(WebGLId program
, WGC3Denum pname
, WGC3Dint
* value
)
265 virtual void getShaderiv(WebGLId shader
, WGC3Denum pname
, WGC3Dint
* value
)
274 virtual WebString
getString(WGC3Denum name
)
276 // We allow querying the extension string.
277 // FIXME: It'd be better to check that we only do this before starting any other expensive work (like starting a compilation)
278 if (name
!= GL_EXTENSIONS
)
283 virtual WebString
getProgramInfoLog(WebGLId program
) { ADD_FAILURE(); return WebString(); }
284 virtual void getRenderbufferParameteriv(WGC3Denum target
, WGC3Denum pname
, WGC3Dint
* value
) { ADD_FAILURE(); }
286 virtual WebString
getShaderInfoLog(WebGLId shader
) { ADD_FAILURE(); return WebString(); }
287 virtual void getShaderPrecisionFormat(WGC3Denum shadertype
, WGC3Denum precisiontype
, WGC3Dint
* range
, WGC3Dint
* precision
) { ADD_FAILURE(); }
288 virtual WebString
getShaderSource(WebGLId shader
) { ADD_FAILURE(); return WebString(); }
289 virtual void getTexParameterfv(WGC3Denum target
, WGC3Denum pname
, WGC3Dfloat
* value
) { ADD_FAILURE(); }
290 virtual void getTexParameteriv(WGC3Denum target
, WGC3Denum pname
, WGC3Dint
* value
) { ADD_FAILURE(); }
291 virtual void getUniformfv(WebGLId program
, WGC3Dint location
, WGC3Dfloat
* value
) { ADD_FAILURE(); }
292 virtual void getUniformiv(WebGLId program
, WGC3Dint location
, WGC3Dint
* value
) { ADD_FAILURE(); }
293 virtual WGC3Dint
getUniformLocation(WebGLId program
, const WGC3Dchar
* name
) { ADD_FAILURE(); return 0; }
294 virtual void getVertexAttribfv(WGC3Duint index
, WGC3Denum pname
, WGC3Dfloat
* value
) { ADD_FAILURE(); }
295 virtual void getVertexAttribiv(WGC3Duint index
, WGC3Denum pname
, WGC3Dint
* value
) { ADD_FAILURE(); }
296 virtual WGC3Dsizeiptr
getVertexAttribOffset(WGC3Duint index
, WGC3Denum pname
) { ADD_FAILURE(); return 0; }
299 // This test isn't using the same fixture as GLRendererTest, and you can't mix TEST() and TEST_F() with the same name, hence LRC2.
300 TEST(GLRendererTest2
, initializationDoesNotMakeSynchronousCalls
)
302 FakeRendererClient mockClient
;
303 scoped_ptr
<GraphicsContext
> context(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new ForbidSynchronousCallContext
)));
304 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(context
.get()));
305 FakeRendererGL
renderer(&mockClient
, resourceProvider
.get());
307 EXPECT_TRUE(renderer
.initialize());
310 class LoseContextOnFirstGetContext
: public FakeWebGraphicsContext3D
{
312 LoseContextOnFirstGetContext()
313 : m_contextLost(false)
317 virtual bool makeContextCurrent() OVERRIDE
319 return !m_contextLost
;
322 virtual void getProgramiv(WebGLId program
, WGC3Denum pname
, WGC3Dint
* value
) OVERRIDE
324 m_contextLost
= true;
328 virtual void getShaderiv(WebGLId shader
, WGC3Denum pname
, WGC3Dint
* value
) OVERRIDE
330 m_contextLost
= true;
334 virtual WGC3Denum
getGraphicsResetStatusARB() OVERRIDE
336 return m_contextLost
? 1 : 0;
343 TEST(GLRendererTest2
, initializationWithQuicklyLostContextDoesNotAssert
)
345 FakeRendererClient mockClient
;
346 scoped_ptr
<GraphicsContext
> context(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new LoseContextOnFirstGetContext
)));
347 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(context
.get()));
348 FakeRendererGL
renderer(&mockClient
, resourceProvider
.get());
350 renderer
.initialize();
353 class ContextThatDoesNotSupportMemoryManagmentExtensions
: public FakeWebGraphicsContext3D
{
355 ContextThatDoesNotSupportMemoryManagmentExtensions() { }
357 // WebGraphicsContext3D methods.
359 // This method would normally do a glSwapBuffers under the hood.
360 virtual void prepareTexture() { }
361 virtual void setMemoryAllocationChangedCallbackCHROMIUM(WebGraphicsMemoryAllocationChangedCallbackCHROMIUM
* callback
) { }
362 virtual WebString
getString(WebKit::WGC3Denum name
) { return WebString(); }
365 TEST(GLRendererTest2
, initializationWithoutGpuMemoryManagerExtensionSupportShouldDefaultToNonZeroAllocation
)
367 FakeRendererClient mockClient
;
368 scoped_ptr
<GraphicsContext
> context(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new ContextThatDoesNotSupportMemoryManagmentExtensions
)));
369 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(context
.get()));
370 FakeRendererGL
renderer(&mockClient
, resourceProvider
.get());
372 renderer
.initialize();
374 EXPECT_GT(mockClient
.memoryAllocationLimitBytes(), 0ul);
377 class ClearCountingContext
: public FakeWebGraphicsContext3D
{
379 ClearCountingContext() : m_clear(0) { }
381 virtual void clear(WGC3Dbitfield
)
386 int clearCount() const { return m_clear
; }
392 TEST(GLRendererTest2
, opaqueBackground
)
394 FakeRendererClient mockClient
;
395 scoped_ptr
<GraphicsContext
> outputSurface(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new ClearCountingContext
)));
396 ClearCountingContext
* context
= static_cast<ClearCountingContext
*>(outputSurface
->context3D());
397 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(outputSurface
.get()));
398 FakeRendererGL
renderer(&mockClient
, resourceProvider
.get());
400 mockClient
.rootRenderPass()->has_transparent_background
= false;
402 EXPECT_TRUE(renderer
.initialize());
404 renderer
.drawFrame(mockClient
.renderPassesInDrawOrder(), mockClient
.renderPasses());
406 // On DEBUG builds, render passes with opaque background clear to blue to
407 // easily see regions that were not drawn on the screen.
409 EXPECT_EQ(0, context
->clearCount());
411 EXPECT_EQ(1, context
->clearCount());
415 TEST(GLRendererTest2
, transparentBackground
)
417 FakeRendererClient mockClient
;
418 scoped_ptr
<GraphicsContext
> outputSurface(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new ClearCountingContext
)));
419 ClearCountingContext
* context
= static_cast<ClearCountingContext
*>(outputSurface
->context3D());
420 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(outputSurface
.get()));
421 FakeRendererGL
renderer(&mockClient
, resourceProvider
.get());
423 mockClient
.rootRenderPass()->has_transparent_background
= true;
425 EXPECT_TRUE(renderer
.initialize());
427 renderer
.drawFrame(mockClient
.renderPassesInDrawOrder(), mockClient
.renderPasses());
429 EXPECT_EQ(1, context
->clearCount());
432 class VisibilityChangeIsLastCallTrackingContext
: public FakeWebGraphicsContext3D
{
434 VisibilityChangeIsLastCallTrackingContext()
435 : m_lastCallWasSetVisibility(0)
439 // WebGraphicsContext3D methods.
440 virtual void setVisibilityCHROMIUM(bool visible
) {
441 if (!m_lastCallWasSetVisibility
)
443 DCHECK(*m_lastCallWasSetVisibility
== false);
444 *m_lastCallWasSetVisibility
= true;
446 virtual void flush() { if (m_lastCallWasSetVisibility
) *m_lastCallWasSetVisibility
= false; }
447 virtual void deleteTexture(WebGLId
) { if (m_lastCallWasSetVisibility
) *m_lastCallWasSetVisibility
= false; }
448 virtual void deleteFramebuffer(WebGLId
) { if (m_lastCallWasSetVisibility
) *m_lastCallWasSetVisibility
= false; }
449 virtual void deleteRenderbuffer(WebGLId
) { if (m_lastCallWasSetVisibility
) *m_lastCallWasSetVisibility
= false; }
451 // This method would normally do a glSwapBuffers under the hood.
452 virtual WebString
getString(WebKit::WGC3Denum name
)
454 if (name
== GL_EXTENSIONS
)
455 return WebString("GL_CHROMIUM_set_visibility GL_CHROMIUM_gpu_memory_manager GL_CHROMIUM_discard_framebuffer");
459 // Methods added for test.
460 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility
) { m_lastCallWasSetVisibility
= lastCallWasSetVisibility
; }
463 bool* m_lastCallWasSetVisibility
;
466 TEST(GLRendererTest2
, visibilityChangeIsLastCall
)
468 FakeRendererClient mockClient
;
469 scoped_ptr
<GraphicsContext
> outputSurface(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new VisibilityChangeIsLastCallTrackingContext
)));
470 VisibilityChangeIsLastCallTrackingContext
* context
= static_cast<VisibilityChangeIsLastCallTrackingContext
*>(outputSurface
->context3D());
471 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(outputSurface
.get()));
472 FakeRendererGL
renderer(&mockClient
, resourceProvider
.get());
474 EXPECT_TRUE(renderer
.initialize());
476 bool lastCallWasSetVisiblity
= false;
477 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to the GPU
478 // process, after glFlush is called, and after the RendererClient's enforceManagedMemoryPolicy
479 // is called. Plumb this tracking between both the RenderClient and the Context by giving
480 // them both a pointer to a variable on the stack.
481 context
->setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity
);
482 mockClient
.setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity
);
483 renderer
.setVisible(true);
484 renderer
.drawFrame(mockClient
.renderPassesInDrawOrder(), mockClient
.renderPasses());
485 renderer
.setVisible(false);
486 EXPECT_TRUE(lastCallWasSetVisiblity
);
489 class TextureStateTrackingContext
: public FakeWebGraphicsContext3D
{
491 TextureStateTrackingContext()
492 : m_activeTexture(GL_INVALID_ENUM
)
496 virtual WebString
getString(WGC3Denum name
)
498 if (name
== GL_EXTENSIONS
)
499 return WebString("GL_OES_EGL_image_external");
503 MOCK_METHOD3(texParameteri
, void(WGC3Denum target
, WGC3Denum pname
, WGC3Dint param
));
504 MOCK_METHOD4(drawElements
, void(WGC3Denum mode
, WGC3Dsizei count
, WGC3Denum type
, WGC3Dintptr offset
));
506 virtual void activeTexture(WGC3Denum texture
)
508 EXPECT_NE(texture
, m_activeTexture
);
509 m_activeTexture
= texture
;
512 WGC3Denum
activeTexture() const { return m_activeTexture
; }
515 WGC3Denum m_activeTexture
;
518 TEST(GLRendererTest2
, activeTextureState
)
520 FakeRendererClient fakeClient
;
521 scoped_ptr
<GraphicsContext
> outputSurface(FakeWebCompositorOutputSurface::create(scoped_ptr
<WebKit::WebGraphicsContext3D
>(new TextureStateTrackingContext
)));
522 TextureStateTrackingContext
* context
= static_cast<TextureStateTrackingContext
*>(outputSurface
->context3D());
523 scoped_ptr
<ResourceProvider
> resourceProvider(ResourceProvider::create(outputSurface
.get()));
524 FakeRendererGL
renderer(&fakeClient
, resourceProvider
.get());
526 // During initialization we are allowed to set any texture parameters.
527 EXPECT_CALL(*context
, texParameteri(_
, _
, _
)).Times(AnyNumber());
528 EXPECT_TRUE(renderer
.initialize());
530 cc::RenderPass::Id
id(1, 1);
531 scoped_ptr
<TestRenderPass
> pass
= TestRenderPass::Create();
532 pass
->SetNew(id
, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100), gfx::Transform());
533 pass
->AppendOneOfEveryQuadType(resourceProvider
.get());
535 // Set up expected texture filter state transitions that match the quads
536 // created in AppendOneOfEveryQuadType().
537 Mock::VerifyAndClearExpectations(context
);
541 // yuv_quad is drawn with the default filter.
542 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
544 // tile_quad is drawn with GL_NEAREST because it is not transformed or
546 EXPECT_CALL(*context
, texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
));
547 EXPECT_CALL(*context
, texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
));
548 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
550 // transformed_tile_quad uses GL_LINEAR.
551 EXPECT_CALL(*context
, texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
));
552 EXPECT_CALL(*context
, texParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
));
553 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
555 // scaled_tile_quad also uses GL_LINEAR.
556 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
));
558 // The remaining quads also use GL_LINEAR because nearest neighbor
559 // filtering is currently only used with tile quads.
560 EXPECT_CALL(*context
, drawElements(_
, _
, _
, _
)).Times(6);
563 cc::DirectRenderer::DrawingFrame drawingFrame
;
564 renderer
.beginDrawingFrame(drawingFrame
);
565 EXPECT_EQ(context
->activeTexture(), GL_TEXTURE0
);
567 for (cc::QuadList::backToFrontIterator it
= pass
->quad_list
.backToFrontBegin();
568 it
!= pass
->quad_list
.backToFrontEnd(); ++it
) {
569 renderer
.drawQuad(drawingFrame
, *it
);
571 renderer
.finishDrawingQuadList();
572 EXPECT_EQ(context
->activeTexture(), GL_TEXTURE0
);
573 Mock::VerifyAndClearExpectations(context
);