| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/gl_renderer.h" | 5 #include "cc/gl_renderer.h" |
| 6 | 6 |
| 7 #include "cc/compositor_frame_metadata.h" | 7 #include "cc/compositor_frame_metadata.h" |
| 8 #include "cc/draw_quad.h" | 8 #include "cc/draw_quad.h" |
| 9 #include "cc/prioritized_resource_manager.h" | 9 #include "cc/prioritized_resource_manager.h" |
| 10 #include "cc/resource_provider.h" | 10 #include "cc/resource_provider.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 , m_setFullRootLayerDamageCount(0) | 66 , m_setFullRootLayerDamageCount(0) |
| 67 , m_lastCallWasSetVisibility(0) | 67 , m_lastCallWasSetVisibility(0) |
| 68 , m_rootLayer(LayerImpl::create(m_hostImpl.activeTree(), 1)) | 68 , m_rootLayer(LayerImpl::create(m_hostImpl.activeTree(), 1)) |
| 69 , m_memoryAllocationLimitBytes(PrioritizedResourceManager::defaultMemory
AllocationLimit()) | 69 , m_memoryAllocationLimitBytes(PrioritizedResourceManager::defaultMemory
AllocationLimit()) |
| 70 { | 70 { |
| 71 m_rootLayer->createRenderSurface(); | 71 m_rootLayer->createRenderSurface(); |
| 72 RenderPass::Id renderPassId = m_rootLayer->renderSurface()->renderPassId
(); | 72 RenderPass::Id renderPassId = m_rootLayer->renderSurface()->renderPassId
(); |
| 73 scoped_ptr<RenderPass> rootRenderPass = RenderPass::Create(); | 73 scoped_ptr<RenderPass> rootRenderPass = RenderPass::Create(); |
| 74 rootRenderPass->SetNew(renderPassId, gfx::Rect(), gfx::Rect(), gfx::Tran
sform()); | 74 rootRenderPass->SetNew(renderPassId, gfx::Rect(), gfx::Rect(), gfx::Tran
sform()); |
| 75 m_renderPassesInDrawOrder.push_back(rootRenderPass.get()); | 75 m_renderPassesInDrawOrder.push_back(rootRenderPass.get()); |
| 76 m_renderPasses.set(renderPassId, rootRenderPass.Pass()); | |
| 77 } | 76 } |
| 78 | 77 |
| 79 // RendererClient methods. | 78 // RendererClient methods. |
| 80 virtual const gfx::Size& deviceViewportSize() const OVERRIDE { static gfx::S
ize fakeSize(1, 1); return fakeSize; } | 79 virtual const gfx::Size& deviceViewportSize() const OVERRIDE { static gfx::S
ize fakeSize(1, 1); return fakeSize; } |
| 81 virtual const LayerTreeSettings& settings() const OVERRIDE { static LayerTre
eSettings fakeSettings; return fakeSettings; } | 80 virtual const LayerTreeSettings& settings() const OVERRIDE { static LayerTre
eSettings fakeSettings; return fakeSettings; } |
| 82 virtual void didLoseOutputSurface() OVERRIDE { } | 81 virtual void didLoseOutputSurface() OVERRIDE { } |
| 83 virtual void onSwapBuffersComplete() OVERRIDE { } | 82 virtual void onSwapBuffersComplete() OVERRIDE { } |
| 84 virtual void setFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCou
nt++; } | 83 virtual void setFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCou
nt++; } |
| 85 virtual void setManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERR
IDE { m_memoryAllocationLimitBytes = policy.bytesLimitWhenVisible; } | 84 virtual void setManagedMemoryPolicy(const ManagedMemoryPolicy& policy) OVERR
IDE { m_memoryAllocationLimitBytes = policy.bytesLimitWhenVisible; } |
| 86 virtual void enforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) O
VERRIDE { if (m_lastCallWasSetVisibility) *m_lastCallWasSetVisibility = false; } | 85 virtual void enforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy) O
VERRIDE { if (m_lastCallWasSetVisibility) *m_lastCallWasSetVisibility = false; } |
| 87 virtual bool hasImplThread() const OVERRIDE { return false; } | 86 virtual bool hasImplThread() const OVERRIDE { return false; } |
| 88 virtual bool shouldClearRootRenderPass() const OVERRIDE { return true; } | 87 virtual bool shouldClearRootRenderPass() const OVERRIDE { return true; } |
| 89 virtual CompositorFrameMetadata makeCompositorFrameMetadata() const | 88 virtual CompositorFrameMetadata makeCompositorFrameMetadata() const |
| 90 OVERRIDE { return CompositorFrameMetadata(); } | 89 OVERRIDE { return CompositorFrameMetadata(); } |
| 91 | 90 |
| 92 // Methods added for test. | 91 // Methods added for test. |
| 93 int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCou
nt; } | 92 int setFullRootLayerDamageCount() const { return m_setFullRootLayerDamageCou
nt; } |
| 94 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility) { m_
lastCallWasSetVisibility = lastCallWasSetVisibility; } | 93 void setLastCallWasSetVisibilityPointer(bool* lastCallWasSetVisibility) { m_
lastCallWasSetVisibility = lastCallWasSetVisibility; } |
| 95 | 94 |
| 96 RenderPass* rootRenderPass() { return m_renderPassesInDrawOrder.back(); } | 95 RenderPass* rootRenderPass() { return m_renderPassesInDrawOrder.back(); } |
| 97 RenderPassList& renderPassesInDrawOrder() { return m_renderPassesInDrawOrder
; } | 96 RenderPassList& renderPassesInDrawOrder() { return m_renderPassesInDrawOrder
; } |
| 98 RenderPassIdHashMap& renderPasses() { return m_renderPasses; } | |
| 99 | 97 |
| 100 size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBy
tes; } | 98 size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBy
tes; } |
| 101 | 99 |
| 102 private: | 100 private: |
| 103 FakeImplProxy m_proxy; | 101 FakeImplProxy m_proxy; |
| 104 FakeLayerTreeHostImpl m_hostImpl; | 102 FakeLayerTreeHostImpl m_hostImpl; |
| 105 int m_setFullRootLayerDamageCount; | 103 int m_setFullRootLayerDamageCount; |
| 106 bool* m_lastCallWasSetVisibility; | 104 bool* m_lastCallWasSetVisibility; |
| 107 scoped_ptr<LayerImpl> m_rootLayer; | 105 scoped_ptr<LayerImpl> m_rootLayer; |
| 108 RenderPassList m_renderPassesInDrawOrder; | 106 RenderPassList m_renderPassesInDrawOrder; |
| 109 RenderPassIdHashMap m_renderPasses; | |
| 110 size_t m_memoryAllocationLimitBytes; | 107 size_t m_memoryAllocationLimitBytes; |
| 111 }; | 108 }; |
| 112 | 109 |
| 113 class FakeRendererGL : public GLRenderer { | 110 class FakeRendererGL : public GLRenderer { |
| 114 public: | 111 public: |
| 115 FakeRendererGL(RendererClient* client, OutputSurface* outputSurface, Resourc
eProvider* resourceProvider) : GLRenderer(client, outputSurface, resourceProvide
r) { } | 112 FakeRendererGL(RendererClient* client, OutputSurface* outputSurface, Resourc
eProvider* resourceProvider) : GLRenderer(client, outputSurface, resourceProvide
r) { } |
| 116 | 113 |
| 117 // GLRenderer methods. | 114 // GLRenderer methods. |
| 118 | 115 |
| 119 // Changing visibility to public. | 116 // Changing visibility to public. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 // Begin drawing a frame while a framebuffer is discarded. | 208 // Begin drawing a frame while a framebuffer is discarded. |
| 212 // Expected: will recreate framebuffer. | 209 // Expected: will recreate framebuffer. |
| 213 TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) | 210 TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) |
| 214 { | 211 { |
| 215 m_renderer.setVisible(false); | 212 m_renderer.setVisible(false); |
| 216 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 213 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); |
| 217 EXPECT_TRUE(m_renderer.isBackbufferDiscarded()); | 214 EXPECT_TRUE(m_renderer.isBackbufferDiscarded()); |
| 218 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 215 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); |
| 219 | 216 |
| 220 m_renderer.setVisible(true); | 217 m_renderer.setVisible(true); |
| 221 m_renderer.drawFrame(m_mockClient.renderPassesInDrawOrder(), m_mockClient.re
nderPasses()); | 218 m_renderer.drawFrame(m_mockClient.renderPassesInDrawOrder()); |
| 222 EXPECT_FALSE(m_renderer.isBackbufferDiscarded()); | 219 EXPECT_FALSE(m_renderer.isBackbufferDiscarded()); |
| 223 | 220 |
| 224 swapBuffers(); | 221 swapBuffers(); |
| 225 EXPECT_EQ(1, context()->frameCount()); | 222 EXPECT_EQ(1, context()->frameCount()); |
| 226 } | 223 } |
| 227 | 224 |
| 228 TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) | 225 TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) |
| 229 { | 226 { |
| 230 m_renderer.setVisible(false); | 227 m_renderer.setVisible(false); |
| 231 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); | 228 context()->setMemoryAllocation(m_suggestHaveBackbufferNo); |
| 232 EXPECT_TRUE(m_renderer.isBackbufferDiscarded()); | 229 EXPECT_TRUE(m_renderer.isBackbufferDiscarded()); |
| 233 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); | 230 EXPECT_EQ(1, m_mockClient.setFullRootLayerDamageCount()); |
| 234 | 231 |
| 235 char pixels[4]; | 232 char pixels[4]; |
| 236 m_renderer.drawFrame(m_mockClient.renderPassesInDrawOrder(), m_mockClient.re
nderPasses()); | 233 m_renderer.drawFrame(m_mockClient.renderPassesInDrawOrder()); |
| 237 EXPECT_FALSE(m_renderer.isBackbufferDiscarded()); | 234 EXPECT_FALSE(m_renderer.isBackbufferDiscarded()); |
| 238 | 235 |
| 239 m_renderer.getFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1)); | 236 m_renderer.getFramebufferPixels(pixels, gfx::Rect(0, 0, 1, 1)); |
| 240 EXPECT_TRUE(m_renderer.isBackbufferDiscarded()); | 237 EXPECT_TRUE(m_renderer.isBackbufferDiscarded()); |
| 241 EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount()); | 238 EXPECT_EQ(2, m_mockClient.setFullRootLayerDamageCount()); |
| 242 } | 239 } |
| 243 | 240 |
| 244 class ForbidSynchronousCallContext : public FakeWebGraphicsContext3D { | 241 class ForbidSynchronousCallContext : public FakeWebGraphicsContext3D { |
| 245 public: | 242 public: |
| 246 ForbidSynchronousCallContext() { } | 243 ForbidSynchronousCallContext() { } |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 FakeRendererClient mockClient; | 402 FakeRendererClient mockClient; |
| 406 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); | 403 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); |
| 407 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur
face->Context3D()); | 404 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur
face->Context3D()); |
| 408 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::create(outpu
tSurface.get())); | 405 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::create(outpu
tSurface.get())); |
| 409 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 406 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); |
| 410 | 407 |
| 411 mockClient.rootRenderPass()->has_transparent_background = false; | 408 mockClient.rootRenderPass()->has_transparent_background = false; |
| 412 | 409 |
| 413 EXPECT_TRUE(renderer.initialize()); | 410 EXPECT_TRUE(renderer.initialize()); |
| 414 | 411 |
| 415 renderer.drawFrame(mockClient.renderPassesInDrawOrder(), mockClient.renderPa
sses()); | 412 renderer.drawFrame(mockClient.renderPassesInDrawOrder()); |
| 416 | 413 |
| 417 // On DEBUG builds, render passes with opaque background clear to blue to | 414 // On DEBUG builds, render passes with opaque background clear to blue to |
| 418 // easily see regions that were not drawn on the screen. | 415 // easily see regions that were not drawn on the screen. |
| 419 #ifdef NDEBUG | 416 #ifdef NDEBUG |
| 420 EXPECT_EQ(0, context->clearCount()); | 417 EXPECT_EQ(0, context->clearCount()); |
| 421 #else | 418 #else |
| 422 EXPECT_EQ(1, context->clearCount()); | 419 EXPECT_EQ(1, context->clearCount()); |
| 423 #endif | 420 #endif |
| 424 } | 421 } |
| 425 | 422 |
| 426 TEST(GLRendererTest2, transparentBackground) | 423 TEST(GLRendererTest2, transparentBackground) |
| 427 { | 424 { |
| 428 FakeRendererClient mockClient; | 425 FakeRendererClient mockClient; |
| 429 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); | 426 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p
tr<WebKit::WebGraphicsContext3D>(new ClearCountingContext))); |
| 430 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur
face->Context3D()); | 427 ClearCountingContext* context = static_cast<ClearCountingContext*>(outputSur
face->Context3D()); |
| 431 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::create(outpu
tSurface.get())); | 428 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::create(outpu
tSurface.get())); |
| 432 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); | 429 FakeRendererGL renderer(&mockClient, outputSurface.get(), resourceProvider.g
et()); |
| 433 | 430 |
| 434 mockClient.rootRenderPass()->has_transparent_background = true; | 431 mockClient.rootRenderPass()->has_transparent_background = true; |
| 435 | 432 |
| 436 EXPECT_TRUE(renderer.initialize()); | 433 EXPECT_TRUE(renderer.initialize()); |
| 437 | 434 |
| 438 renderer.drawFrame(mockClient.renderPassesInDrawOrder(), mockClient.renderPa
sses()); | 435 renderer.drawFrame(mockClient.renderPassesInDrawOrder()); |
| 439 | 436 |
| 440 EXPECT_EQ(1, context->clearCount()); | 437 EXPECT_EQ(1, context->clearCount()); |
| 441 } | 438 } |
| 442 | 439 |
| 443 class VisibilityChangeIsLastCallTrackingContext : public FakeWebGraphicsContext3
D { | 440 class VisibilityChangeIsLastCallTrackingContext : public FakeWebGraphicsContext3
D { |
| 444 public: | 441 public: |
| 445 VisibilityChangeIsLastCallTrackingContext() | 442 VisibilityChangeIsLastCallTrackingContext() |
| 446 : m_lastCallWasSetVisibility(0) | 443 : m_lastCallWasSetVisibility(0) |
| 447 { | 444 { |
| 448 } | 445 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 EXPECT_TRUE(renderer.initialize()); | 482 EXPECT_TRUE(renderer.initialize()); |
| 486 | 483 |
| 487 bool lastCallWasSetVisiblity = false; | 484 bool lastCallWasSetVisiblity = false; |
| 488 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to t
he GPU | 485 // Ensure that the call to setVisibilityCHROMIUM is the last call issue to t
he GPU |
| 489 // process, after glFlush is called, and after the RendererClient's enforceM
anagedMemoryPolicy | 486 // process, after glFlush is called, and after the RendererClient's enforceM
anagedMemoryPolicy |
| 490 // is called. Plumb this tracking between both the RenderClient and the Cont
ext by giving | 487 // is called. Plumb this tracking between both the RenderClient and the Cont
ext by giving |
| 491 // them both a pointer to a variable on the stack. | 488 // them both a pointer to a variable on the stack. |
| 492 context->setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); | 489 context->setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); |
| 493 mockClient.setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); | 490 mockClient.setLastCallWasSetVisibilityPointer(&lastCallWasSetVisiblity); |
| 494 renderer.setVisible(true); | 491 renderer.setVisible(true); |
| 495 renderer.drawFrame(mockClient.renderPassesInDrawOrder(), mockClient.renderPa
sses()); | 492 renderer.drawFrame(mockClient.renderPassesInDrawOrder()); |
| 496 renderer.setVisible(false); | 493 renderer.setVisible(false); |
| 497 EXPECT_TRUE(lastCallWasSetVisiblity); | 494 EXPECT_TRUE(lastCallWasSetVisiblity); |
| 498 } | 495 } |
| 499 | 496 |
| 500 class TextureStateTrackingContext : public FakeWebGraphicsContext3D { | 497 class TextureStateTrackingContext : public FakeWebGraphicsContext3D { |
| 501 public: | 498 public: |
| 502 TextureStateTrackingContext() | 499 TextureStateTrackingContext() |
| 503 : m_activeTexture(GL_INVALID_ENUM) | 500 : m_activeTexture(GL_INVALID_ENUM) |
| 504 { | 501 { |
| 505 } | 502 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 | 610 |
| 614 RenderPass::Id childPassId(2, 0); | 611 RenderPass::Id childPassId(2, 0); |
| 615 TestRenderPass* childPass = addRenderPass(renderPasses, childPassId, viewpor
tRect, gfx::Transform()); | 612 TestRenderPass* childPass = addRenderPass(renderPasses, childPassId, viewpor
tRect, gfx::Transform()); |
| 616 addQuad(childPass, viewportRect, SK_ColorBLUE); | 613 addQuad(childPass, viewportRect, SK_ColorBLUE); |
| 617 | 614 |
| 618 addRenderPassQuad(rootPass, childPass); | 615 addRenderPassQuad(rootPass, childPass); |
| 619 | 616 |
| 620 mockClient.renderPassesInDrawOrder().clear(); | 617 mockClient.renderPassesInDrawOrder().clear(); |
| 621 mockClient.renderPassesInDrawOrder().push_back(childPass); | 618 mockClient.renderPassesInDrawOrder().push_back(childPass); |
| 622 mockClient.renderPassesInDrawOrder().push_back(rootPass); | 619 mockClient.renderPassesInDrawOrder().push_back(rootPass); |
| 623 mockClient.renderPasses().set(rootPassId, renderPasses.take(0)); | |
| 624 mockClient.renderPasses().set(childPassId, renderPasses.take(1)); | |
| 625 | 620 |
| 626 // First render pass is not the root one, clearing should happen. | 621 // First render pass is not the root one, clearing should happen. |
| 627 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) | 622 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) |
| 628 .Times(AtLeast(1)); | 623 .Times(AtLeast(1)); |
| 629 | 624 |
| 630 Expectation firstRenderPass = EXPECT_CALL(*mockContext, drawElements(_, _, _
, _)) | 625 Expectation firstRenderPass = EXPECT_CALL(*mockContext, drawElements(_, _, _
, _)) |
| 631 .Times(1); | 626 .Times(1); |
| 632 | 627 |
| 633 // The second render pass is the root one, clearing should be prevented. | 628 // The second render pass is the root one, clearing should be prevented. |
| 634 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) | 629 EXPECT_CALL(*mockContext, clear(GL_COLOR_BUFFER_BIT)) |
| 635 .Times(0) | 630 .Times(0) |
| 636 .After(firstRenderPass); | 631 .After(firstRenderPass); |
| 637 | 632 |
| 638 EXPECT_CALL(*mockContext, drawElements(_, _, _, _)) | 633 EXPECT_CALL(*mockContext, drawElements(_, _, _, _)) |
| 639 .Times(AnyNumber()) | 634 .Times(AnyNumber()) |
| 640 .After(firstRenderPass); | 635 .After(firstRenderPass); |
| 641 | 636 |
| 642 renderer.decideRenderPassAllocationsForFrame(mockClient.renderPassesInDrawOr
der()); | 637 renderer.decideRenderPassAllocationsForFrame(mockClient.renderPassesInDrawOr
der()); |
| 643 renderer.drawFrame(mockClient.renderPassesInDrawOrder(), mockClient.renderPa
sses()); | 638 renderer.drawFrame(mockClient.renderPassesInDrawOrder()); |
| 644 | 639 |
| 645 // In multiple render passes all but the root pass should clear the framebuf
fer. | 640 // In multiple render passes all but the root pass should clear the framebuf
fer. |
| 646 Mock::VerifyAndClearExpectations(&mockContext); | 641 Mock::VerifyAndClearExpectations(&mockContext); |
| 647 } | 642 } |
| 648 | 643 |
| 649 } // namespace | 644 } // namespace |
| 650 } // namespace cc | 645 } // namespace cc |
| OLD | NEW |