OLD | NEW |
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" | |
12 #include "base/android/build_info.h" | 11 #include "base/android/build_info.h" |
13 #include "base/android/context_utils.h" | 12 #include "base/android/context_utils.h" |
14 #include "base/bind.h" | 13 #include "base/bind.h" |
15 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
16 #include "base/command_line.h" | 15 #include "base/command_line.h" |
17 #include "base/location.h" | 16 #include "base/location.h" |
18 #include "base/logging.h" | 17 #include "base/logging.h" |
19 #include "base/macros.h" | 18 #include "base/macros.h" |
20 #include "base/memory/memory_pressure_listener.h" | |
21 #include "base/metrics/histogram_macros.h" | 19 #include "base/metrics/histogram_macros.h" |
22 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
23 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
24 #include "base/sys_info.h" | 22 #include "base/sys_info.h" |
25 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
26 #include "base/threading/worker_pool.h" | 24 #include "base/threading/worker_pool.h" |
27 #include "cc/layers/layer.h" | 25 #include "cc/layers/layer.h" |
28 #include "cc/layers/surface_layer.h" | 26 #include "cc/layers/surface_layer.h" |
29 #include "cc/output/compositor_frame.h" | 27 #include "cc/output/compositor_frame.h" |
30 #include "cc/output/copy_output_request.h" | 28 #include "cc/output/copy_output_request.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 #include "ui/touch_selection/touch_selection_controller.h" | 93 #include "ui/touch_selection/touch_selection_controller.h" |
96 | 94 |
97 namespace content { | 95 namespace content { |
98 | 96 |
99 namespace { | 97 namespace { |
100 | 98 |
101 const int kUndefinedCompositorFrameSinkId = -1; | 99 const int kUndefinedCompositorFrameSinkId = -1; |
102 | 100 |
103 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; | 101 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; |
104 | 102 |
105 using base::android::ApplicationState; | |
106 using base::android::ApplicationStatusListener; | |
107 using base::MemoryPressureListener; | |
108 | |
109 class GLHelperHolder { | 103 class GLHelperHolder { |
110 public: | 104 public: |
111 static GLHelperHolder* Create(); | 105 static GLHelperHolder* Create(); |
112 | 106 |
113 display_compositor::GLHelper* gl_helper() { return gl_helper_.get(); } | 107 display_compositor::GLHelper* gl_helper() { return gl_helper_.get(); } |
114 bool IsLost() { | 108 bool IsLost() { |
115 if (!gl_helper_) | 109 if (!gl_helper_) |
116 return true; | 110 return true; |
117 return provider_->ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; | 111 return provider_->ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; |
118 } | 112 } |
119 | 113 |
120 void FreeUnusedSharedMemoryIfNeeded(); | |
121 | |
122 private: | 114 private: |
123 GLHelperHolder(); | 115 GLHelperHolder() = default; |
124 void Initialize(); | 116 void Initialize(); |
125 void OnContextLost(); | 117 void OnContextLost(); |
126 void OnApplicationStatusChanged(ApplicationState new_state); | |
127 void OnMemoryPressure(MemoryPressureListener::MemoryPressureLevel level); | |
128 | 118 |
129 scoped_refptr<ContextProviderCommandBuffer> provider_; | 119 scoped_refptr<ContextProviderCommandBuffer> provider_; |
130 std::unique_ptr<display_compositor::GLHelper> gl_helper_; | 120 std::unique_ptr<display_compositor::GLHelper> gl_helper_; |
131 | 121 |
132 // Set to |false| if there are only stopped activities (or none). | |
133 bool has_running_or_paused_activities_; | |
134 // Whether we recently were signaled a low memory condition. | |
135 bool did_signal_memory_pressure_; | |
136 | |
137 std::unique_ptr<ApplicationStatusListener> app_status_listener_; | |
138 std::unique_ptr<MemoryPressureListener> mem_pressure_listener_; | |
139 | |
140 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder); | 122 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder); |
141 }; | 123 }; |
142 | 124 |
143 GLHelperHolder::GLHelperHolder() | |
144 : has_running_or_paused_activities_( | |
145 (ApplicationStatusListener::GetState() == | |
146 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) || | |
147 (ApplicationStatusListener::GetState() == | |
148 base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES)), | |
149 did_signal_memory_pressure_(false) {} | |
150 | |
151 GLHelperHolder* GLHelperHolder::Create() { | 125 GLHelperHolder* GLHelperHolder::Create() { |
152 GLHelperHolder* holder = new GLHelperHolder; | 126 GLHelperHolder* holder = new GLHelperHolder; |
153 holder->Initialize(); | 127 holder->Initialize(); |
154 return holder; | 128 return holder; |
155 } | 129 } |
156 | 130 |
157 void GLHelperHolder::Initialize() { | 131 void GLHelperHolder::Initialize() { |
158 auto* factory = BrowserGpuChannelHostFactory::instance(); | 132 auto* factory = BrowserGpuChannelHostFactory::instance(); |
159 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel()); | 133 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel()); |
160 | 134 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 if (!provider_->BindToCurrentThread()) | 177 if (!provider_->BindToCurrentThread()) |
204 return; | 178 return; |
205 provider_->ContextGL()->TraceBeginCHROMIUM( | 179 provider_->ContextGL()->TraceBeginCHROMIUM( |
206 "gpu_toplevel", | 180 "gpu_toplevel", |
207 base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get()) | 181 base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get()) |
208 .c_str()); | 182 .c_str()); |
209 provider_->SetLostContextCallback( | 183 provider_->SetLostContextCallback( |
210 base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this))); | 184 base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this))); |
211 gl_helper_.reset(new display_compositor::GLHelper( | 185 gl_helper_.reset(new display_compositor::GLHelper( |
212 provider_->ContextGL(), provider_->ContextSupport())); | 186 provider_->ContextGL(), provider_->ContextSupport())); |
213 | |
214 // Unretained() is safe because |this| owns the following two callbacks. | |
215 app_status_listener_.reset(new ApplicationStatusListener(base::Bind( | |
216 &GLHelperHolder::OnApplicationStatusChanged, base::Unretained(this)))); | |
217 mem_pressure_listener_.reset(new MemoryPressureListener(base::Bind( | |
218 &GLHelperHolder::OnMemoryPressure, base::Unretained(this)))); | |
219 } | |
220 | |
221 void GLHelperHolder::FreeUnusedSharedMemoryIfNeeded() { | |
222 if (!has_running_or_paused_activities_ || did_signal_memory_pressure_) | |
223 provider_->FreeUnusedSharedMemory(); | |
224 } | 187 } |
225 | 188 |
226 void GLHelperHolder::OnContextLost() { | 189 void GLHelperHolder::OnContextLost() { |
227 app_status_listener_.reset(); | |
228 mem_pressure_listener_.reset(); | |
229 gl_helper_.reset(); | |
230 // Need to post a task because the command buffer client cannot be deleted | 190 // Need to post a task because the command buffer client cannot be deleted |
231 // from within this callback. | 191 // from within this callback. |
232 base::ThreadTaskRunnerHandle::Get()->PostTask( | 192 base::ThreadTaskRunnerHandle::Get()->PostTask( |
233 FROM_HERE, base::Bind(&RenderWidgetHostViewAndroid::OnContextLost)); | 193 FROM_HERE, base::Bind(&RenderWidgetHostViewAndroid::OnContextLost)); |
234 } | 194 } |
235 | 195 |
236 void GLHelperHolder::OnApplicationStatusChanged(ApplicationState new_state) { | 196 // This can only be used for readback postprocessing. It may return null if the |
237 bool new_has_running_or_paused_activities = | 197 // channel was lost and not reestablished yet. |
238 new_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES || | 198 display_compositor::GLHelper* GetPostReadbackGLHelper() { |
239 new_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES; | |
240 | |
241 if (!has_running_or_paused_activities_ && | |
242 new_has_running_or_paused_activities) { | |
243 // Reset at this time since on Android there is no 'back to normal' | |
244 // notification (but only onTrim/onLowMemory). | |
245 did_signal_memory_pressure_ = false; | |
246 } else if (!new_has_running_or_paused_activities) { | |
247 provider_->FreeUnusedSharedMemory(); | |
248 } | |
249 | |
250 has_running_or_paused_activities_ = new_has_running_or_paused_activities; | |
251 } | |
252 | |
253 void GLHelperHolder::OnMemoryPressure( | |
254 MemoryPressureListener::MemoryPressureLevel level) { | |
255 if (level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE || | |
256 level == MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) { | |
257 did_signal_memory_pressure_ = true; | |
258 provider_->FreeUnusedSharedMemory(); | |
259 } | |
260 } | |
261 | |
262 GLHelperHolder* GetPostReadbackGLHelperHolder(bool create_if_necessary) { | |
263 static GLHelperHolder* g_readback_helper_holder = nullptr; | 199 static GLHelperHolder* g_readback_helper_holder = nullptr; |
264 | 200 |
265 if (!create_if_necessary && !g_readback_helper_holder) | |
266 return nullptr; | |
267 | |
268 if (g_readback_helper_holder && g_readback_helper_holder->IsLost()) { | 201 if (g_readback_helper_holder && g_readback_helper_holder->IsLost()) { |
269 delete g_readback_helper_holder; | 202 delete g_readback_helper_holder; |
270 g_readback_helper_holder = nullptr; | 203 g_readback_helper_holder = nullptr; |
271 } | 204 } |
272 | 205 |
273 if (!g_readback_helper_holder) | 206 if (!g_readback_helper_holder) |
274 g_readback_helper_holder = GLHelperHolder::Create(); | 207 g_readback_helper_holder = GLHelperHolder::Create(); |
275 | 208 |
276 return g_readback_helper_holder; | 209 return g_readback_helper_holder->gl_helper(); |
277 } | |
278 | |
279 display_compositor::GLHelper* GetPostReadbackGLHelper() { | |
280 bool create_if_necessary = true; | |
281 return GetPostReadbackGLHelperHolder(create_if_necessary)->gl_helper(); | |
282 } | |
283 | |
284 void FreeUnusedGLHelperMemory() { | |
285 bool create_if_necessary = false; | |
286 GLHelperHolder* holder = GetPostReadbackGLHelperHolder(create_if_necessary); | |
287 | |
288 if (holder) { | |
289 holder->FreeUnusedSharedMemoryIfNeeded(); | |
290 } | |
291 } | 210 } |
292 | 211 |
293 void CopyFromCompositingSurfaceFinished( | 212 void CopyFromCompositingSurfaceFinished( |
294 const ReadbackRequestCallback& callback, | 213 const ReadbackRequestCallback& callback, |
295 std::unique_ptr<cc::SingleReleaseCallback> release_callback, | 214 std::unique_ptr<cc::SingleReleaseCallback> release_callback, |
296 std::unique_ptr<SkBitmap> bitmap, | 215 std::unique_ptr<SkBitmap> bitmap, |
297 const base::TimeTicks& start_time, | 216 const base::TimeTicks& start_time, |
298 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 217 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
299 bool result) { | 218 bool result) { |
300 TRACE_EVENT0( | 219 TRACE_EVENT0( |
301 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished"); | 220 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished"); |
302 bitmap_pixels_lock.reset(); | 221 bitmap_pixels_lock.reset(); |
303 gpu::SyncToken sync_token; | 222 gpu::SyncToken sync_token; |
304 if (result) { | 223 if (result) { |
305 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); | 224 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); |
306 if (gl_helper) | 225 if (gl_helper) |
307 gl_helper->GenerateSyncToken(&sync_token); | 226 gl_helper->GenerateSyncToken(&sync_token); |
308 } | 227 } |
309 | |
310 FreeUnusedGLHelperMemory(); | |
311 | |
312 const bool lost_resource = !sync_token.HasData(); | 228 const bool lost_resource = !sync_token.HasData(); |
313 release_callback->Run(sync_token, lost_resource); | 229 release_callback->Run(sync_token, lost_resource); |
314 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, | 230 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, |
315 base::TimeTicks::Now() - start_time); | 231 base::TimeTicks::Now() - start_time); |
316 ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED; | 232 ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED; |
317 callback.Run(*bitmap, response); | 233 callback.Run(*bitmap, response); |
318 } | 234 } |
319 | 235 |
320 std::unique_ptr<ui::TouchSelectionController> CreateSelectionController( | 236 std::unique_ptr<ui::TouchSelectionController> CreateSelectionController( |
321 ui::TouchSelectionControllerClient* client, | 237 ui::TouchSelectionControllerClient* client, |
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1964 case ui::MotionEvent::ACTION_UP: | 1880 case ui::MotionEvent::ACTION_UP: |
1965 case ui::MotionEvent::ACTION_POINTER_UP: | 1881 case ui::MotionEvent::ACTION_POINTER_UP: |
1966 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.OS.TOUCH_RELEASED", | 1882 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.OS.TOUCH_RELEASED", |
1967 delta.InMicroseconds(), 1, 1000000, 50); | 1883 delta.InMicroseconds(), 1, 1000000, 50); |
1968 default: | 1884 default: |
1969 return; | 1885 return; |
1970 } | 1886 } |
1971 } | 1887 } |
1972 | 1888 |
1973 } // namespace content | 1889 } // namespace content |
OLD | NEW |