summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-10 22:44:43 +0000
committerboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-10 22:44:43 +0000
commit0552c8ef896c4356f4db85618972dedccd6ad53b (patch)
treed00992f235af190d2bdb9de0a5f72fbfcc1c9917
parent1e7258d60d7ebdb30a27552d900e885922119a2c (diff)
downloadchromium_src-0552c8ef896c4356f4db85618972dedccd6ad53b.zip
chromium_src-0552c8ef896c4356f4db85618972dedccd6ad53b.tar.gz
chromium_src-0552c8ef896c4356f4db85618972dedccd6ad53b.tar.bz2
[Android WebView] First cut memory management
Based on simple algorithm of visible rect x constant. Completely disregards the preferred allocation from based on content of the page. Constants extermined experimentally using current android nexus devices. BUG=286026 Review URL: https://chromiumcodereview.appspot.com/23572023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222372 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--android_webview/browser/in_process_view_renderer.cc55
-rw-r--r--android_webview/browser/in_process_view_renderer.h2
-rw-r--r--android_webview/common/aw_switches.cc2
-rw-r--r--android_webview/common/aw_switches.h4
-rw-r--r--android_webview/lib/main/aw_main_delegate.cc3
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.cc8
-rw-r--r--content/browser/android/in_process/synchronous_compositor_impl.h2
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.cc32
-rw-r--r--content/browser/android/in_process/synchronous_compositor_output_surface.h6
-rw-r--r--content/content_browser.gypi1
-rw-r--r--content/public/browser/android/synchronous_compositor.cc12
-rw-r--r--content/public/browser/android/synchronous_compositor.h14
-rw-r--r--content/public/common/content_switches.h4
13 files changed, 131 insertions, 14 deletions
diff --git a/android_webview/browser/in_process_view_renderer.cc b/android_webview/browser/in_process_view_renderer.cc
index aebf732..07b4d67 100644
--- a/android_webview/browser/in_process_view_renderer.cc
+++ b/android_webview/browser/in_process_view_renderer.cc
@@ -17,10 +17,12 @@
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/in_process_command_buffer.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkBitmapDevice.h"
@@ -28,6 +30,7 @@
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/utils/SkCanvasStateUtils.h"
+#include "ui/gfx/android/device_display_info.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/vector2d_conversions.h"
@@ -143,6 +146,13 @@ AwDrawSWFunctionTable* g_sw_draw_functions = NULL;
const int64 kFallbackTickTimeoutInMilliseconds = 20;
+
+// Used to calculate memory and resource allocation. Determined experimentally.
+size_t g_memory_multiplier = 15;
+const size_t kMaxNumTilesToFillDisplay = 20;
+const size_t kBytesPerPixel = 4;
+const size_t kMemoryAllocationStep = 10 * 1024 * 1024;
+
class ScopedAllowGL {
public:
ScopedAllowGL();
@@ -276,6 +286,39 @@ void InProcessViewRenderer::WebContentsGone() {
compositor_ = NULL;
}
+// static
+void InProcessViewRenderer::CalculateTileMemoryPolicy() {
+ CommandLine* cl = CommandLine::ForCurrentProcess();
+ if (cl->HasSwitch(switches::kTileMemoryMultiplier)) {
+ std::string string_value =
+ cl->GetSwitchValueASCII(switches::kTileMemoryMultiplier);
+ int int_value;
+ if (base::StringToInt(string_value, &int_value) &&
+ int_value >= 2 && int_value <= 50) {
+ g_memory_multiplier = int_value;
+ }
+ }
+
+ if (cl->HasSwitch(switches::kDefaultTileWidth) ||
+ cl->HasSwitch(switches::kDefaultTileHeight)) {
+ return;
+ }
+
+ // TODO(boliu): Should use view context to get the display dimensions, and
+ // pass tile size in a per WebContents setting instead of through command
+ // line switch.
+ gfx::DeviceDisplayInfo info;
+ int default_tile_size = 256;
+
+ if (info.GetDisplayWidth() >= 1080)
+ default_tile_size = 512;
+
+ std::stringstream size;
+ size << default_tile_size;
+ cl->AppendSwitchASCII(switches::kDefaultTileWidth, size.str());
+ cl->AppendSwitchASCII(switches::kDefaultTileHeight, size.str());
+}
+
bool InProcessViewRenderer::RequestProcessGL() {
return client_->RequestDrawGL(NULL);
}
@@ -372,6 +415,18 @@ void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) {
return;
}
+ // Update memory budget. This will no-op in compositor if the policy has not
+ // changed since last draw.
+ content::SynchronousCompositorMemoryPolicy policy;
+ policy.bytes_limit = g_memory_multiplier * kBytesPerPixel *
+ cached_global_visible_rect_.width() *
+ cached_global_visible_rect_.height();
+ // Round up to a multiple of kMemoryAllocationStep.
+ policy.bytes_limit =
+ (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
+ policy.num_resources_limit = kMaxNumTilesToFillDisplay * g_memory_multiplier;
+ compositor_->SetMemoryPolicy(policy);
+
DCHECK(gl_surface_);
gl_surface_->SetBackingFrameBufferObject(
state_restore.framebuffer_binding_ext());
diff --git a/android_webview/browser/in_process_view_renderer.h b/android_webview/browser/in_process_view_renderer.h
index 620f010..a864a39 100644
--- a/android_webview/browser/in_process_view_renderer.h
+++ b/android_webview/browser/in_process_view_renderer.h
@@ -30,6 +30,8 @@ class AwGLSurface;
class InProcessViewRenderer : public BrowserViewRenderer,
public content::SynchronousCompositorClient {
public:
+ static void CalculateTileMemoryPolicy();
+
InProcessViewRenderer(BrowserViewRenderer::Client* client,
JavaHelper* java_helper,
content::WebContents* web_contents);
diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc
index a87e93a..b2663fa 100644
--- a/android_webview/common/aw_switches.cc
+++ b/android_webview/common/aw_switches.cc
@@ -10,4 +10,6 @@ const char kDisableSimpleCache[] = "disable-simple-cache";
const char kDisableWebViewGLMode[] = "disable-webview-gl-mode";
+const char kTileMemoryMultiplier[] = "tile-memory-multiplier";
+
} // namespace switches
diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h
index 2c7db28..e855bb7 100644
--- a/android_webview/common/aw_switches.h
+++ b/android_webview/common/aw_switches.h
@@ -13,6 +13,10 @@ extern const char kDisableSimpleCache[];
// When set, forces use of fallback SW path even on HW canvas.
extern const char kDisableWebViewGLMode[];
+// Used to make tile memory allocation decision. Roughly the number of
+// displays that a single layer will have enough memory for.
+extern const char kTileMemoryMultiplier[];
+
} // namespace switches
#endif // ANDROID_WEBVIEW_COMMON_AW_SWITCHES_H_
diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc
index ff7dfbf..10906c7 100644
--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -6,6 +6,7 @@
#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/gpu_memory_buffer_factory_impl.h"
+#include "android_webview/browser/in_process_view_renderer.h"
#include "android_webview/browser/scoped_allow_wait_for_legacy_web_view_api.h"
#include "android_webview/lib/aw_browser_dependency_factory_impl.h"
#include "android_webview/native/aw_geolocation_permission_context.h"
@@ -50,6 +51,8 @@ bool AwMainDelegate::BasicStartupComplete(int* exit_code) {
gpu_memory_buffer_factory_.get());
gpu::InProcessCommandBuffer::EnableVirtualizedContext();
+ InProcessViewRenderer::CalculateTileMemoryPolicy();
+
CommandLine* cl = CommandLine::ForCurrentProcess();
cl->AppendSwitch(switches::kEnableBeginFrameScheduling);
cl->AppendSwitch(cc::switches::kEnableMapImage);
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 3f71321..9f1b607 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -331,6 +331,14 @@ bool SynchronousCompositorImpl::DemandDrawSw(SkCanvas* canvas) {
return output_surface_->DemandDrawSw(canvas);
}
+void SynchronousCompositorImpl::SetMemoryPolicy(
+ const SynchronousCompositorMemoryPolicy& policy) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(output_surface_);
+
+ return output_surface_->SetMemoryPolicy(policy);
+}
+
void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset() {
if (input_handler_)
input_handler_->OnRootLayerDelegatedScrollOffsetChanged();
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index 854c5eb..3189dcc 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -58,6 +58,8 @@ class SynchronousCompositorImpl
gfx::Rect clip,
bool stencil_enabled) OVERRIDE;
virtual bool DemandDrawSw(SkCanvas* canvas) OVERRIDE;
+ virtual void SetMemoryPolicy(
+ const SynchronousCompositorMemoryPolicy& policy) OVERRIDE;
virtual void DidChangeRootLayerScrollOffset() OVERRIDE;
// SynchronousCompositorOutputSurfaceDelegate
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
index 2760a62..4137734 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc
@@ -9,7 +9,6 @@
#include "cc/output/begin_frame_args.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/context_provider.h"
-#include "cc/output/managed_memory_policy.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/software_output_device.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
@@ -108,7 +107,9 @@ SynchronousCompositorOutputSurface::SynchronousCompositorOutputSurface(
needs_begin_frame_(false),
invoking_composite_(false),
did_swap_buffer_(false),
- current_sw_canvas_(NULL) {
+ current_sw_canvas_(NULL),
+ memory_policy_(0),
+ output_surface_client_(NULL) {
capabilities_.deferred_gl_initialization = true;
capabilities_.draw_and_swap_full_viewport_every_frame = true;
capabilities_.adjust_deadline_for_parent = false;
@@ -136,21 +137,16 @@ bool SynchronousCompositorOutputSurface::BindToClient(
DCHECK(CalledOnValidThread());
if (!cc::OutputSurface::BindToClient(surface_client))
return false;
- surface_client->SetTreeActivationCallback(
+
+ output_surface_client_ = surface_client;
+ output_surface_client_->SetTreeActivationCallback(
base::Bind(&DidActivatePendingTree, routing_id_));
+ output_surface_client_->SetMemoryPolicy(memory_policy_);
+
SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate();
if (delegate)
delegate->DidBindOutputSurface(this);
- const int bytes_limit = 64 * 1024 * 1024;
- const int num_resources_limit = 100;
- surface_client->SetMemoryPolicy(
- cc::ManagedMemoryPolicy(bytes_limit,
- cc::ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING,
- 0,
- cc::ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING,
- num_resources_limit));
-
return true;
}
@@ -171,6 +167,7 @@ void SynchronousCompositorOutputSurface::SetNeedsBeginFrame(
void SynchronousCompositorOutputSurface::SwapBuffers(
cc::CompositorFrame* frame) {
+ DCHECK(CalledOnValidThread());
if (!ForcedDrawToSoftwareDevice()) {
DCHECK(context_provider_);
context_provider_->Context3d()->shallowFlushCHROMIUM();
@@ -206,6 +203,7 @@ bool SynchronousCompositorOutputSurface::InitializeHwDraw(
}
void SynchronousCompositorOutputSurface::ReleaseHwDraw() {
+ DCHECK(CalledOnValidThread());
cc::OutputSurface::ReleaseGL();
}
@@ -287,6 +285,16 @@ void SynchronousCompositorOutputSurface::PostCheckForRetroactiveBeginFrame() {
// intentionally no-op here.
}
+void SynchronousCompositorOutputSurface::SetMemoryPolicy(
+ const SynchronousCompositorMemoryPolicy& policy) {
+ DCHECK(CalledOnValidThread());
+ memory_policy_.bytes_limit_when_visible = policy.bytes_limit;
+ memory_policy_.num_resources_limit = policy.num_resources_limit;
+
+ if (output_surface_client_)
+ output_surface_client_->SetMemoryPolicy(memory_policy_);
+}
+
// Not using base::NonThreadSafe as we want to enforce a more exacting threading
// requirement: SynchronousCompositorOutputSurface() must only be used on the UI
// thread.
diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.h b/content/browser/android/in_process/synchronous_compositor_output_surface.h
index d11651d..b9b4d67 100644
--- a/content/browser/android/in_process/synchronous_compositor_output_surface.h
+++ b/content/browser/android/in_process/synchronous_compositor_output_surface.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "cc/output/managed_memory_policy.h"
#include "cc/output/output_surface.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "ui/gfx/transform.h"
@@ -72,6 +73,7 @@ class SynchronousCompositorOutputSurface
gfx::Rect clip,
bool stencil_enabled);
bool DemandDrawSw(SkCanvas* canvas);
+ void SetMemoryPolicy(const SynchronousCompositorMemoryPolicy& policy);
private:
class SoftwareDevice;
@@ -99,6 +101,10 @@ class SynchronousCompositorOutputSurface
// Only valid (non-NULL) during a DemandDrawSw() call.
SkCanvas* current_sw_canvas_;
+ cc::ManagedMemoryPolicy memory_policy_;
+
+ cc::OutputSurfaceClient* output_surface_client_;
+
DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorOutputSurface);
};
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 6ef6695..8b17172 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -37,6 +37,7 @@
'public/browser/android/devtools_auth.h',
'public/browser/android/download_controller_android.h',
'public/browser/android/synchronous_compositor_client.h',
+ 'public/browser/android/synchronous_compositor.cc',
'public/browser/android/synchronous_compositor.h',
'public/browser/browser_accessibility_state.h',
'public/browser/browser_child_process_host.h',
diff --git a/content/public/browser/android/synchronous_compositor.cc b/content/public/browser/android/synchronous_compositor.cc
new file mode 100644
index 0000000..051aa5b
--- /dev/null
+++ b/content/public/browser/android/synchronous_compositor.cc
@@ -0,0 +1,12 @@
+// 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 "content/public/browser/android/synchronous_compositor.h"
+
+namespace content {
+
+SynchronousCompositorMemoryPolicy::SynchronousCompositorMemoryPolicy()
+ : bytes_limit(0), num_resources_limit(0) {}
+
+} // namespace content
diff --git a/content/public/browser/android/synchronous_compositor.h b/content/public/browser/android/synchronous_compositor.h
index 810daf2..45b01eb 100644
--- a/content/public/browser/android/synchronous_compositor.h
+++ b/content/public/browser/android/synchronous_compositor.h
@@ -23,6 +23,16 @@ class WebContents;
class SynchronousCompositorClient;
+struct CONTENT_EXPORT SynchronousCompositorMemoryPolicy {
+ // Memory limit for rendering and pre-rendering.
+ size_t bytes_limit;
+
+ // Limit of number of GL resources used for rendering and pre-rendering.
+ size_t num_resources_limit;
+
+ SynchronousCompositorMemoryPolicy();
+};
+
// Interface for embedders that wish to direct compositing operations
// synchronously under their own control. Only meaningful when the
// kEnableSyncrhonousRendererCompositor flag is specified.
@@ -65,6 +75,10 @@ class CONTENT_EXPORT SynchronousCompositor {
// and clip set there-in).
virtual bool DemandDrawSw(SkCanvas* canvas) = 0;
+ // Set the memory limit policy of this compositor.
+ virtual void SetMemoryPolicy(
+ const SynchronousCompositorMemoryPolicy& policy) = 0;
+
// Should be called by the embedder after the embedder had modified the
// scroll offset of the root layer (as returned by
// SynchronousCompositorClient::GetTotalRootLayerScrollOffset).
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 089e1e8..381abdd 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -28,8 +28,8 @@ CONTENT_EXPORT extern const char kBrowserAssertTest[];
CONTENT_EXPORT extern const char kBrowserCrashTest[];
CONTENT_EXPORT extern const char kBrowserSubprocessPath[];
extern const char kDebugPluginLoading[];
-extern const char kDefaultTileWidth[];
-extern const char kDefaultTileHeight[];
+CONTENT_EXPORT extern const char kDefaultTileWidth[];
+CONTENT_EXPORT extern const char kDefaultTileHeight[];
extern const char kDirectNPAPIRequests[];
CONTENT_EXPORT extern const char kDisable2dCanvasAntialiasing[];
CONTENT_EXPORT extern const char kDisable3DAPIs[];