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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_android.cc

Issue 2336043004: Android: Free GLHelper context ashmem when it makes sense (Closed)
Patch Set: Android: Free GLHelper context ashmem when it makes sense Created 4 years, 3 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/renderer_host/render_widget_host_view_android.h" 5 #include "content/browser/renderer_host/render_widget_host_view_android.h"
6 6
7 #include <android/bitmap.h> 7 #include <android/bitmap.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/android/application_status_listener.h"
11 #include "base/android/build_info.h" 12 #include "base/android/build_info.h"
12 #include "base/android/context_utils.h" 13 #include "base/android/context_utils.h"
13 #include "base/bind.h" 14 #include "base/bind.h"
14 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 16 #include "base/command_line.h"
16 #include "base/location.h" 17 #include "base/location.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/macros.h" 19 #include "base/macros.h"
20 #include "base/memory/memory_pressure_listener.h"
19 #include "base/metrics/histogram_macros.h" 21 #include "base/metrics/histogram_macros.h"
20 #include "base/single_thread_task_runner.h" 22 #include "base/single_thread_task_runner.h"
21 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
22 #include "base/sys_info.h" 24 #include "base/sys_info.h"
23 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/threading/worker_pool.h" 26 #include "base/threading/worker_pool.h"
25 #include "cc/layers/layer.h" 27 #include "cc/layers/layer.h"
26 #include "cc/layers/surface_layer.h" 28 #include "cc/layers/surface_layer.h"
27 #include "cc/output/compositor_frame.h" 29 #include "cc/output/compositor_frame.h"
28 #include "cc/output/copy_output_request.h" 30 #include "cc/output/copy_output_request.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 #include "ui/touch_selection/touch_selection_controller.h" 94 #include "ui/touch_selection/touch_selection_controller.h"
93 95
94 namespace content { 96 namespace content {
95 97
96 namespace { 98 namespace {
97 99
98 const int kUndefinedOutputSurfaceId = -1; 100 const int kUndefinedOutputSurfaceId = -1;
99 101
100 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; 102 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
101 103
104 using base::android::ApplicationState;
105 using base::android::ApplicationStatusListener;
106 using base::MemoryPressureListener;
107
102 class GLHelperHolder { 108 class GLHelperHolder {
103 public: 109 public:
104 static GLHelperHolder* Create(); 110 static GLHelperHolder* Create();
105 111
106 display_compositor::GLHelper* gl_helper() { return gl_helper_.get(); } 112 display_compositor::GLHelper* gl_helper() { return gl_helper_.get(); }
107 bool IsLost() { 113 bool IsLost() {
108 if (!gl_helper_) 114 if (!gl_helper_)
109 return true; 115 return true;
110 return provider_->ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; 116 return provider_->ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
111 } 117 }
112 118
119 void FreeUnusedSharedMemoryIfNeeded();
120
113 private: 121 private:
114 GLHelperHolder() = default; 122 GLHelperHolder();
115 void Initialize(); 123 void Initialize();
116 void OnContextLost(); 124 void OnContextLost();
125 void OnApplicationStatusChanged(ApplicationState new_state);
126 void OnMemoryPressure(MemoryPressureListener::MemoryPressureLevel level);
117 127
118 scoped_refptr<ContextProviderCommandBuffer> provider_; 128 scoped_refptr<ContextProviderCommandBuffer> provider_;
119 std::unique_ptr<display_compositor::GLHelper> gl_helper_; 129 std::unique_ptr<display_compositor::GLHelper> gl_helper_;
120 130
131 bool has_running_activities_;
132 bool should_aggressively_free_memory_;
133
134 std::unique_ptr<ApplicationStatusListener> app_status_listener_;
135 std::unique_ptr<MemoryPressureListener> mem_pressure_listener_;
136
121 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder); 137 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder);
122 }; 138 };
123 139
140 GLHelperHolder::GLHelperHolder()
141 : has_running_activities_(
142 ApplicationStatusListener::GetState() ==
143 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES),
144 should_aggressively_free_memory_(!has_running_activities_) {}
145
124 GLHelperHolder* GLHelperHolder::Create() { 146 GLHelperHolder* GLHelperHolder::Create() {
125 GLHelperHolder* holder = new GLHelperHolder; 147 GLHelperHolder* holder = new GLHelperHolder;
126 holder->Initialize(); 148 holder->Initialize();
127 return holder; 149 return holder;
128 } 150 }
129 151
130 void GLHelperHolder::Initialize() { 152 void GLHelperHolder::Initialize() {
131 auto* factory = BrowserGpuChannelHostFactory::instance(); 153 auto* factory = BrowserGpuChannelHostFactory::instance();
132 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel()); 154 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel());
133 155
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 if (!provider_->BindToCurrentThread()) 198 if (!provider_->BindToCurrentThread())
177 return; 199 return;
178 provider_->ContextGL()->TraceBeginCHROMIUM( 200 provider_->ContextGL()->TraceBeginCHROMIUM(
179 "gpu_toplevel", 201 "gpu_toplevel",
180 base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get()) 202 base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get())
181 .c_str()); 203 .c_str());
182 provider_->SetLostContextCallback( 204 provider_->SetLostContextCallback(
183 base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this))); 205 base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this)));
184 gl_helper_.reset(new display_compositor::GLHelper( 206 gl_helper_.reset(new display_compositor::GLHelper(
185 provider_->ContextGL(), provider_->ContextSupport())); 207 provider_->ContextGL(), provider_->ContextSupport()));
208
209 app_status_listener_.reset(new ApplicationStatusListener(base::Bind(
210 &GLHelperHolder::OnApplicationStatusChanged, base::Unretained(this))));
danakj 2016/09/13 22:44:58 Please leave a comment explaining why unretained t
no sievers 2016/09/26 22:19:28 Done.
211 mem_pressure_listener_.reset(new MemoryPressureListener(base::Bind(
212 &GLHelperHolder::OnMemoryPressure, base::Unretained(this))));
danakj 2016/09/13 22:44:58 ditto
no sievers 2016/09/26 22:19:28 Done.
213 }
214
215 void GLHelperHolder::FreeUnusedSharedMemoryIfNeeded() {
216 if (should_aggressively_free_memory_)
217 provider_->FreeUnusedSharedMemory();
186 } 218 }
187 219
188 void GLHelperHolder::OnContextLost() { 220 void GLHelperHolder::OnContextLost() {
221 app_status_listener_.reset();
222 mem_pressure_listener_.reset();
223 provider_->FreeUnusedSharedMemory();
danakj 2016/09/13 22:44:58 What if we just delete the helper instead?
no sievers 2016/09/26 22:19:28 Yes, good idea and it works because IsLost() above
189 // Need to post a task because the command buffer client cannot be deleted 224 // Need to post a task because the command buffer client cannot be deleted
190 // from within this callback. 225 // from within this callback.
191 base::ThreadTaskRunnerHandle::Get()->PostTask( 226 base::ThreadTaskRunnerHandle::Get()->PostTask(
192 FROM_HERE, base::Bind(&RenderWidgetHostViewAndroid::OnContextLost)); 227 FROM_HERE, base::Bind(&RenderWidgetHostViewAndroid::OnContextLost));
193 } 228 }
194 229
195 // This can only be used for readback postprocessing. It may return null if the 230 void GLHelperHolder::OnApplicationStatusChanged(ApplicationState new_state) {
196 // channel was lost and not reestablished yet. 231 bool new_has_running_activities =
197 display_compositor::GLHelper* GetPostReadbackGLHelper() { 232 new_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
233
234 if (!has_running_activities_ && new_has_running_activities) {
235 // Intentionally allow reset at this time even if we previously had a
236 // low memory signal.
237 should_aggressively_free_memory_ = false;
238 } else if (!new_has_running_activities) {
239 should_aggressively_free_memory_ = true;
240 provider_->FreeUnusedSharedMemory();
241 }
242
243 has_running_activities_ = new_has_running_activities;
244 }
245
246 void GLHelperHolder::OnMemoryPressure(
247 MemoryPressureListener::MemoryPressureLevel level) {
248 if (level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE ||
249 level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
250 should_aggressively_free_memory_ = true;
danakj 2016/09/13 22:44:58 I feel weird about 2 functions setting this indepe
no sievers 2016/09/26 22:19:28 Done.
251 provider_->FreeUnusedSharedMemory();
252 }
253 }
254
255 GLHelperHolder* GetPostReadbackGLHelperHolder(bool create_if_necessary) {
198 static GLHelperHolder* g_readback_helper_holder = nullptr; 256 static GLHelperHolder* g_readback_helper_holder = nullptr;
199 257
258 if (!create_if_necessary && !g_readback_helper_holder)
259 return nullptr;
260
200 if (g_readback_helper_holder && g_readback_helper_holder->IsLost()) { 261 if (g_readback_helper_holder && g_readback_helper_holder->IsLost()) {
201 delete g_readback_helper_holder; 262 delete g_readback_helper_holder;
202 g_readback_helper_holder = nullptr; 263 g_readback_helper_holder = nullptr;
203 } 264 }
204 265
205 if (!g_readback_helper_holder) 266 if (!g_readback_helper_holder)
206 g_readback_helper_holder = GLHelperHolder::Create(); 267 g_readback_helper_holder = GLHelperHolder::Create();
207 268
208 return g_readback_helper_holder->gl_helper(); 269 return g_readback_helper_holder;
270 }
271
272 display_compositor::GLHelper* GetPostReadbackGLHelper() {
273 return GetPostReadbackGLHelperHolder(true)->gl_helper();
danakj 2016/09/13 22:44:58 can you put the true into a temp var to give it a
no sievers 2016/09/26 22:19:29 Done.
274 }
275
276 void FreeUnusedGLHelperMemory() {
277 GLHelperHolder* holder = GetPostReadbackGLHelperHolder(false);
danakj 2016/09/13 22:44:58 ditto for false
no sievers 2016/09/26 22:19:28 Done.
278
279 if (holder) {
280 holder->FreeUnusedSharedMemoryIfNeeded();
281 }
209 } 282 }
210 283
211 void CopyFromCompositingSurfaceFinished( 284 void CopyFromCompositingSurfaceFinished(
212 const ReadbackRequestCallback& callback, 285 const ReadbackRequestCallback& callback,
213 std::unique_ptr<cc::SingleReleaseCallback> release_callback, 286 std::unique_ptr<cc::SingleReleaseCallback> release_callback,
214 std::unique_ptr<SkBitmap> bitmap, 287 std::unique_ptr<SkBitmap> bitmap,
215 const base::TimeTicks& start_time, 288 const base::TimeTicks& start_time,
216 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock, 289 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock,
217 bool result) { 290 bool result) {
218 TRACE_EVENT0( 291 TRACE_EVENT0(
219 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished"); 292 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
220 bitmap_pixels_lock.reset(); 293 bitmap_pixels_lock.reset();
221 gpu::SyncToken sync_token; 294 gpu::SyncToken sync_token;
222 if (result) { 295 if (result) {
223 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); 296 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper();
224 if (gl_helper) 297 if (gl_helper)
225 gl_helper->GenerateSyncToken(&sync_token); 298 gl_helper->GenerateSyncToken(&sync_token);
226 } 299 }
300
301 FreeUnusedGLHelperMemory();
danakj 2016/09/13 22:44:58 What if there was more than one copy going?
no sievers 2016/09/26 22:19:28 I think that's fine because it would only free *un
302
227 const bool lost_resource = !sync_token.HasData(); 303 const bool lost_resource = !sync_token.HasData();
228 release_callback->Run(sync_token, lost_resource); 304 release_callback->Run(sync_token, lost_resource);
229 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, 305 UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
230 base::TimeTicks::Now() - start_time); 306 base::TimeTicks::Now() - start_time);
231 ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED; 307 ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED;
232 callback.Run(*bitmap, response); 308 callback.Run(*bitmap, response);
233 } 309 }
234 310
235 std::unique_ptr<ui::TouchSelectionController> CreateSelectionController( 311 std::unique_ptr<ui::TouchSelectionController> CreateSelectionController(
236 ui::TouchSelectionControllerClient* client, 312 ui::TouchSelectionControllerClient* client,
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after
1880 case ui::MotionEvent::ACTION_UP: 1956 case ui::MotionEvent::ACTION_UP:
1881 case ui::MotionEvent::ACTION_POINTER_UP: 1957 case ui::MotionEvent::ACTION_POINTER_UP:
1882 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.OS.TOUCH_RELEASED", 1958 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.OS.TOUCH_RELEASED",
1883 delta.InMicroseconds(), 1, 1000000, 50); 1959 delta.InMicroseconds(), 1, 1000000, 50);
1884 default: 1960 default:
1885 return; 1961 return;
1886 } 1962 }
1887 } 1963 }
1888 1964
1889 } // namespace content 1965 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698