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

Unified Diff: android_webview/browser/hardware_renderer.cc

Issue 226363004: Global GPU memory manager for android webview (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove "HardwareRenderer::GetMemoryPolicy" declaration 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
Index: android_webview/browser/hardware_renderer.cc
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index a45da7ff724231c5775bfc66b33474068a95fe18..46e1620683913cadaa455f708f95ea868ae26dfd 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -6,7 +6,6 @@
#include "android_webview/browser/aw_gl_surface.h"
#include "android_webview/browser/browser_view_renderer_client.h"
-#include "android_webview/browser/gl_view_renderer_manager.h"
#include "android_webview/browser/scoped_app_gl_state_restore.h"
#include "android_webview/public/browser/draw_gl.h"
#include "base/command_line.h"
@@ -15,6 +14,8 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/shader_translator_cache.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/transform.h"
@@ -30,6 +31,13 @@ const size_t g_memory_multiplier = 10;
const size_t g_num_gralloc_limit = 150;
const size_t kBytesPerPixel = 4;
const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
+// HardwareRenderer needs |g_num_gralloc_limit| tiles to draw quickly, but it
+// will be resource hungry if it only gets allocated less than
+// |kGrallocHungryLimit|.
+const size_t kGrallocHungryLimit = 100;
+// HardwareRenderer becomes starved if the resource request cannot be granted
+// kStarvedTimes in a row.
+const size_t kStarvedTimes = 5;
base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> >
g_service = LAZY_INSTANCE_INITIALIZER;
@@ -39,9 +47,12 @@ base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> >
HardwareRenderer::HardwareRenderer(SharedRendererState* state)
: shared_renderer_state_(state),
last_egl_context_(eglGetCurrentContext()),
- manager_key_(GLViewRendererManager::GetInstance()->PushBack(
- shared_renderer_state_)) {
+ renderer_manager_key_(GLViewRendererManager::GetInstance()->PushBack(
+ shared_renderer_state_)),
+ tile_manager_key_(GlobalTileManager::GetInstance()->PushBack(this)),
+ num_hungry_(0) {
DCHECK(last_egl_context_);
+
if (!g_service.Get()) {
g_service.Get() = new internal::DeferredGpuCommandService;
content::SynchronousCompositor::SetGpuService(g_service.Get());
@@ -59,8 +70,13 @@ HardwareRenderer::HardwareRenderer(SharedRendererState* state)
}
HardwareRenderer::~HardwareRenderer() {
- GLViewRendererManager* mru = GLViewRendererManager::GetInstance();
- mru->Remove(manager_key_);
+ GLViewRendererManager* render_manager = GLViewRendererManager::GetInstance();
+ render_manager->Remove(renderer_manager_key_);
+
+ GlobalTileManager* tile_manager = GlobalTileManager::GetInstance();
+ tile_manager->RequestTiles(
+ memory_policy_.num_resources_limit, 0, IsStarved(), tile_manager_key_);
+ tile_manager->Remove(tile_manager_key_);
ScopedAppGLStateRestore state_restore(
ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
@@ -72,7 +88,8 @@ HardwareRenderer::~HardwareRenderer() {
bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) {
TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
- GLViewRendererManager::GetInstance()->DidDrawGL(manager_key_);
+ GLViewRendererManager::GetInstance()->DidDrawGL(renderer_manager_key_);
+ GlobalTileManager::GetInstance()->DidDrawGL(tile_manager_key_);
const DrawGLInput input = shared_renderer_state_->GetDrawGLInput();
// We need to watch if the current Android context has changed and enforce
@@ -167,10 +184,8 @@ bool HardwareRenderer::TrimMemory(int level, bool visible) {
// Just set the memory limit to 0 and drop all tiles. This will be reset to
// normal levels in the next DrawGL call.
- content::SynchronousCompositorMemoryPolicy policy;
- policy.bytes_limit = 0;
- policy.num_resources_limit = 0;
- if (memory_policy_ == policy)
+ content::SynchronousCompositorMemoryPolicy zero_policy;
+ if (memory_policy_ == zero_policy)
return false;
TRACE_EVENT0("android_webview", "HardwareRenderer::TrimMemory");
@@ -178,7 +193,7 @@ bool HardwareRenderer::TrimMemory(int level, bool visible) {
ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
internal::ScopedAllowGL allow_gl;
- SetMemoryPolicy(policy);
+ SetMemoryPolicy(zero_policy);
return true;
}
@@ -187,9 +202,51 @@ void HardwareRenderer::SetMemoryPolicy(
if (memory_policy_ == new_policy)
return;
+ GlobalTileManager* tile_manager = GlobalTileManager::GetInstance();
+
+ size_t num_tiles = tile_manager->
+ RequestTiles(memory_policy_.num_resources_limit,
+ new_policy.num_resources_limit, IsStarved(), tile_manager_key_);
+
+ if (num_tiles <
+ std::min(kGrallocHungryLimit, new_policy.num_resources_limit))
+ num_hungry_++;
+ else
+ num_hungry_ = 0;
+
+
+ new_policy.num_resources_limit = num_tiles;
+
+ shared_renderer_state_->GetCompositor()->
+ SetMemoryPolicy(new_policy);
memory_policy_ = new_policy;
+}
+
+bool HardwareRenderer::IsStarved() {
+ // If the hardware renderer is hungry for kStarvedTimes in a row, this
+ // hardware renderer is considered starved.
+ return (num_hungry_ >= kStarvedTimes);
+}
+
+size_t HardwareRenderer::ForceDropTiles() {
+ size_t dropped_tiles = memory_policy_.num_resources_limit;
+ content::SynchronousCompositorMemoryPolicy zero_policy;
+ memory_policy_ = zero_policy;
shared_renderer_state_->GetCompositor()->
- SetMemoryPolicy(memory_policy_);
+ SetMemoryPolicy(zero_policy);
+
+
+ // Now force a fake SW draw to make sure the tiles are dropped because the
+ // tile manager only manages tiles after a Draw.
+ // Making a fake SW draw is a hacky way to forcibly drop tiles. Maybe we can
+ // find better implementations.
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(1, 1);
+ bitmap.eraseColor(0);
+ SkCanvas canvas(bitmap);
+
+ shared_renderer_state_->GetCompositor()->DemandDrawSw(&canvas);
+ return dropped_tiles;
}
// static

Powered by Google App Engine
This is Rietveld 408576698