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

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: address Bo's comments Created 6 years, 7 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"
14 #include "content/public/browser/android/synchronous_compositor.h"
15 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/common/content_switches.h" 16 #include "content/public/common/content_switches.h"
17 #include "gpu/command_buffer/service/shader_translator_cache.h" 17 #include "gpu/command_buffer/service/shader_translator_cache.h"
18 #include "ui/gfx/geometry/rect_conversions.h" 18 #include "ui/gfx/geometry/rect_conversions.h"
19 #include "ui/gfx/geometry/rect_f.h" 19 #include "ui/gfx/geometry/rect_f.h"
20 #include "ui/gfx/transform.h" 20 #include "ui/gfx/transform.h"
21 21
22 using content::BrowserThread;
23
24 namespace android_webview { 22 namespace android_webview {
25 23
26 namespace { 24 namespace {
27 25
28 // Used to calculate memory and resource allocation. Determined experimentally.
29 const size_t g_memory_multiplier = 10;
30 const size_t g_num_gralloc_limit = 150;
31 const size_t kBytesPerPixel = 4;
32 const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
33
34 base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> > 26 base::LazyInstance<scoped_refptr<internal::DeferredGpuCommandService> >
35 g_service = LAZY_INSTANCE_INITIALIZER; 27 g_service = LAZY_INSTANCE_INITIALIZER;
36 28
37 } // namespace 29 } // namespace
38 30
39 HardwareRenderer::HardwareRenderer(SharedRendererState* state) 31 HardwareRenderer::HardwareRenderer(SharedRendererState* state)
40 : shared_renderer_state_(state), 32 : shared_renderer_state_(state),
41 last_egl_context_(eglGetCurrentContext()), 33 last_egl_context_(eglGetCurrentContext()),
42 manager_key_(GLViewRendererManager::GetInstance()->PushBack( 34 renderer_manager_key_(GLViewRendererManager::GetInstance()->PushBack(
43 shared_renderer_state_)) { 35 shared_renderer_state_)) {
44 DCHECK(last_egl_context_); 36 DCHECK(last_egl_context_);
45 if (!g_service.Get()) { 37 if (!g_service.Get()) {
46 g_service.Get() = new internal::DeferredGpuCommandService; 38 g_service.Get() = new internal::DeferredGpuCommandService;
47 content::SynchronousCompositor::SetGpuService(g_service.Get()); 39 content::SynchronousCompositor::SetGpuService(g_service.Get());
48 } 40 }
49 41
50 ScopedAppGLStateRestore state_restore( 42 ScopedAppGLStateRestore state_restore(
51 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 43 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
52 internal::ScopedAllowGL allow_gl; 44 internal::ScopedAllowGL allow_gl;
53 45
54 gl_surface_ = new AwGLSurface; 46 gl_surface_ = new AwGLSurface;
55 bool success = 47 bool success =
56 shared_renderer_state_->GetCompositor()-> 48 shared_renderer_state_->GetCompositor()->
57 InitializeHwDraw(gl_surface_); 49 InitializeHwDraw(gl_surface_);
58 DCHECK(success); 50 DCHECK(success);
59 } 51 }
60 52
61 HardwareRenderer::~HardwareRenderer() { 53 HardwareRenderer::~HardwareRenderer() {
62 GLViewRendererManager* mru = GLViewRendererManager::GetInstance(); 54 GLViewRendererManager* render_manager = GLViewRendererManager::GetInstance();
63 mru->Remove(manager_key_); 55 render_manager->Remove(renderer_manager_key_);
64 56
65 ScopedAppGLStateRestore state_restore( 57 ScopedAppGLStateRestore state_restore(
66 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); 58 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
67 internal::ScopedAllowGL allow_gl; 59 internal::ScopedAllowGL allow_gl;
68 60
69 shared_renderer_state_->GetCompositor()->ReleaseHwDraw(); 61 shared_renderer_state_->GetCompositor()->ReleaseHwDraw();
70 gl_surface_ = NULL; 62 gl_surface_ = NULL;
71 } 63 }
72 64
73 bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) { 65 bool HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, DrawGLResult* result) {
74 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); 66 TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL");
75 GLViewRendererManager::GetInstance()->DidDrawGL(manager_key_); 67 GLViewRendererManager::GetInstance()->DidDrawGL(renderer_manager_key_);
76 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput(); 68 const DrawGLInput input = shared_renderer_state_->GetDrawGLInput();
77 69
78 // We need to watch if the current Android context has changed and enforce 70 // We need to watch if the current Android context has changed and enforce
79 // a clean-up in the compositor. 71 // a clean-up in the compositor.
80 EGLContext current_context = eglGetCurrentContext(); 72 EGLContext current_context = eglGetCurrentContext();
81 if (!current_context) { 73 if (!current_context) {
82 DLOG(ERROR) << "DrawGL called without EGLContext"; 74 DLOG(ERROR) << "DrawGL called without EGLContext";
83 return false; 75 return false;
84 } 76 }
85 77
86 // TODO(boliu): Handle context loss. 78 // TODO(boliu): Handle context loss.
87 if (last_egl_context_ != current_context) 79 if (last_egl_context_ != current_context)
88 DLOG(WARNING) << "EGLContextChanged"; 80 DLOG(WARNING) << "EGLContextChanged";
89 81
90 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); 82 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW);
91 internal::ScopedAllowGL allow_gl; 83 internal::ScopedAllowGL allow_gl;
92 84
93 if (draw_info->mode == AwDrawGLInfo::kModeProcess) 85 if (draw_info->mode == AwDrawGLInfo::kModeProcess)
94 return false; 86 return false;
95 87
96 // Update memory budget. This will no-op in compositor if the policy has not 88 SetCompositorMemoryPolicy();
97 // changed since last draw.
98 content::SynchronousCompositorMemoryPolicy policy;
99 policy.bytes_limit = g_memory_multiplier * kBytesPerPixel *
100 input.global_visible_rect.width() *
101 input.global_visible_rect.height();
102 // Round up to a multiple of kMemoryAllocationStep.
103 policy.bytes_limit =
104 (policy.bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
105 policy.num_resources_limit = g_num_gralloc_limit;
106 SetMemoryPolicy(policy);
107 89
108 gl_surface_->SetBackingFrameBufferObject( 90 gl_surface_->SetBackingFrameBufferObject(
109 state_restore.framebuffer_binding_ext()); 91 state_restore.framebuffer_binding_ext());
110 92
111 gfx::Transform transform; 93 gfx::Transform transform;
112 transform.matrix().setColMajorf(draw_info->transform); 94 transform.matrix().setColMajorf(draw_info->transform);
113 transform.Translate(input.scroll_offset.x(), input.scroll_offset.y()); 95 transform.Translate(input.scroll_offset.x(), input.scroll_offset.y());
114 gfx::Rect clip_rect(draw_info->clip_left, 96 gfx::Rect clip_rect(draw_info->clip_left,
115 draw_info->clip_top, 97 draw_info->clip_top,
116 draw_info->clip_right - draw_info->clip_left, 98 draw_info->clip_right - draw_info->clip_left,
(...skipping 16 matching lines...) Expand all
133 gl_surface_->ResetBackingFrameBufferObject(); 115 gl_surface_->ResetBackingFrameBufferObject();
134 116
135 if (did_draw) { 117 if (did_draw) {
136 result->frame_id = input.frame_id; 118 result->frame_id = input.frame_id;
137 result->clip_contains_visible_rect = 119 result->clip_contains_visible_rect =
138 clip_rect.Contains(input.global_visible_rect); 120 clip_rect.Contains(input.global_visible_rect);
139 } 121 }
140 return did_draw; 122 return did_draw;
141 } 123 }
142 124
143 bool HardwareRenderer::TrimMemory(int level, bool visible) { 125 void HardwareRenderer::SetCompositorMemoryPolicy() {
144 // Constants from Android ComponentCallbacks2. 126 if (shared_renderer_state_->IsMemoryPolicyDirty()) {
145 enum { 127 content::SynchronousCompositorMemoryPolicy policy =
146 TRIM_MEMORY_RUNNING_LOW = 10, 128 shared_renderer_state_->GetMemoryPolicy();
147 TRIM_MEMORY_UI_HIDDEN = 20, 129 // Memory policy is set by BrowserViewRenderer on UI thread.
148 TRIM_MEMORY_BACKGROUND = 40, 130 shared_renderer_state_->GetCompositor()->SetMemoryPolicy(policy);
149 }; 131 shared_renderer_state_->SetMemoryPolicyDirty(false);
150
151 // Not urgent enough. TRIM_MEMORY_UI_HIDDEN is treated specially because
152 // it does not indicate memory pressure, but merely that the app is
153 // backgrounded.
154 if (level < TRIM_MEMORY_RUNNING_LOW || level == TRIM_MEMORY_UI_HIDDEN)
155 return false;
156
157 // Do not release resources on view we expect to get DrawGL soon.
158 if (level < TRIM_MEMORY_BACKGROUND && visible)
159 return false;
160
161 if (!eglGetCurrentContext()) {
162 NOTREACHED();
163 return false;
164 } 132 }
165
166 DCHECK_EQ(last_egl_context_, eglGetCurrentContext());
167
168 // Just set the memory limit to 0 and drop all tiles. This will be reset to
169 // normal levels in the next DrawGL call.
170 content::SynchronousCompositorMemoryPolicy policy;
171 policy.bytes_limit = 0;
172 policy.num_resources_limit = 0;
173 if (memory_policy_ == policy)
174 return false;
175
176 TRACE_EVENT0("android_webview", "HardwareRenderer::TrimMemory");
177 ScopedAppGLStateRestore state_restore(
178 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT);
179 internal::ScopedAllowGL allow_gl;
180
181 SetMemoryPolicy(policy);
182 return true;
183 }
184
185 void HardwareRenderer::SetMemoryPolicy(
186 content::SynchronousCompositorMemoryPolicy& new_policy) {
187 if (memory_policy_ == new_policy)
188 return;
189
190 memory_policy_ = new_policy;
191 shared_renderer_state_->GetCompositor()->
192 SetMemoryPolicy(memory_policy_);
193 } 133 }
194 134
195 // static 135 // static
196 void HardwareRenderer::CalculateTileMemoryPolicy() { 136 void HardwareRenderer::CalculateTileMemoryPolicy() {
197 CommandLine* cl = CommandLine::ForCurrentProcess(); 137 CommandLine* cl = CommandLine::ForCurrentProcess();
198 138
199 const char kDefaultTileSize[] = "384"; 139 const char kDefaultTileSize[] = "384";
200 if (!cl->HasSwitch(switches::kDefaultTileWidth)) 140 if (!cl->HasSwitch(switches::kDefaultTileWidth))
201 cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize); 141 cl->AppendSwitchASCII(switches::kDefaultTileWidth, kDefaultTileSize);
202 142
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef(); 234 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
295 } 235 }
296 236
297 void DeferredGpuCommandService::Release() const { 237 void DeferredGpuCommandService::Release() const {
298 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release(); 238 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
299 } 239 }
300 240
301 } // namespace internal 241 } // namespace internal
302 242
303 } // namespace android_webview 243 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698