Depend on stored sync session GUID for Android.
[chromium-blink-merge.git] / cc / gl_renderer_unittest.cc
blob3dda6e65dca73f72816cbd6974523cfdee80def4
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;
21 using testing::_;
22 using testing::AnyNumber;
23 using testing::InSequence;
24 using testing::Mock;
26 namespace cc {
27 namespace {
29 class FrameCountingMemoryAllocationSettingContext : public FakeWebGraphicsContext3D {
30 public:
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");
42 return WebString();
45 // Methods added for test.
46 int frameCount() { return m_frame; }
47 void setMemoryAllocation(WebGraphicsMemoryAllocation allocation)
49 m_memoryAllocationChangedCallback->onMemoryAllocationChanged(allocation);
52 private:
53 int m_frame;
54 WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* m_memoryAllocationChangedCallback;
57 class FakeRendererClient : public RendererClient {
58 public:
59 FakeRendererClient()
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; }
93 private:
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 {
103 public:
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 {
117 protected:
118 GLRendererTest()
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())
127 virtual void SetUp()
129 m_renderer.initialize();
132 void swapBuffers()
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());
157 swapBuffers();
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());
213 swapBuffers();
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());
224 char pixels[4];
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 {
234 public:
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.
251 else
252 ADD_FAILURE();
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)
258 #ifndef NDEBUG
259 *value = 1;
260 #else
261 ADD_FAILURE();
262 #endif
265 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value)
267 #ifndef NDEBUG
268 *value = 1;
269 #else
270 ADD_FAILURE();
271 #endif
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)
279 ADD_FAILURE();
280 return WebString();
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 {
311 public:
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;
325 *value = 0;
328 virtual void getShaderiv(WebGLId shader, WGC3Denum pname, WGC3Dint* value) OVERRIDE
330 m_contextLost = true;
331 *value = 0;
334 virtual WGC3Denum getGraphicsResetStatusARB() OVERRIDE
336 return m_contextLost ? 1 : 0;
339 private:
340 bool m_contextLost;
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 {
354 public:
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 {
378 public:
379 ClearCountingContext() : m_clear(0) { }
381 virtual void clear(WGC3Dbitfield)
383 m_clear++;
386 int clearCount() const { return m_clear; }
388 private:
389 int 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.
408 #ifdef NDEBUG
409 EXPECT_EQ(0, context->clearCount());
410 #else
411 EXPECT_EQ(1, context->clearCount());
412 #endif
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 {
433 public:
434 VisibilityChangeIsLastCallTrackingContext()
435 : m_lastCallWasSetVisibility(0)
439 // WebGraphicsContext3D methods.
440 virtual void setVisibilityCHROMIUM(bool visible) {
441 if (!m_lastCallWasSetVisibility)
442 return;
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");
456 return WebString();
459 // Methods added for test.
460 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility) { m_lastCallWasSetVisibility = lastCallWasSetVisibility; }
462 private:
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 {
490 public:
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");
500 return WebString();
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; }
514 private:
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);
539 InSequence sequence;
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
545 // scaled.
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);
576 } // namespace
577 } // namespace cc