summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-29 13:11:04 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-29 13:11:04 +0000
commitfd32d12c2b5df2ea7391003dca7307094535a297 (patch)
treeda94ae6e14da3c03f679bb81a848fa653d6beca2 /cc/output
parentfecf9f77fccd08c22e9655843a534c79ed0ba567 (diff)
downloadchromium_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
Diffstat (limited to 'cc/output')
-rw-r--r--cc/output/delegating_renderer.cc45
-rw-r--r--cc/output/delegating_renderer.h4
-rw-r--r--cc/output/gl_renderer.cc44
-rw-r--r--cc/output/gl_renderer.h16
-rw-r--r--cc/output/gl_renderer_unittest.cc135
-rw-r--r--cc/output/managed_memory_policy.cc74
-rw-r--r--cc/output/managed_memory_policy.h42
-rw-r--r--cc/output/output_surface.cc47
-rw-r--r--cc/output/output_surface.h3
-rw-r--r--cc/output/output_surface_client.h3
-rw-r--r--cc/output/output_surface_unittest.cc66
-rw-r--r--cc/output/renderer.h4
-rw-r--r--cc/output/software_renderer.cc6
-rw-r--r--cc/output/software_renderer.h1
-rw-r--r--cc/output/software_renderer_unittest.cc2
15 files changed, 321 insertions, 171 deletions
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/output/managed_memory_policy.cc b/cc/output/managed_memory_policy.cc
new file mode 100644
index 0000000..f21fbd6
--- /dev/null
+++ b/cc/output/managed_memory_policy.cc
@@ -0,0 +1,74 @@
+// 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/output/managed_memory_policy.h"
+
+#include "base/logging.h"
+#include "cc/resources/priority_calculator.h"
+
+namespace cc {
+
+ManagedMemoryPolicy::ManagedMemoryPolicy(size_t bytes_limit_when_visible)
+ : bytes_limit_when_visible(bytes_limit_when_visible),
+ priority_cutoff_when_visible(CUTOFF_ALLOW_EVERYTHING),
+ bytes_limit_when_not_visible(0),
+ priority_cutoff_when_not_visible(CUTOFF_ALLOW_NOTHING) {}
+
+ManagedMemoryPolicy::ManagedMemoryPolicy(
+ size_t bytes_limit_when_visible,
+ PriorityCutoff priority_cutoff_when_visible,
+ size_t bytes_limit_when_not_visible,
+ PriorityCutoff priority_cutoff_when_not_visible)
+ : bytes_limit_when_visible(bytes_limit_when_visible),
+ priority_cutoff_when_visible(priority_cutoff_when_visible),
+ bytes_limit_when_not_visible(bytes_limit_when_not_visible),
+ priority_cutoff_when_not_visible(priority_cutoff_when_not_visible) {}
+
+bool ManagedMemoryPolicy::operator==(const ManagedMemoryPolicy& other) const {
+ return bytes_limit_when_visible == other.bytes_limit_when_visible &&
+ priority_cutoff_when_visible == other.priority_cutoff_when_visible &&
+ bytes_limit_when_not_visible == other.bytes_limit_when_not_visible &&
+ priority_cutoff_when_not_visible ==
+ other.priority_cutoff_when_not_visible;
+}
+
+bool ManagedMemoryPolicy::operator!=(const ManagedMemoryPolicy& other) const {
+ return !(*this == other);
+}
+
+// static
+int ManagedMemoryPolicy::PriorityCutoffToValue(PriorityCutoff priority_cutoff) {
+ switch (priority_cutoff) {
+ case CUTOFF_ALLOW_NOTHING:
+ return PriorityCalculator::AllowNothingCutoff();
+ case CUTOFF_ALLOW_REQUIRED_ONLY:
+ return PriorityCalculator::AllowVisibleOnlyCutoff();
+ case CUTOFF_ALLOW_NICE_TO_HAVE:
+ return PriorityCalculator::AllowVisibleAndNearbyCutoff();
+ case CUTOFF_ALLOW_EVERYTHING:
+ return PriorityCalculator::AllowEverythingCutoff();
+ }
+ NOTREACHED();
+ return PriorityCalculator::AllowNothingCutoff();
+}
+
+// static
+TileMemoryLimitPolicy
+ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
+ PriorityCutoff priority_cutoff) {
+ switch (priority_cutoff) {
+ case CUTOFF_ALLOW_NOTHING:
+ return ALLOW_NOTHING;
+ case CUTOFF_ALLOW_REQUIRED_ONLY:
+ return ALLOW_ABSOLUTE_MINIMUM;
+ case CUTOFF_ALLOW_NICE_TO_HAVE:
+ return ALLOW_PREPAINT_ONLY;
+ case CUTOFF_ALLOW_EVERYTHING:
+ return ALLOW_ANYTHING;
+ }
+ NOTREACHED();
+ return ALLOW_NOTHING;
+}
+
+} // namespace cc
diff --git a/cc/output/managed_memory_policy.h b/cc/output/managed_memory_policy.h
new file mode 100644
index 0000000..2790e8b
--- /dev/null
+++ b/cc/output/managed_memory_policy.h
@@ -0,0 +1,42 @@
+// 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_OUTPUT_MANAGED_MEMORY_POLICY_H_
+#define CC_OUTPUT_MANAGED_MEMORY_POLICY_H_
+
+#include "base/basictypes.h"
+#include "cc/base/cc_export.h"
+#include "cc/resources/tile_priority.h"
+
+namespace cc {
+
+struct CC_EXPORT ManagedMemoryPolicy {
+ enum PriorityCutoff {
+ CUTOFF_ALLOW_NOTHING,
+ CUTOFF_ALLOW_REQUIRED_ONLY,
+ CUTOFF_ALLOW_NICE_TO_HAVE,
+ CUTOFF_ALLOW_EVERYTHING,
+ };
+
+ explicit ManagedMemoryPolicy(size_t bytes_limit_when_visible);
+ ManagedMemoryPolicy(size_t bytes_limit_when_visible,
+ PriorityCutoff priority_cutoff_when_visible,
+ size_t bytes_limit_when_not_visible,
+ PriorityCutoff priority_cutoff_when_not_visible);
+ bool operator==(const ManagedMemoryPolicy&) const;
+ bool operator!=(const ManagedMemoryPolicy&) const;
+
+ size_t bytes_limit_when_visible;
+ PriorityCutoff priority_cutoff_when_visible;
+ size_t bytes_limit_when_not_visible;
+ PriorityCutoff priority_cutoff_when_not_visible;
+
+ static int PriorityCutoffToValue(PriorityCutoff priority_cutoff);
+ static TileMemoryLimitPolicy PriorityCutoffToTileMemoryLimitPolicy(
+ PriorityCutoff priority_cutoff);
+};
+
+} // namespace cc
+
+#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_;