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

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

Powered by Google App Engine
This is Rietveld 408576698