diff options
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[]; |