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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "android_webview/browser/hardware_renderer.h" 5 #include "android_webview/browser/hardware_renderer.h"
6 6
7 #include "android_webview/browser/aw_gl_surface.h" 7 #include "android_webview/browser/aw_gl_surface.h"
8 #include "android_webview/browser/browser_view_renderer_client.h" 8 #include "android_webview/browser/browser_view_renderer_client.h"
9 #include "android_webview/browser/gl_view_renderer_manager.h"
10 #include "android_webview/browser/scoped_app_gl_state_restore.h" 9 #include "android_webview/browser/scoped_app_gl_state_restore.h"
11 #include "android_webview/public/browser/draw_gl.h" 10 #include "android_webview/public/browser/draw_gl.h"
12 #include "base/command_line.h" 11 #include "base/command_line.h"
13 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
14 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
15 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
16 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
17 #include "gpu/command_buffer/service/shader_translator_cache.h" 16 #include "gpu/command_buffer/service/shader_translator_cache.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "ui/gfx/geometry/rect_conversions.h" 19 #include "ui/gfx/geometry/rect_conversions.h"
19 #include "ui/gfx/geometry/rect_f.h" 20 #include "ui/gfx/geometry/rect_f.h"
20 #include "ui/gfx/transform.h" 21 #include "ui/gfx/transform.h"
21 22
22 using content::BrowserThread; 23 using content::BrowserThread;
23 24
24 namespace android_webview { 25 namespace android_webview {
25 26
26 namespace { 27 namespace {
27 28
28 // Used to calculate memory and resource allocation. Determined experimentally. 29 // Used to calculate memory and resource allocation. Determined experimentally.
29 const size_t g_memory_multiplier = 10; 30 const size_t g_memory_multiplier = 10;
30 const size_t g_num_gralloc_limit = 150; 31 const size_t g_num_gralloc_limit = 150;
31 const size_t kBytesPerPixel = 4; 32 const size_t kBytesPerPixel = 4;
32 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; 33 const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
34 // HardwareRenderer needs |g_num_gralloc_limit| tiles to draw quickly, but it
35 // will be resource hungry if it only gets allocated less than
36 // |kGrallocHungryLimit|.
37 const size_t kGrallocHungryLimit = 100;
38 // HardwareRenderer becomes starved if the resource request cannot be granted
39 // kStarvedTimes in a row.
40 const size_t kStarvedTimes = 5;
33 41
34 base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> > 42 base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> >
35 g_service = LAZY_INSTANCE_INITIALIZER; 43 g_service = LAZY_INSTANCE_INITIALIZER;
36 44
37 } // namespace 45 } // namespace
38 46
39 HardwareRenderer::HardwareRenderer(SharedRendererState* state) 47 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
40 : shared_renderer_state_(state), 48 : shared_renderer_state_(state),
41 last_egl_context_(eglGetCurrentContext()), 49 last_egl_context_(eglGetCurrentContext()),
42 manager_key_(GLViewRendererManager::GetInstance()->PushBack( 50 renderer_manager_key_(GLViewRendererManager::GetInstance()->PushBack(
43 shared_renderer_state_)) { 51 shared_renderer_state_)),
52 tile_manager_key_(GlobalTileManager::GetInstance()->PushBack(this)),
53 num_hungry_(0) {
44 DCHECK(last_egl_context_); 54 DCHECK(last_egl_context_);
55
45 if (!g_service.Get()) { 56 if (!g_service.Get()) {
46 g_service.Get() = new internal::DeferredGpuCommandService; 57 g_service.Get() = new internal::DeferredGpuCommandService;
47 content::SynchronousCompositor::SetGpuService(g_service.Get()); 58 content::SynchronousCompositor::SetGpuService(g_service.Get());
48 } 59 }
49 60
50 ScopedAppGLStateRestore state_restore( 61 ScopedAppGLStateRestore state_restore(
51 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 62 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
52 internal::ScopedAllowGL allow_gl; 63 internal::ScopedAllowGL allow_gl;
53 64
54 gl_surface_ = new AwGLSurface; 65 gl_surface_ = new AwGLSurface;
55 bool success = 66 bool success =
56 shared_renderer_state_->GetCompositor()-> 67 shared_renderer_state_->GetCompositor()->
57 InitializeHwDraw(gl_surface_); 68 InitializeHwDraw(gl_surface_);
58 DCHECK(success); 69 DCHECK(success);
59 } 70 }
60 71
61 HardwareRenderer::~HardwareRenderer() { 72 HardwareRenderer::~HardwareRenderer() {
62 GLViewRendererManager* mru = GLViewRendererManager::GetInstance(); 73 GLViewRendererManager* render_manager = GLViewRendererManager::GetInstance();
63 mru->Remove(manager_key_); 74 render_manager->Remove(renderer_manager_key_);
75
76 GlobalTileManager* tile_manager = GlobalTileManager::GetInstance();
77 tile_manager->RequestTiles(
78 memory_policy_.num_resources_limit, 0, IsStarved(), tile_manager_key_);
79 tile_manager->Remove(tile_manager_key_);
64 80
65 ScopedAppGLStateRestore state_restore( 81 ScopedAppGLStateRestore state_restore(
66 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 82 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
67 internal::ScopedAllowGL allow_gl; 83 internal::ScopedAllowGL allow_gl;
68 84
69 shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); 85 shared_renderer_state_->GetCompositor()->ReleaseHwDraw();
70 gl_surface_ = NULL; 86 gl_surface_ = NULL;
71 } 87 }
72 88
73 bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) { 89 bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) {
74 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); 90 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
75 GLViewRendererManager::GetInstance()->DidDrawGL(manager_key_); 91 GLViewRendererManager::GetInstance()->DidDrawGL(renderer_manager_key_);
92 GlobalTileManager::GetInstance()->DidDrawGL(tile_manager_key_);
76 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput(); 93 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput();
77 94
78 // We need to watch if the current Android context has changed and enforce 95 // We need to watch if the current Android context has changed and enforce
79 // a clean-up in the compositor. 96 // a clean-up in the compositor.
80 EGLContext current_context = eglGetCurrentContext(); 97 EGLContext current_context = eglGetCurrentContext();
81 if (!current_context) { 98 if (!current_context) {
82 DLOG(ERROR) << "DrawGL called without EGLContext"; 99 DLOG(ERROR) << "DrawGL called without EGLContext";
83 return false; 100 return false;
84 } 101 }
85 102
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 177
161 if (!eglGetCurrentContext()) { 178 if (!eglGetCurrentContext()) {
162 NOTREACHED(); 179 NOTREACHED();
163 return false; 180 return false;
164 } 181 }
165 182
166 DCHECK_EQ(last_egl_context_, eglGetCurrentContext()); 183 DCHECK_EQ(last_egl_context_, eglGetCurrentContext());
167 184
168 // Just set the memory limit to 0 and drop all tiles. This will be reset to 185 // Just set the memory limit to 0 and drop all tiles. This will be reset to
169 // normal levels in the next DrawGL call. 186 // normal levels in the next DrawGL call.
170 content::SynchronousCompositorMemoryPolicy policy; 187 content::SynchronousCompositorMemoryPolicy zero_policy;
171 policy.bytes_limit = 0; 188 if (memory_policy_ == zero_policy)
172 policy.num_resources_limit = 0;
173 if (memory_policy_ == policy)
174 return false; 189 return false;
175 190
176 TRACE_EVENT0("android_webview", "HardwareRenderer::TrimMemory"); 191 TRACE_EVENT0("android_webview", "HardwareRenderer::TrimMemory");
177 ScopedAppGLStateRestore state_restore( 192 ScopedAppGLStateRestore state_restore(
178 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 193 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
179 internal::ScopedAllowGL allow_gl; 194 internal::ScopedAllowGL allow_gl;
180 195
181 SetMemoryPolicy(policy); 196 SetMemoryPolicy(zero_policy);
182 return true; 197 return true;
183 } 198 }
184 199
185 void HardwareRenderer::SetMemoryPolicy( 200 void HardwareRenderer::SetMemoryPolicy(
186 content::SynchronousCompositorMemoryPolicy& new_policy) { 201 content::SynchronousCompositorMemoryPolicy& new_policy) {
187 if (memory_policy_ == new_policy) 202 if (memory_policy_ == new_policy)
188 return; 203 return;
189 204
205 GlobalTileManager* tile_manager = GlobalTileManager::GetInstance();
206
207 size_t num_tiles = tile_manager->
208 RequestTiles(memory_policy_.num_resources_limit,
209 new_policy.num_resources_limit, IsStarved(), tile_manager_key_);
210
211 if (num_tiles <
212 std::min(kGrallocHungryLimit, new_policy.num_resources_limit))
213 num_hungry_++;
214 else
215 num_hungry_ = 0;
216
217
218 new_policy.num_resources_limit = num_tiles;
219
220 shared_renderer_state_->GetCompositor()->
221 SetMemoryPolicy(new_policy);
190 memory_policy_ = new_policy; 222 memory_policy_ = new_policy;
223 }
224
225 bool HardwareRenderer::IsStarved() {
226 // If the hardware renderer is hungry for kStarvedTimes in a row, this
227 // hardware renderer is considered starved.
228 return (num_hungry_ >= kStarvedTimes);
229 }
230
231 size_t HardwareRenderer::ForceDropTiles() {
232 size_t dropped_tiles = memory_policy_.num_resources_limit;
233 content::SynchronousCompositorMemoryPolicy zero_policy;
234 memory_policy_ = zero_policy;
191 shared_renderer_state_->GetCompositor()-> 235 shared_renderer_state_->GetCompositor()->
192 SetMemoryPolicy(memory_policy_); 236 SetMemoryPolicy(zero_policy);
237
238
239 // Now force a fake SW draw to make sure the tiles are dropped because the
240 // tile manager only manages tiles after a Draw.
241 // Making a fake SW draw is a hacky way to forcibly drop tiles. Maybe we can
242 // find better implementations.
243 SkBitmap bitmap;
244 bitmap.allocN32Pixels(1, 1);
245 bitmap.eraseColor(0);
246 SkCanvas canvas(bitmap);
247
248 shared_renderer_state_->GetCompositor()->DemandDrawSw(&canvas);
249 return dropped_tiles;
193 } 250 }
194 251
195 // static 252 // static
196 void HardwareRenderer::CalculateTileMemoryPolicy() { 253 void HardwareRenderer::CalculateTileMemoryPolicy() {
197 CommandLine* cl = CommandLine::ForCurrentProcess(); 254 CommandLine* cl = CommandLine::ForCurrentProcess();
198 255
199 const char kDefaultTileSize[] = "384"; 256 const char kDefaultTileSize[] = "384";
200 if (!cl->HasSwitch(switches::kDefaultTileWidth)) 257 if (!cl->HasSwitch(switches::kDefaultTileWidth))
201 cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize); 258 cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize);
202 259
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef(); 352 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
296 } 353 }
297 354
298 void DeferredGpuCommandService::Release() const { 355 void DeferredGpuCommandService::Release() const {
299 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release(); 356 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
300 } 357 }
301 358
302 } // namespace internal 359 } // namespace internal
303 360
304 } // namespace android_webview 361 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698