diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-29 13:11:04 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-29 13:11:04 +0000 |
commit | fd32d12c2b5df2ea7391003dca7307094535a297 (patch) | |
tree | da94ae6e14da3c03f679bb81a848fa653d6beca2 | |
parent | fecf9f77fccd08c22e9655843a534c79ed0ba567 (diff) | |
download | chromium_src-fd32d12c2b5df2ea7391003dca7307094535a297.zip chromium_src-fd32d12c2b5df2ea7391003dca7307094535a297.tar.gz chromium_src-fd32d12c2b5df2ea7391003dca7307094535a297.tar.bz2 |
cc: Pipe visibility and memory allocation to DelegatingRenderer
The GPU process makes memory allocation decisions based on the visibility of
surface. In the DelegatingRenderer case we don't use the surface directly, but
we still have it - just like composite-to-mailbox. So we can use
setVisibilityCHROMIUM to signal the GPU process, and listen to the memory
allocation callback.
This CL refactors a bunch of the logic that was hardcoded in GLRenderer into
OutputSurface which is shared. That also opens the door to implementing a memory
manager for the software renderer.
BUG=123444
Review URL: https://chromiumcodereview.appspot.com/18121005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209287 0039d316-1c4b-4281-b951-d872f2087c98
28 files changed, 343 insertions, 210 deletions
@@ -182,6 +182,8 @@ 'output/gl_renderer.h', 'output/gl_renderer_draw_cache.cc', 'output/gl_renderer_draw_cache.h', + 'output/managed_memory_policy.cc', + 'output/managed_memory_policy.h', 'output/output_surface.cc', 'output/output_surface.h', 'output/output_surface_client.h', @@ -248,8 +250,6 @@ 'resources/layer_tiling_data.h', 'resources/layer_updater.cc', 'resources/layer_updater.h', - 'resources/managed_memory_policy.cc', - 'resources/managed_memory_policy.h', 'resources/managed_tile_state.cc', 'resources/managed_tile_state.h', 'resources/memory_history.cc', diff --git a/cc/debug/fake_web_graphics_context_3d.h b/cc/debug/fake_web_graphics_context_3d.h index 83ebc8e..417a62c 100644 --- a/cc/debug/fake_web_graphics_context_3d.h +++ b/cc/debug/fake_web_graphics_context_3d.h @@ -73,7 +73,6 @@ class CC_EXPORT FakeWebGraphicsContext3D WebKit::WGC3Denum target, WebKit::WGC3Dsizei num_attachments, const WebKit::WGC3Denum* attachments) {} - virtual void ensureFramebufferCHROMIUM() {} virtual void setMemoryAllocationChangedCallbackCHROMIUM( WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {} diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc index 58af4e1..e701bf8 100644 --- a/cc/output/delegating_renderer.cc +++ b/cc/output/delegating_renderer.cc @@ -52,8 +52,6 @@ DelegatingRenderer::DelegatingRenderer( bool DelegatingRenderer::Initialize() { capabilities_.using_partial_swap = false; - // TODO(danakj): Throttling - we may want to only allow 1 outstanding frame, - // but the parent compositor may pipeline for us. capabilities_.max_texture_size = resource_provider_->max_texture_size(); capabilities_.best_texture_format = resource_provider_->best_texture_format(); capabilities_.allow_partial_texture_updates = false; @@ -105,12 +103,8 @@ bool DelegatingRenderer::Initialize() { if (has_io_surface) DCHECK(has_arb_texture_rect); - // TODO(piman): loop visibility to GPU process? capabilities_.using_set_visibility = has_set_visibility; - // TODO(danakj): Support GpuMemoryManager. - capabilities_.using_gpu_memory_manager = false; - capabilities_.using_egl_image = has_egl_image; capabilities_.using_map_image = has_map_image; @@ -175,7 +169,6 @@ void DelegatingRenderer::ReceiveSwapBuffersAck( resource_provider_->ReceiveFromParent(ack.resources); } - bool DelegatingRenderer::IsContextLost() { WebGraphicsContext3D* context3d = resource_provider_->GraphicsContext3D(); if (!context3d) @@ -184,7 +177,45 @@ bool DelegatingRenderer::IsContextLost() { } void DelegatingRenderer::SetVisible(bool visible) { + if (visible == visible_) + return; + visible_ = visible; + WebGraphicsContext3D* context = resource_provider_->GraphicsContext3D(); + if (!visible_) { + TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources"); + resource_provider_->ReleaseCachedData(); + if (context) + context->flush(); + } + if (capabilities_.using_set_visibility) { + // We loop visibility to the GPU process, since that's what manages memory. + // That will allow it to feed us with memory allocations that we can act + // upon. + DCHECK(context); + context->setVisibilityCHROMIUM(visible); + } +} + +void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible, + size_t bytes_visible_and_nearby, + size_t bytes_allocated) { + WebGraphicsContext3D* context = resource_provider_->GraphicsContext3D(); + if (!context) { + // TODO(piman): software path. + NOTIMPLEMENTED(); + return; + } + WebKit::WebGraphicsManagedMemoryStats stats; + stats.bytesVisible = bytes_visible; + stats.bytesVisibleAndNearby = bytes_visible_and_nearby; + stats.bytesAllocated = bytes_allocated; + stats.backbufferRequested = false; + context->sendManagedMemoryStatsCHROMIUM(&stats); +} + +void DelegatingRenderer::SetDiscardBackBufferWhenNotVisible(bool discard) { + // Nothing to do, we don't have a back buffer. } } // namespace cc diff --git a/cc/output/delegating_renderer.h b/cc/output/delegating_renderer.h index eb7e68f..7662e38 100644 --- a/cc/output/delegating_renderer.h +++ b/cc/output/delegating_renderer.h @@ -43,7 +43,9 @@ class CC_EXPORT DelegatingRenderer : public Renderer { virtual void SendManagedMemoryStats(size_t bytes_visible, size_t bytes_visible_and_nearby, - size_t bytes_allocated) OVERRIDE {} + size_t bytes_allocated) OVERRIDE; + + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE; private: DelegatingRenderer(RendererClient* client, diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 094ebd2..1528703 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -32,7 +32,6 @@ #include "cc/quads/stream_video_draw_quad.h" #include "cc/quads/texture_draw_quad.h" #include "cc/resources/layer_quad.h" -#include "cc/resources/priority_calculator.h" #include "cc/resources/scoped_resource.h" #include "cc/resources/sync_point_helper.h" #include "cc/trees/damage_tracker.h" @@ -182,12 +181,6 @@ bool GLRenderer::Initialize() { if (extensions.count("GL_CHROMIUM_iosurface") > 0) DCHECK_GT(extensions.count("GL_ARB_texture_rectangle"), 0u); - capabilities_.using_gpu_memory_manager = - extensions.count("GL_CHROMIUM_gpu_memory_manager") > 0 && - Settings().use_memory_management; - if (capabilities_.using_gpu_memory_manager) - context_->setMemoryAllocationChangedCallbackCHROMIUM(this); - capabilities_.using_egl_image = extensions.count("GL_OES_EGL_image_external") > 0; @@ -2052,44 +2045,11 @@ void GLRenderer::SwapBuffers() { resource_provider_->SetReadLockFence(new SimpleSwapFence()); } -void GLRenderer::onMemoryAllocationChanged( - WebGraphicsMemoryAllocation allocation) { - // Just ignore the memory manager when it says to set the limit to zero - // bytes. This will happen when the memory manager thinks that the renderer - // is not visible (which the renderer knows better). - if (allocation.bytesLimitWhenVisible) { - ManagedMemoryPolicy policy( - allocation.bytesLimitWhenVisible, - PriorityCutoff(allocation.priorityCutoffWhenVisible), - allocation.bytesLimitWhenNotVisible, - PriorityCutoff(allocation.priorityCutoffWhenNotVisible)); - - client_->SetManagedMemoryPolicy(policy); - } - - discard_backbuffer_when_not_visible_ = !allocation.suggestHaveBackbuffer; +void GLRenderer::SetDiscardBackBufferWhenNotVisible(bool discard) { + discard_backbuffer_when_not_visible_ = discard; EnforceMemoryPolicy(); } -ManagedMemoryPolicy::PriorityCutoff GLRenderer::PriorityCutoff( - WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff) { - // This is simple a 1:1 map, the names differ only because the WebKit names - // should be to match the cc names. - switch (priority_cutoff) { - case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowNothing: - return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; - case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleOnly: - return ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY; - case WebKit::WebGraphicsMemoryAllocation:: - PriorityCutoffAllowVisibleAndNearby: - return ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE; - case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything: - return ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING; - } - NOTREACHED(); - return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; -} - void GLRenderer::EnforceMemoryPolicy() { if (!visible_) { TRACE_EVENT0("cc", "GLRenderer::EnforceMemoryPolicy dropping resources"); diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index 15944d3..d0b509a 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -36,11 +36,7 @@ class GeometryBinding; class ScopedEnsureFramebufferAllocation; // Class that handles drawing of composited render layers using GL. -class CC_EXPORT GLRenderer - : public DirectRenderer, - public NON_EXPORTED_BASE( - WebKit::WebGraphicsContext3D:: - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM) { +class CC_EXPORT GLRenderer : public DirectRenderer { public: static scoped_ptr<GLRenderer> Create(RendererClient* client, OutputSurface* output_surface, @@ -72,6 +68,8 @@ class CC_EXPORT GLRenderer size_t bytes_visible_and_nearby, size_t bytes_allocated) OVERRIDE; + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE; + static void DebugGLCall(WebKit::WebGraphicsContext3D* context, const char* command, const char* file, @@ -125,8 +123,6 @@ class CC_EXPORT GLRenderer friend class GLRendererShaderTest; static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform); - static ManagedMemoryPolicy::PriorityCutoff PriorityCutoff( - WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff); void DrawCheckerboardQuad(const DrawingFrame* frame, const CheckerboardDrawQuad* quad); @@ -225,12 +221,6 @@ class CC_EXPORT GLRenderer void ReinitializeGrCanvas(); void ReinitializeGLState(); - // WebKit:: - // WebGraphicsContext3D::WebGraphicsMemoryAllocationChangedCallbackCHROMIUM - // implementation. - virtual void onMemoryAllocationChanged( - WebKit::WebGraphicsMemoryAllocation allocation) OVERRIDE; - virtual void DiscardBackbuffer() OVERRIDE; virtual void EnsureBackbuffer() OVERRIDE; void EnforceMemoryPolicy(); diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 34443e3..5687cb0 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -112,19 +112,14 @@ namespace { TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); } #endif -class FrameCountingMemoryAllocationSettingContext - : public TestWebGraphicsContext3D { +class FrameCountingContext : public TestWebGraphicsContext3D { public: - FrameCountingMemoryAllocationSettingContext() : frame_(0) {} + FrameCountingContext() : frame_(0) {} // WebGraphicsContext3D methods. // This method would normally do a glSwapBuffers under the hood. virtual void prepareTexture() { frame_++; } - virtual void setMemoryAllocationChangedCallbackCHROMIUM( - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) { - memory_allocation_changed_callback_ = callback; - } virtual WebString getString(WebKit::WGC3Denum name) { if (name == GL_EXTENSIONS) return WebString( @@ -135,14 +130,9 @@ class FrameCountingMemoryAllocationSettingContext // Methods added for test. int frame_count() { return frame_; } - void SetMemoryAllocation(WebGraphicsMemoryAllocation allocation) { - memory_allocation_changed_callback_->onMemoryAllocationChanged(allocation); - } private: int frame_; - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* - memory_allocation_changed_callback_; }; class FakeRendererClient : public RendererClient { @@ -150,10 +140,7 @@ class FakeRendererClient : public RendererClient { FakeRendererClient() : host_impl_(&proxy_), set_full_root_layer_damage_count_(0), - last_call_was_set_visibility_(0), root_layer_(LayerImpl::Create(host_impl_.active_tree(), 1)), - memory_allocation_limit_bytes_( - PrioritizedResourceManager::DefaultMemoryAllocationLimit()), viewport_size_(gfx::Size(1, 1)), scale_factor_(1.f) { root_layer_->CreateRenderSurface(); @@ -180,12 +167,6 @@ class FakeRendererClient : public RendererClient { virtual void SetFullRootLayerDamage() OVERRIDE { set_full_root_layer_damage_count_++; } - virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) - OVERRIDE { - memory_allocation_limit_bytes_ = policy.bytes_limit_when_visible; - if (last_call_was_set_visibility_) - *last_call_was_set_visibility_ = false; - } virtual bool HasImplThread() const OVERRIDE { return false; } virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; } virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE { @@ -199,10 +180,6 @@ class FakeRendererClient : public RendererClient { int set_full_root_layer_damage_count() const { return set_full_root_layer_damage_count_; } - void set_last_call_was_set_visibility_pointer( - bool* last_call_was_set_visibility) { - last_call_was_set_visibility_ = last_call_was_set_visibility; - } void set_viewport_and_scale( gfx::Size viewport_size, float scale_factor) { viewport_size_ = viewport_size; @@ -214,18 +191,12 @@ class FakeRendererClient : public RendererClient { return &render_passes_in_draw_order_; } - size_t memory_allocation_limit_bytes() const { - return memory_allocation_limit_bytes_; - } - private: FakeImplProxy proxy_; FakeLayerTreeHostImpl host_impl_; int set_full_root_layer_damage_count_; - bool* last_call_was_set_visibility_; scoped_ptr<LayerImpl> root_layer_; RenderPassList render_passes_in_draw_order_; - size_t memory_allocation_limit_bytes_; gfx::Size viewport_size_; float scale_factor_; }; @@ -250,11 +221,9 @@ class FakeRendererGL : public GLRenderer { class GLRendererTest : public testing::Test { protected: GLRendererTest() - : suggest_have_backbuffer_yes_(1, true), - suggest_have_backbuffer_no_(1, false), - output_surface_(FakeOutputSurface::Create3d( + : output_surface_(FakeOutputSurface::Create3d( scoped_ptr<WebKit::WebGraphicsContext3D>( - new FrameCountingMemoryAllocationSettingContext()))), + new FrameCountingContext()))), resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)), renderer_(&mock_client_, output_surface_.get(), @@ -264,14 +233,10 @@ class GLRendererTest : public testing::Test { void SwapBuffers() { renderer_.SwapBuffers(); } - FrameCountingMemoryAllocationSettingContext* Context() { - return static_cast<FrameCountingMemoryAllocationSettingContext*>( - output_surface_->context3d()); + FrameCountingContext* Context() { + return static_cast<FrameCountingContext*>(output_surface_->context3d()); } - WebGraphicsMemoryAllocation suggest_have_backbuffer_yes_; - WebGraphicsMemoryAllocation suggest_have_backbuffer_no_; - scoped_ptr<OutputSurface> output_surface_; FakeRendererClient mock_client_; scoped_ptr<ResourceProvider> resource_provider_; @@ -421,7 +386,7 @@ namespace { // Suggest recreating framebuffer when one already exists. // Expected: it does nothing. TEST_F(GLRendererTest, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing) { - Context()->SetMemoryAllocation(suggest_have_backbuffer_yes_); + renderer_.SetDiscardBackBufferWhenNotVisible(false); EXPECT_EQ(0, mock_client_.set_full_root_layer_damage_count()); EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); @@ -437,7 +402,7 @@ TEST_F( GLRendererTest, SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) { renderer_.SetVisible(false); - Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); + renderer_.SetDiscardBackBufferWhenNotVisible(true); EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); } @@ -447,7 +412,7 @@ TEST_F( // Expected: the allocation is ignored. TEST_F(GLRendererTest, SuggestBackbufferNoDoNothingWhenVisible) { renderer_.SetVisible(true); - Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); + renderer_.SetDiscardBackBufferWhenNotVisible(true); EXPECT_EQ(0, mock_client_.set_full_root_layer_damage_count()); EXPECT_FALSE(renderer_.IsBackbufferDiscarded()); } @@ -457,11 +422,11 @@ TEST_F(GLRendererTest, SuggestBackbufferNoDoNothingWhenVisible) { // Expected: it does nothing. TEST_F(GLRendererTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) { renderer_.SetVisible(false); - Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); + renderer_.SetDiscardBackBufferWhenNotVisible(true); EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); - Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); + renderer_.SetDiscardBackBufferWhenNotVisible(true); EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); } @@ -471,7 +436,7 @@ TEST_F(GLRendererTest, SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) { // Expected: will recreate framebuffer. TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) { renderer_.SetVisible(false); - Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); + renderer_.SetDiscardBackBufferWhenNotVisible(true); EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); @@ -485,7 +450,7 @@ TEST_F(GLRendererTest, DiscardedBackbufferIsRecreatedForScopeDuration) { TEST_F(GLRendererTest, FramebufferDiscardedAfterReadbackWhenNotVisible) { renderer_.SetVisible(false); - Context()->SetMemoryAllocation(suggest_have_backbuffer_no_); + renderer_.SetDiscardBackBufferWhenNotVisible(true); EXPECT_TRUE(renderer_.IsBackbufferDiscarded()); EXPECT_EQ(1, mock_client_.set_full_root_layer_damage_count()); @@ -702,37 +667,6 @@ TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) { renderer.Initialize(); } -class ContextThatDoesNotSupportMemoryManagmentExtensions - : public TestWebGraphicsContext3D { - public: - ContextThatDoesNotSupportMemoryManagmentExtensions() {} - - // WebGraphicsContext3D methods. - - // This method would normally do a glSwapBuffers under the hood. - virtual void prepareTexture() {} - virtual void setMemoryAllocationChangedCallbackCHROMIUM( - WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) {} - virtual WebString getString(WebKit::WGC3Denum name) { return WebString(); } -}; - -TEST( - GLRendererTest2, - InitWithoutGpuMemManagerExtensionSupportShouldDefaultToNonZeroAllocation) { - FakeRendererClient mock_client; - scoped_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>( - new ContextThatDoesNotSupportMemoryManagmentExtensions))); - scoped_ptr<ResourceProvider> resource_provider( - ResourceProvider::Create(output_surface.get(), 0)); - FakeRendererGL renderer( - &mock_client, output_surface.get(), resource_provider.get()); - - renderer.Initialize(); - - EXPECT_GT(mock_client.memory_allocation_limit_bytes(), 0ul); -} - class ClearCountingContext : public TestWebGraphicsContext3D { public: ClearCountingContext() : clear_(0) {} @@ -795,30 +729,33 @@ class VisibilityChangeIsLastCallTrackingContext : public TestWebGraphicsContext3D { public: VisibilityChangeIsLastCallTrackingContext() - : last_call_was_set_visibility_(0) {} + : last_call_was_set_visibility_(false) {} // WebGraphicsContext3D methods. virtual void setVisibilityCHROMIUM(bool visible) { - if (!last_call_was_set_visibility_) - return; - DCHECK(*last_call_was_set_visibility_ == false); - *last_call_was_set_visibility_ = true; + DCHECK(last_call_was_set_visibility_ == false); + last_call_was_set_visibility_ = true; } virtual void flush() { - if (last_call_was_set_visibility_) - *last_call_was_set_visibility_ = false; + last_call_was_set_visibility_ = false; } virtual void deleteTexture(WebGLId) { - if (last_call_was_set_visibility_) - *last_call_was_set_visibility_ = false; + last_call_was_set_visibility_ = false; } virtual void deleteFramebuffer(WebGLId) { - if (last_call_was_set_visibility_) - *last_call_was_set_visibility_ = false; + last_call_was_set_visibility_ = false; + } + virtual void deleteQueryEXT(WebGLId) { + last_call_was_set_visibility_ = false; } virtual void deleteRenderbuffer(WebGLId) { - if (last_call_was_set_visibility_) - *last_call_was_set_visibility_ = false; + last_call_was_set_visibility_ = false; + } + virtual void discardBackbufferCHROMIUM() { + last_call_was_set_visibility_ = false; + } + virtual void ensureBackbufferCHROMIUM() { + last_call_was_set_visibility_ = false; } // This method would normally do a glSwapBuffers under the hood. @@ -831,13 +768,12 @@ class VisibilityChangeIsLastCallTrackingContext } // Methods added for test. - void set_last_call_was_set_visibility_pointer( - bool* last_call_was_set_visibility) { - last_call_was_set_visibility_ = last_call_was_set_visibility; + bool last_call_was_set_visibility() const { + return last_call_was_set_visibility_; } private: - bool* last_call_was_set_visibility_; + bool last_call_was_set_visibility_; }; TEST(GLRendererTest2, VisibilityChangeIsLastCall) { @@ -855,20 +791,15 @@ TEST(GLRendererTest2, VisibilityChangeIsLastCall) { EXPECT_TRUE(renderer.Initialize()); - bool last_call_was_set_visiblity = false; // Ensure that the call to setVisibilityCHROMIUM is the last call issue to the // GPU process, after glFlush is called, and after the RendererClient's // SetManagedMemoryPolicy is called. Plumb this tracking between both the // RenderClient and the Context by giving them both a pointer to a variable on // the stack. - context->set_last_call_was_set_visibility_pointer( - &last_call_was_set_visiblity); - mock_client.set_last_call_was_set_visibility_pointer( - &last_call_was_set_visiblity); renderer.SetVisible(true); renderer.DrawFrame(mock_client.render_passes_in_draw_order()); renderer.SetVisible(false); - EXPECT_TRUE(last_call_was_set_visiblity); + EXPECT_TRUE(context->last_call_was_set_visibility()); } class TextureStateTrackingContext : public TestWebGraphicsContext3D { diff --git a/cc/resources/managed_memory_policy.cc b/cc/output/managed_memory_policy.cc index 3571d7a..f21fbd6 100644 --- a/cc/resources/managed_memory_policy.cc +++ b/cc/output/managed_memory_policy.cc @@ -1,8 +1,8 @@ -// Copyright 2011 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/resources/managed_memory_policy.h" +#include "cc/output/managed_memory_policy.h" #include "base/logging.h" #include "cc/resources/priority_calculator.h" diff --git a/cc/resources/managed_memory_policy.h b/cc/output/managed_memory_policy.h index dd8ac25..2790e8b 100644 --- a/cc/resources/managed_memory_policy.h +++ b/cc/output/managed_memory_policy.h @@ -1,9 +1,9 @@ -// Copyright 2011 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_RESOURCES_MANAGED_MEMORY_POLICY_H_ -#define CC_RESOURCES_MANAGED_MEMORY_POLICY_H_ +#ifndef CC_OUTPUT_MANAGED_MEMORY_POLICY_H_ +#define CC_OUTPUT_MANAGED_MEMORY_POLICY_H_ #include "base/basictypes.h" #include "cc/base/cc_export.h" @@ -39,4 +39,4 @@ struct CC_EXPORT ManagedMemoryPolicy { } // namespace cc -#endif // CC_RESOURCES_MANAGED_MEMORY_POLICY_H_ +#endif // CC_OUTPUT_MANAGED_MEMORY_POLICY_H_ diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 15112f6..a992e8e 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -15,6 +15,7 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "cc/output/compositor_frame.h" +#include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" #include "cc/scheduler/delay_based_time_source.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" @@ -28,11 +29,35 @@ using std::string; using std::vector; namespace cc { +namespace { + +ManagedMemoryPolicy::PriorityCutoff ConvertPriorityCutoff( + WebKit::WebGraphicsMemoryAllocation::PriorityCutoff priority_cutoff) { + // This is simple a 1:1 map, the names differ only because the WebKit names + // should be to match the cc names. + switch (priority_cutoff) { + case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowNothing: + return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; + case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleOnly: + return ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY; + case WebKit::WebGraphicsMemoryAllocation:: + PriorityCutoffAllowVisibleAndNearby: + return ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE; + case WebKit::WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything: + return ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING; + } + NOTREACHED(); + return ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; +} + +} // anonymous namespace class OutputSurfaceCallbacks : public WebKit::WebGraphicsContext3D:: WebGraphicsSwapBuffersCompleteCallbackCHROMIUM, - public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { + public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback, + public WebKit::WebGraphicsContext3D:: + WebGraphicsMemoryAllocationChangedCallbackCHROMIUM { public: explicit OutputSurfaceCallbacks(OutputSurface* client) : client_(client) { @@ -45,6 +70,17 @@ class OutputSurfaceCallbacks // WK:WGC3D::WGContextLostCallback implementation. virtual void onContextLost() { client_->DidLoseOutputSurface(); } + // WK:WGC3D::WGMemoryAllocationChangedCallbackCHROMIUM implementation. + virtual void onMemoryAllocationChanged( + WebKit::WebGraphicsMemoryAllocation allocation) { + ManagedMemoryPolicy policy( + allocation.bytesLimitWhenVisible, + ConvertPriorityCutoff(allocation.priorityCutoffWhenVisible), + allocation.bytesLimitWhenNotVisible, + ConvertPriorityCutoff(allocation.priorityCutoffWhenNotVisible)); + client_->SetMemoryPolicy(policy, !allocation.suggestHaveBackbuffer); + } + private: OutputSurface* client_; }; @@ -303,6 +339,7 @@ void OutputSurface::SetContext3D( callbacks_.reset(new OutputSurfaceCallbacks(this)); context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get()); context3d_->setContextLostCallback(callbacks_.get()); + context3d_->setMemoryAllocationChangedCallbackCHROMIUM(callbacks_.get()); } void OutputSurface::EnsureBackbuffer() { @@ -377,4 +414,12 @@ void OutputSurface::PostSwapBuffersComplete() { static_cast<CompositorFrameAck*>(NULL))); } +void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible) { + TRACE_EVENT2("cc", "OutputSurface::SetMemoryPolicy", + "bytes_limit_when_visible", policy.bytes_limit_when_visible, + "discard_backbuffer", discard_backbuffer_when_not_visible); + client_->SetMemoryPolicy(policy, discard_backbuffer_when_not_visible); +} + } // namespace cc diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index 738e650..bb783d9 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -29,6 +29,7 @@ namespace cc { class CompositorFrame; class CompositorFrameAck; +struct ManagedMemoryPolicy; class OutputSurfaceClient; class OutputSurfaceCallbacks; @@ -178,6 +179,8 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { friend class OutputSurfaceCallbacks; void SetContext3D(scoped_ptr<WebKit::WebGraphicsContext3D> context3d); + void SetMemoryPolicy(const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible); BeginFrameArgs skipped_begin_frame_args_; diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index 4816ac7..72126cd 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h @@ -19,6 +19,7 @@ class Transform; namespace cc { class CompositorFrameAck; +struct ManagedMemoryPolicy; class CC_EXPORT OutputSurfaceClient { public: @@ -33,6 +34,8 @@ class CC_EXPORT OutputSurfaceClient { virtual void DidLoseOutputSurface() = 0; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) = 0; + virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible) = 0; protected: virtual ~OutputSurfaceClient() {} diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index a73b779..54ad9ac 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/test/test_simple_task_runner.h" +#include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface.h" #include "cc/output/output_surface_client.h" #include "cc/output/software_output_device.h" @@ -11,6 +12,8 @@ #include "gpu/GLES2/gl2extchromium.h" #include "testing/gtest/include/gtest/gtest.h" +using WebKit::WebGraphicsMemoryAllocation; + namespace cc { namespace { @@ -81,7 +84,9 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { : begin_frame_count_(0), deferred_initialize_result_(true), deferred_initialize_called_(false), - did_lose_output_surface_called_(false) {} + did_lose_output_surface_called_(false), + memory_policy_(0), + discard_backbuffer_when_not_visible_(false) {} virtual bool DeferredInitialize( scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE { @@ -98,6 +103,12 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { } virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) OVERRIDE {} + virtual void SetMemoryPolicy( + const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible) OVERRIDE { + memory_policy_ = policy; + discard_backbuffer_when_not_visible_ = discard_backbuffer_when_not_visible; + } int begin_frame_count() { return begin_frame_count_; @@ -115,11 +126,19 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { return did_lose_output_surface_called_; } + const ManagedMemoryPolicy& memory_policy() const { return memory_policy_; } + + bool discard_backbuffer_when_not_visible() const { + return discard_backbuffer_when_not_visible_; + } + private: int begin_frame_count_; bool deferred_initialize_result_; bool deferred_initialize_called_; bool did_lose_output_surface_called_; + ManagedMemoryPolicy memory_policy_; + bool discard_backbuffer_when_not_visible_; }; TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) { @@ -352,5 +371,50 @@ TEST(OutputSurfaceTest, OptimisticAndRetroactiveBeginFrames) { EXPECT_EQ(client.begin_frame_count(), 4); } +TEST(OutputSurfaceTest, MemoryAllocation) { + scoped_ptr<TestWebGraphicsContext3D> scoped_context = + TestWebGraphicsContext3D::Create(); + TestWebGraphicsContext3D* context = scoped_context.get(); + + TestOutputSurface output_surface( + scoped_context.PassAs<WebKit::WebGraphicsContext3D>()); + + FakeOutputSurfaceClient client; + EXPECT_TRUE(output_surface.BindToClient(&client)); + + WebGraphicsMemoryAllocation allocation; + allocation.suggestHaveBackbuffer = true; + allocation.bytesLimitWhenVisible = 1234; + allocation.priorityCutoffWhenVisible = + WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleOnly; + allocation.bytesLimitWhenNotVisible = 4567; + allocation.priorityCutoffWhenNotVisible = + WebGraphicsMemoryAllocation::PriorityCutoffAllowNothing; + + context->SetMemoryAllocation(allocation); + + EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible); + EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY, + client.memory_policy().priority_cutoff_when_visible); + EXPECT_EQ(4567u, client.memory_policy().bytes_limit_when_not_visible); + EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING, + client.memory_policy().priority_cutoff_when_not_visible); + EXPECT_FALSE(client.discard_backbuffer_when_not_visible()); + + allocation.suggestHaveBackbuffer = false; + context->SetMemoryAllocation(allocation); + EXPECT_TRUE(client.discard_backbuffer_when_not_visible()); + + allocation.priorityCutoffWhenVisible = + WebGraphicsMemoryAllocation::PriorityCutoffAllowEverything; + allocation.priorityCutoffWhenNotVisible = + WebGraphicsMemoryAllocation::PriorityCutoffAllowVisibleAndNearby; + context->SetMemoryAllocation(allocation); + EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, + client.memory_policy().priority_cutoff_when_visible); + EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE, + client.memory_policy().priority_cutoff_when_not_visible); +} + } // namespace } // namespace cc diff --git a/cc/output/renderer.h b/cc/output/renderer.h index 3070073..3a628ad 100644 --- a/cc/output/renderer.h +++ b/cc/output/renderer.h @@ -8,7 +8,6 @@ #include "base/basictypes.h" #include "cc/base/cc_export.h" #include "cc/quads/render_pass.h" -#include "cc/resources/managed_memory_policy.h" #include "cc/trees/layer_tree_host.h" namespace cc { @@ -27,7 +26,6 @@ class CC_EXPORT RendererClient { virtual float DeviceScaleFactor() const = 0; virtual const LayerTreeSettings& Settings() const = 0; virtual void SetFullRootLayerDamage() = 0; - virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; virtual bool HasImplThread() const = 0; virtual bool ShouldClearRootRenderPass() const = 0; virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const = 0; @@ -76,6 +74,8 @@ class CC_EXPORT Renderer { size_t bytes_visible_and_nearby, size_t bytes_allocated) = 0; + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) = 0; + protected: explicit Renderer(RendererClient* client) : client_(client) {} diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 1cf221c..2da959f 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -490,4 +490,10 @@ void SoftwareRenderer::SetVisible(bool visible) { visible_ = visible; } +void SoftwareRenderer::SetDiscardBackBufferWhenNotVisible(bool discard) { + // TODO(piman, skaslev): Can we release the backbuffer? We don't currently + // receive memory policy yet anyway. + NOTIMPLEMENTED(); +} + } // namespace cc diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h index 4adf922..f810b68 100644 --- a/cc/output/software_renderer.h +++ b/cc/output/software_renderer.h @@ -44,6 +44,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { size_t bytes_allocated) OVERRIDE {} virtual void ReceiveSwapBuffersAck( const CompositorFrameAck& ack) OVERRIDE; + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE; protected: virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) OVERRIDE; diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc index a882c2d..deaf2f9 100644 --- a/cc/output/software_renderer_unittest.cc +++ b/cc/output/software_renderer_unittest.cc @@ -62,8 +62,6 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { return settings_; } virtual void SetFullRootLayerDamage() OVERRIDE {} - virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) - OVERRIDE {} virtual bool HasImplThread() const OVERRIDE { return false; } virtual bool ShouldClearRootRenderPass() const OVERRIDE { return should_clear_root_render_pass_; diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index cd007c1..ed1ad5a 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -41,8 +41,6 @@ class PixelTest::PixelTestRendererClient return settings_; } virtual void SetFullRootLayerDamage() OVERRIDE {} - virtual void SetManagedMemoryPolicy( - const ManagedMemoryPolicy& policy) OVERRIDE {} virtual bool HasImplThread() const OVERRIDE { return false; } virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; } virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const @@ -66,6 +64,8 @@ class PixelTest::PixelTestRendererClient gfx::Rect viewport) OVERRIDE { device_viewport_ = viewport; } + virtual void SetMemoryPolicy( + const ManagedMemoryPolicy& policy, bool discard) OVERRIDE {} private: gfx::Rect device_viewport_; diff --git a/cc/test/test_web_graphics_context_3d.cc b/cc/test/test_web_graphics_context_3d.cc index 2f1f4c7..f5ebb6b 100644 --- a/cc/test/test_web_graphics_context_3d.cc +++ b/cc/test/test_web_graphics_context_3d.cc @@ -52,6 +52,7 @@ TestWebGraphicsContext3D::TestWebGraphicsContext3D() times_map_buffer_chromium_succeeds_(-1), context_lost_callback_(NULL), swap_buffers_callback_(NULL), + memory_allocation_changed_callback_(NULL), max_texture_size_(1024), width_(0), height_(0), @@ -78,6 +79,7 @@ TestWebGraphicsContext3D::TestWebGraphicsContext3D( times_map_buffer_chromium_succeeds_(-1), context_lost_callback_(NULL), swap_buffers_callback_(NULL), + memory_allocation_changed_callback_(NULL), max_texture_size_(1024), width_(0), height_(0), @@ -368,6 +370,11 @@ void TestWebGraphicsContext3D::setSwapBuffersCompleteCallbackCHROMIUM( swap_buffers_callback_ = callback; } +void TestWebGraphicsContext3D::setMemoryAllocationChangedCallbackCHROMIUM( + WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback) { + memory_allocation_changed_callback_ = callback; +} + void TestWebGraphicsContext3D::prepareTexture() { if (swap_buffers_callback_) { base::MessageLoop::current()->PostTask( @@ -531,6 +538,13 @@ WebKit::WGC3Duint TestWebGraphicsContext3D::NextImageId() { return image_id; } +void TestWebGraphicsContext3D::SetMemoryAllocation( + WebKit::WebGraphicsMemoryAllocation allocation) { + if (!memory_allocation_changed_callback_) + return; + memory_allocation_changed_callback_->onMemoryAllocationChanged(allocation); +} + TestWebGraphicsContext3D::Buffer::Buffer() : target(0) {} TestWebGraphicsContext3D::Buffer::~Buffer() {} diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h index 401fa4a4..4855b0a 100644 --- a/cc/test/test_web_graphics_context_3d.h +++ b/cc/test/test_web_graphics_context_3d.h @@ -114,6 +114,9 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D { virtual void setSwapBuffersCompleteCallbackCHROMIUM( WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* callback); + virtual void setMemoryAllocationChangedCallbackCHROMIUM( + WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* callback); + virtual void prepareTexture(); virtual void finish(); virtual void flush(); @@ -196,6 +199,8 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D { virtual WebKit::WebGLId NextImageId(); + void SetMemoryAllocation(WebKit::WebGraphicsMemoryAllocation allocation); + protected: TestWebGraphicsContext3D(); TestWebGraphicsContext3D( @@ -220,6 +225,8 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D { int times_map_buffer_chromium_succeeds_; WebGraphicsContextLostCallback* context_lost_callback_; WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* swap_buffers_callback_; + WebGraphicsMemoryAllocationChangedCallbackCHROMIUM* + memory_allocation_changed_callback_; std::vector<WebGraphicsSyncPointCallback*> sync_point_callbacks_; std::vector<WebKit::WebGLId> textures_; base::hash_set<WebKit::WebGLId> used_textures_; diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 73df3c5..38c410c5 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -47,7 +47,6 @@ RendererCapabilities::RendererCapabilities() : best_texture_format(0), using_partial_swap(false), using_set_visibility(false), - using_gpu_memory_manager(false), using_egl_image(false), allow_partial_texture_updates(false), using_offscreen_context3d(false), diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 2b162fd..109c69c 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -74,7 +74,6 @@ struct CC_EXPORT RendererCapabilities { unsigned best_texture_format; bool using_partial_swap; bool using_set_visibility; - bool using_gpu_memory_manager; bool using_egl_image; bool allow_partial_texture_updates; bool using_offscreen_context3d; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 99386b9..abe83b0 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1030,6 +1030,19 @@ bool LayerTreeHostImpl::ShouldClearRootRenderPass() const { return settings_.should_clear_root_render_pass; } +void LayerTreeHostImpl::SetMemoryPolicy( + const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible) { + if (policy.bytes_limit_when_visible) { + // Just ignore the memory manager when it says to set the limit to zero + // bytes. This will happen when the memory manager thinks that the renderer + // is not visible (which the renderer knows better). + SetManagedMemoryPolicy(policy); + } + renderer_->SetDiscardBackBufferWhenNotVisible( + discard_backbuffer_when_not_visible); +} + void LayerTreeHostImpl::SetManagedMemoryPolicy( const ManagedMemoryPolicy& policy) { if (managed_memory_policy_ == policy) diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index ab6ab46..cf9b094 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -20,6 +20,7 @@ #include "cc/layers/layer_lists.h" #include "cc/layers/render_pass_sink.h" #include "cc/output/begin_frame_args.h" +#include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" #include "cc/output/renderer.h" #include "cc/quads/render_pass.h" @@ -186,8 +187,6 @@ class CC_EXPORT LayerTreeHostImpl virtual const LayerTreeSettings& Settings() const OVERRIDE; public: virtual void SetFullRootLayerDamage() OVERRIDE; - virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) - OVERRIDE; virtual bool HasImplThread() const OVERRIDE; virtual bool ShouldClearRootRenderPass() const OVERRIDE; virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE; @@ -203,12 +202,14 @@ class CC_EXPORT LayerTreeHostImpl virtual bool DeferredInitialize( scoped_refptr<ContextProvider> offscreen_context_provider) OVERRIDE; virtual void SetNeedsRedrawRect(gfx::Rect rect) OVERRIDE; - virtual void BeginFrame(const BeginFrameArgs& args) - OVERRIDE; + virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) OVERRIDE; virtual void DidLoseOutputSurface() OVERRIDE; virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE; + virtual void SetMemoryPolicy( + const ManagedMemoryPolicy& policy, + bool discard_backbuffer_when_not_visible) OVERRIDE; // Called from LayerTreeImpl. void OnCanDrawStateChangedForTree(); @@ -438,6 +439,7 @@ class CC_EXPORT LayerTreeHostImpl void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) const; void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time); + void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy); void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy); scoped_ptr<OutputSurface> output_surface_; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 7b1c59e..0387538 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -71,7 +71,9 @@ class LayerTreeHostImplTest : public testing::Test, did_request_commit_(false), did_request_redraw_(false), did_upload_visible_tile_(false), - reduce_memory_result_(true) { + reduce_memory_result_(true), + current_limit_bytes_(0), + current_priority_cutoff_value_(0) { media::InitializeMediaLibraryForTesting(); } @@ -123,6 +125,8 @@ class LayerTreeHostImplTest : public testing::Test, base::Time wall_clock_time) OVERRIDE {} virtual bool ReduceContentsTextureMemoryOnImplThread( size_t limit_bytes, int priority_cutoff) OVERRIDE { + current_limit_bytes_ = limit_bytes; + current_priority_cutoff_value_ = priority_cutoff; return reduce_memory_result_; } virtual void ReduceWastedContentsTextureMemoryOnImplThread() OVERRIDE {} @@ -286,6 +290,8 @@ class LayerTreeHostImplTest : public testing::Test, bool did_upload_visible_tile_; bool reduce_memory_result_; base::TimeDelta requested_scrollbar_animation_delay_; + size_t current_limit_bytes_; + int current_priority_cutoff_value_; }; class TestWebGraphicsContext3DMakeCurrentFails @@ -331,16 +337,16 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { // Toggle contents textures purged without causing any evictions, // and make sure that it does not change can_draw. set_reduce_memory_result(false); - host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( + host_impl_->memory_allocation_limit_bytes() - 1), true); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_FALSE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; // Toggle contents textures purged to make sure it toggles can_draw. set_reduce_memory_result(true); - host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( + host_impl_->memory_allocation_limit_bytes() - 1), true); EXPECT_FALSE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; @@ -4693,8 +4699,8 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { set_reduce_memory_result(false); host_impl_->set_max_memory_needed_bytes( host_impl_->memory_allocation_limit_bytes() - 1); - host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( + host_impl_->memory_allocation_limit_bytes() - 1), true); EXPECT_FALSE(did_request_commit_); did_request_commit_ = false; @@ -4704,8 +4710,8 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { set_reduce_memory_result(false); host_impl_->set_max_memory_needed_bytes( host_impl_->memory_allocation_limit_bytes()); - host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( + host_impl_->memory_allocation_limit_bytes() - 1), true); EXPECT_TRUE(did_request_commit_); did_request_commit_ = false; @@ -4713,15 +4719,15 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { // to re-commit. set_reduce_memory_result(true); host_impl_->set_max_memory_needed_bytes(1); - host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( + host_impl_->memory_allocation_limit_bytes() - 1), true); EXPECT_TRUE(did_request_commit_); did_request_commit_ = false; // But if we set it to the same value that it was before, we shouldn't // re-commit. - host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes())); + host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( + host_impl_->memory_allocation_limit_bytes()), true); EXPECT_FALSE(did_request_commit_); } @@ -4765,8 +4771,6 @@ class TestRenderer : public GLRenderer, public RendererClient { return settings_; } virtual void SetFullRootLayerDamage() OVERRIDE {} - virtual void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy) - OVERRIDE {} virtual bool HasImplThread() const OVERRIDE { return false; } virtual bool ShouldClearRootRenderPass() const OVERRIDE { return true; } virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const @@ -6025,5 +6029,66 @@ TEST_F(LayerTreeHostImplTest, DeferredInitializeSmoke) { DrawFrame(); } +class ContextThatDoesNotSupportMemoryManagmentExtensions + : public TestWebGraphicsContext3D { + public: + // WebGraphicsContext3D methods. + virtual WebKit::WebString getString(WebKit::WGC3Denum name) { + return WebKit::WebString(); + } +}; + +// Checks that we have a non-0 default allocation if we pass a context that +// doesn't support memory management extensions. +TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) { + LayerTreeSettings settings; + host_impl_ = LayerTreeHostImpl::Create(settings, + this, + &proxy_, + &stats_instrumentation_); + + host_impl_->InitializeRenderer(FakeOutputSurface::Create3d( + scoped_ptr<WebKit::WebGraphicsContext3D>( + new ContextThatDoesNotSupportMemoryManagmentExtensions)) + .PassAs<OutputSurface>()); + EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes()); +} + +TEST_F(LayerTreeHostImplTest, MemoryPolicy) { + ManagedMemoryPolicy policy1( + 456, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, + 123, ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE); + int visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( + policy1.priority_cutoff_when_visible); + int not_visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( + policy1.priority_cutoff_when_not_visible); + + host_impl_->SetVisible(true); + host_impl_->SetMemoryPolicy(policy1, false); + EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); + EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_); + + host_impl_->SetVisible(false); + EXPECT_EQ(policy1.bytes_limit_when_not_visible, current_limit_bytes_); + EXPECT_EQ(not_visible_cutoff_value, current_priority_cutoff_value_); + + host_impl_->SetVisible(true); + EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); + EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_); + + // A policy with a 0 allocation is discarded. + ManagedMemoryPolicy actual_policy = host_impl_->ActualManagedMemoryPolicy(); + ManagedMemoryPolicy policy2( + 0, ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY, + 0, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING); + host_impl_->SetMemoryPolicy(policy2, false); + EXPECT_EQ(actual_policy, host_impl_->ActualManagedMemoryPolicy()); + EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); + EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_); + host_impl_->SetVisible(false); + EXPECT_EQ(policy1.bytes_limit_when_not_visible, current_limit_bytes_); + EXPECT_EQ(not_visible_cutoff_value, current_priority_cutoff_value_); +} + } // namespace } // namespace cc diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc index 8a67c65..c412fd5 100644 --- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc +++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc @@ -28,9 +28,10 @@ class LayerTreeHostOnDemandRasterPixelTest : public LayerTreePixelTest { virtual void BeginCommitOnThread(LayerTreeHostImpl* impl) OVERRIDE { // Not enough memory available. Enforce on-demand rasterization. - impl->SetManagedMemoryPolicy( + impl->SetMemoryPolicy( ManagedMemoryPolicy(1, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, - 1, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING)); + 1, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING), + true); } virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index f85e598..849cb38 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -1562,8 +1562,8 @@ class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit // Reduce the memory limit to only fit the root layer and one render // surface. This prevents any contents drawing into surfaces // from being allocated. - host_impl->SetManagedMemoryPolicy( - ManagedMemoryPolicy(100 * 100 * 4 * 2)); + host_impl->SetMemoryPolicy( + ManagedMemoryPolicy(100 * 100 * 4 * 2), true); break; case 1: EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId( @@ -2180,11 +2180,12 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted layer_tree_host()->contents_texture_manager()->MemoryUseBytes()); // Set a new policy that will kick out 1 of the 3 resources. // Because a resource was evicted, a commit will be kicked off. - host_impl->SetManagedMemoryPolicy( + host_impl->SetMemoryPolicy( ManagedMemoryPolicy(100 * 100 * 4 * 2, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, 100 * 100 * 4 * 1, - ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING)); + ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING), + true); break; case 2: // Only two backings should have memory. diff --git a/ui/compositor/test_web_graphics_context_3d.h b/ui/compositor/test_web_graphics_context_3d.h index e2607c7..66e2a15 100644 --- a/ui/compositor/test_web_graphics_context_3d.h +++ b/ui/compositor/test_web_graphics_context_3d.h @@ -58,7 +58,6 @@ class COMPOSITOR_EXPORT TestWebGraphicsContext3D : virtual void discardFramebufferEXT(WebKit::WGC3Denum target, WebKit::WGC3Dsizei numAttachments, const WebKit::WGC3Denum* attachments) {} - virtual void ensureFramebufferCHROMIUM() {} virtual void setMemoryAllocationChangedCallbackCHROMIUM( WebGraphicsMemoryAllocationChangedCallbackCHROMIUM*) { } virtual WebKit::WebString getRequestableExtensionsCHROMIUM(); |