Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2046)

Unified Diff: android_webview/browser/browser_view_renderer.cc

Issue 226363004: Global GPU memory manager for android webview (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Type casts and private methods in BVR. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « android_webview/browser/browser_view_renderer.h ('k') | android_webview/browser/global_tile_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: android_webview/browser/browser_view_renderer.cc
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index c6188e3e4c60344fde7d02557aec2f510c28900f..7db981674578754db45baded9786af9ba539e759 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -9,11 +9,15 @@
#include "android_webview/public/browser/draw_gl.h"
#include "base/android/jni_android.h"
#include "base/auto_reset.h"
+#include "base/command_line.h"
#include "base/debug/trace_event.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 "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"
@@ -23,6 +27,8 @@
using base::android::AttachCurrentThread;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
+using content::BrowserThread;
+using content::SynchronousCompositorMemoryPolicy;
namespace android_webview {
@@ -30,6 +36,18 @@ namespace {
const int64 kFallbackTickTimeoutInMilliseconds = 20;
+// Used to calculate memory allocation. Determined experimentally.
+const size_t kMemoryMultiplier = 10;
+const size_t kBytesPerPixel = 4;
+const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
+
+// Used to calculate tile allocation. Determined experimentally.
+const size_t kTileMultiplier = 12;
+const size_t kTileAllocationStep = 20;
+// This will be set by static function CalculateTileMemoryPolicy() during init.
+// See AwMainDelegate::BasicStartupComplete.
+size_t g_tile_area;
+
class AutoResetWithLock {
public:
AutoResetWithLock(gfx::Vector2dF* scoped_variable,
@@ -57,6 +75,22 @@ class AutoResetWithLock {
} // namespace
+// static
+void BrowserViewRenderer::CalculateTileMemoryPolicy() {
+ CommandLine* cl = CommandLine::ForCurrentProcess();
+ const char kDefaultTileSize[] = "384";
+
+ if (!cl->HasSwitch(switches::kDefaultTileWidth))
+ cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize);
+
+ if (!cl->HasSwitch(switches::kDefaultTileHeight))
+ cl->AppendSwitchASCII(switches::kDefaultTileHeight, kDefaultTileSize);
+
+ size_t tile_size;
+ base::StringToSizeT(kDefaultTileSize, &tile_size);
+ g_tile_area = tile_size * tile_size;
+}
+
BrowserViewRenderer::BrowserViewRenderer(
BrowserViewRendererClient* client,
SharedRendererState* shared_renderer_state,
@@ -90,6 +124,99 @@ BrowserViewRenderer::BrowserViewRenderer(
BrowserViewRenderer::~BrowserViewRenderer() {
content::SynchronousCompositor::SetClientForWebContents(web_contents_, NULL);
+ // OnDetachedFromWindow should be called before the destructor, so the memory
+ // policy should have already been updated.
+}
+
+// This function updates the cached memory policy in shared renderer state, as
+// well as the tile resource allocation in GlobalTileManager.
+void BrowserViewRenderer::TrimMemory(const int level, const bool visible) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Constants from Android ComponentCallbacks2.
+ enum {
+ TRIM_MEMORY_RUNNING_LOW = 10,
+ TRIM_MEMORY_UI_HIDDEN = 20,
+ TRIM_MEMORY_BACKGROUND = 40,
+ };
+
+ // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
+ // it does not indicate memory pressure, but merely that the app is
+ // backgrounded.
+ if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
+ return;
+
+ // Do not release resources on view we expect to get DrawGL soon.
+ if (level < TRIM_MEMORY_BACKGROUND && visible)
+ return;
+
+ // Just set the memory limit to 0 and drop all tiles. This will be reset to
+ // normal levels in the next DrawGL call.
+ SynchronousCompositorMemoryPolicy zero_policy;
+ if (shared_renderer_state_->GetMemoryPolicy() == zero_policy)
+ return;
+
+ TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory");
+
+ RequestMemoryPolicy(zero_policy);
+ EnforceMemoryPolicyImmediately(zero_policy);
+}
+
+SynchronousCompositorMemoryPolicy
+BrowserViewRenderer::CalculateDesiredMemoryPolicy() {
+ SynchronousCompositorMemoryPolicy policy;
+ size_t width = draw_gl_input_.global_visible_rect.width();
+ size_t height = draw_gl_input_.global_visible_rect.height();
+ policy.bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
+ // Round up to a multiple of kMemoryAllocationStep.
+ policy.bytes_limit =
+ (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
+
+ size_t tiles = std::max(width * height * kTileMultiplier / g_tile_area, 1u);
+ // Round up to a multiple of kTileAllocationStep. The minimum number of tiles
+ // is also kTileAllocationStep.
+ tiles = (tiles + kTileAllocationStep - 1) / kTileAllocationStep *
+ kTileAllocationStep;
+ policy.num_resources_limit = tiles;
+ return policy;
+}
+
+// This function updates the cached memory policy in shared renderer state, as
+// well as the tile resource allocation in GlobalTileManager.
+void BrowserViewRenderer::RequestMemoryPolicy(
+ SynchronousCompositorMemoryPolicy& new_policy) {
+ // This will be used in SetNumTiles.
+ num_bytes_ = new_policy.bytes_limit;
+
+ GlobalTileManager* manager = GlobalTileManager::GetInstance();
+
+ // The following line will call BrowserViewRenderer::SetTilesNum().
+ manager->RequestTiles(new_policy.num_resources_limit, tile_manager_key_);
+}
+
+void BrowserViewRenderer::SetNumTiles(size_t num_tiles,
+ bool effective_immediately) {
+ if (num_tiles == num_tiles_)
+ return;
+ num_tiles_ = num_tiles;
+
+ SynchronousCompositorMemoryPolicy new_policy;
+ new_policy.num_resources_limit = num_tiles_;
+ new_policy.bytes_limit = num_bytes_;
+ shared_renderer_state_->SetMemoryPolicy(new_policy);
+
+ if (effective_immediately)
+ EnforceMemoryPolicyImmediately(new_policy);
+}
+
+void BrowserViewRenderer::EnforceMemoryPolicyImmediately(
+ SynchronousCompositorMemoryPolicy new_policy) {
+ shared_renderer_state_->GetCompositor()->SetMemoryPolicy(new_policy);
+ ForceFakeCompositeSW();
+ shared_renderer_state_->SetMemoryPolicyDirty(false);
+}
+
+size_t BrowserViewRenderer::GetNumTiles() const {
+ return shared_renderer_state_->GetMemoryPolicy().num_resources_limit;
}
bool BrowserViewRenderer::OnDraw(jobject java_canvas,
@@ -106,10 +233,23 @@ bool BrowserViewRenderer::OnDraw(jobject java_canvas,
return false;
if (is_hardware_canvas && attached_to_window_) {
shared_renderer_state_->SetDrawGLInput(draw_gl_input_);
+
+ SynchronousCompositorMemoryPolicy old_policy =
+ shared_renderer_state_->GetMemoryPolicy();
+ SynchronousCompositorMemoryPolicy new_policy =
+ CalculateDesiredMemoryPolicy();
+ RequestMemoryPolicy(new_policy);
// We should be performing a hardware draw here. If we don't have the
// compositor yet or if RequestDrawGL fails, it means we failed this draw
// and thus return false here to clear to background color for this draw.
- return has_compositor_ && client_->RequestDrawGL(java_canvas, false);
+ bool did_draw_gl =
+ has_compositor_ && client_->RequestDrawGL(java_canvas, false);
+ if (did_draw_gl)
+ GlobalTileManager::GetInstance()->DidUse(tile_manager_key_);
+ else
+ RequestMemoryPolicy(old_policy);
+
+ return did_draw_gl;
}
// Perform a software draw
return DrawSWInternal(java_canvas, clip);
@@ -230,11 +370,18 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) {
attached_to_window_ = true;
width_ = width;
height_ = height;
+ tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this);
}
void BrowserViewRenderer::OnDetachedFromWindow() {
TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
attached_to_window_ = false;
+ SynchronousCompositorMemoryPolicy zero_policy;
+ RequestMemoryPolicy(zero_policy);
+ GlobalTileManager::GetInstance()->Remove(tile_manager_key_);
+ // The hardware resources are released in the destructor of hardware renderer,
+ // so we don't need to do it here.
+ // See AwContents::ReleaseHardwareDrawOnRenderThread(JNIEnv*, jobject).
}
bool BrowserViewRenderer::IsAttachedToWindow() const {
@@ -268,6 +415,8 @@ void BrowserViewRenderer::DidDestroyCompositor(
DCHECK(ui_task_runner_->BelongsToCurrentThread());
has_compositor_ = false;
shared_renderer_state_->SetCompositorOnUiThread(NULL);
+ SynchronousCompositorMemoryPolicy zero_policy;
+ DCHECK(shared_renderer_state_->GetMemoryPolicy() == zero_policy);
}
void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) {
« no previous file with comments | « android_webview/browser/browser_view_renderer.h ('k') | android_webview/browser/global_tile_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698