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" |
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/ref_counted.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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 #include "ui/touch_selection/touch_selection_controller.h" | 95 #include "ui/touch_selection/touch_selection_controller.h" |
94 | 96 |
95 namespace content { | 97 namespace content { |
96 | 98 |
97 namespace { | 99 namespace { |
98 | 100 |
99 const int kUndefinedCompositorFrameSinkId = -1; | 101 const int kUndefinedCompositorFrameSinkId = -1; |
100 | 102 |
101 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; | 103 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime"; |
102 | 104 |
| 105 class PendingReadbackLock; |
| 106 |
| 107 PendingReadbackLock* g_pending_readback_lock = nullptr; |
| 108 |
| 109 class PendingReadbackLock : public base::RefCounted<PendingReadbackLock> { |
| 110 public: |
| 111 PendingReadbackLock() { |
| 112 DCHECK_EQ(g_pending_readback_lock, nullptr); |
| 113 g_pending_readback_lock = this; |
| 114 } |
| 115 |
| 116 private: |
| 117 friend class base::RefCounted<PendingReadbackLock>; |
| 118 |
| 119 ~PendingReadbackLock() { |
| 120 DCHECK_EQ(g_pending_readback_lock, this); |
| 121 g_pending_readback_lock = nullptr; |
| 122 } |
| 123 }; |
| 124 |
| 125 using base::android::ApplicationState; |
| 126 using base::android::ApplicationStatusListener; |
| 127 |
103 class GLHelperHolder { | 128 class GLHelperHolder { |
104 public: | 129 public: |
105 static GLHelperHolder* Create(); | 130 static GLHelperHolder* Create(); |
106 | 131 |
107 display_compositor::GLHelper* gl_helper() { return gl_helper_.get(); } | 132 display_compositor::GLHelper* gl_helper() { return gl_helper_.get(); } |
108 bool IsLost() { | 133 bool IsLost() { |
109 if (!gl_helper_) | 134 if (!gl_helper_) |
110 return true; | 135 return true; |
111 return provider_->ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; | 136 return provider_->ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR; |
112 } | 137 } |
113 | 138 |
| 139 void ReleaseIfPossible(); |
| 140 |
114 private: | 141 private: |
115 GLHelperHolder() = default; | 142 GLHelperHolder(); |
116 void Initialize(); | 143 void Initialize(); |
117 void OnContextLost(); | 144 void OnContextLost(); |
| 145 void OnApplicationStatusChanged(ApplicationState new_state); |
118 | 146 |
119 scoped_refptr<ContextProviderCommandBuffer> provider_; | 147 scoped_refptr<ContextProviderCommandBuffer> provider_; |
120 std::unique_ptr<display_compositor::GLHelper> gl_helper_; | 148 std::unique_ptr<display_compositor::GLHelper> gl_helper_; |
121 | 149 |
| 150 // Set to |false| if there are only stopped activities (or none). |
| 151 bool has_running_or_paused_activities_; |
| 152 |
| 153 std::unique_ptr<ApplicationStatusListener> app_status_listener_; |
| 154 |
122 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder); | 155 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder); |
123 }; | 156 }; |
124 | 157 |
| 158 GLHelperHolder::GLHelperHolder() |
| 159 : has_running_or_paused_activities_( |
| 160 (ApplicationStatusListener::GetState() == |
| 161 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) || |
| 162 (ApplicationStatusListener::GetState() == |
| 163 base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES)) {} |
| 164 |
125 GLHelperHolder* GLHelperHolder::Create() { | 165 GLHelperHolder* GLHelperHolder::Create() { |
126 GLHelperHolder* holder = new GLHelperHolder; | 166 GLHelperHolder* holder = new GLHelperHolder; |
127 holder->Initialize(); | 167 holder->Initialize(); |
128 return holder; | 168 return holder; |
129 } | 169 } |
130 | 170 |
131 void GLHelperHolder::Initialize() { | 171 void GLHelperHolder::Initialize() { |
132 auto* factory = BrowserGpuChannelHostFactory::instance(); | 172 auto* factory = BrowserGpuChannelHostFactory::instance(); |
133 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel()); | 173 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel()); |
134 | 174 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 if (!provider_->BindToCurrentThread()) | 217 if (!provider_->BindToCurrentThread()) |
178 return; | 218 return; |
179 provider_->ContextGL()->TraceBeginCHROMIUM( | 219 provider_->ContextGL()->TraceBeginCHROMIUM( |
180 "gpu_toplevel", | 220 "gpu_toplevel", |
181 base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get()) | 221 base::StringPrintf("CmdBufferImageTransportFactory-%p", provider_.get()) |
182 .c_str()); | 222 .c_str()); |
183 provider_->SetLostContextCallback( | 223 provider_->SetLostContextCallback( |
184 base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this))); | 224 base::Bind(&GLHelperHolder::OnContextLost, base::Unretained(this))); |
185 gl_helper_.reset(new display_compositor::GLHelper( | 225 gl_helper_.reset(new display_compositor::GLHelper( |
186 provider_->ContextGL(), provider_->ContextSupport())); | 226 provider_->ContextGL(), provider_->ContextSupport())); |
| 227 |
| 228 // Unretained() is safe because |this| owns the following two callbacks. |
| 229 app_status_listener_.reset(new ApplicationStatusListener(base::Bind( |
| 230 &GLHelperHolder::OnApplicationStatusChanged, base::Unretained(this)))); |
| 231 } |
| 232 |
| 233 void GLHelperHolder::ReleaseIfPossible() { |
| 234 if (!has_running_or_paused_activities_ && !g_pending_readback_lock) { |
| 235 gl_helper_.reset(); |
| 236 provider_ = nullptr; |
| 237 // Make sure this will get recreated on next use. |
| 238 DCHECK(IsLost()); |
| 239 } |
187 } | 240 } |
188 | 241 |
189 void GLHelperHolder::OnContextLost() { | 242 void GLHelperHolder::OnContextLost() { |
| 243 app_status_listener_.reset(); |
| 244 gl_helper_.reset(); |
190 // Need to post a task because the command buffer client cannot be deleted | 245 // Need to post a task because the command buffer client cannot be deleted |
191 // from within this callback. | 246 // from within this callback. |
192 base::ThreadTaskRunnerHandle::Get()->PostTask( | 247 base::ThreadTaskRunnerHandle::Get()->PostTask( |
193 FROM_HERE, base::Bind(&RenderWidgetHostViewAndroid::OnContextLost)); | 248 FROM_HERE, base::Bind(&RenderWidgetHostViewAndroid::OnContextLost)); |
194 } | 249 } |
195 | 250 |
196 // This can only be used for readback postprocessing. It may return null if the | 251 void GLHelperHolder::OnApplicationStatusChanged(ApplicationState new_state) { |
197 // channel was lost and not reestablished yet. | 252 has_running_or_paused_activities_ = |
198 display_compositor::GLHelper* GetPostReadbackGLHelper() { | 253 new_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES || |
| 254 new_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES; |
| 255 ReleaseIfPossible(); |
| 256 } |
| 257 |
| 258 GLHelperHolder* GetPostReadbackGLHelperHolder(bool create_if_necessary) { |
199 static GLHelperHolder* g_readback_helper_holder = nullptr; | 259 static GLHelperHolder* g_readback_helper_holder = nullptr; |
200 | 260 |
| 261 if (!create_if_necessary && !g_readback_helper_holder) |
| 262 return nullptr; |
| 263 |
201 if (g_readback_helper_holder && g_readback_helper_holder->IsLost()) { | 264 if (g_readback_helper_holder && g_readback_helper_holder->IsLost()) { |
202 delete g_readback_helper_holder; | 265 delete g_readback_helper_holder; |
203 g_readback_helper_holder = nullptr; | 266 g_readback_helper_holder = nullptr; |
204 } | 267 } |
205 | 268 |
206 if (!g_readback_helper_holder) | 269 if (!g_readback_helper_holder) |
207 g_readback_helper_holder = GLHelperHolder::Create(); | 270 g_readback_helper_holder = GLHelperHolder::Create(); |
208 | 271 |
209 return g_readback_helper_holder->gl_helper(); | 272 return g_readback_helper_holder; |
| 273 } |
| 274 |
| 275 display_compositor::GLHelper* GetPostReadbackGLHelper() { |
| 276 bool create_if_necessary = true; |
| 277 return GetPostReadbackGLHelperHolder(create_if_necessary)->gl_helper(); |
| 278 } |
| 279 |
| 280 void ReleaseGLHelper() { |
| 281 bool create_if_necessary = false; |
| 282 GLHelperHolder* holder = GetPostReadbackGLHelperHolder(create_if_necessary); |
| 283 |
| 284 if (holder) { |
| 285 holder->ReleaseIfPossible(); |
| 286 } |
210 } | 287 } |
211 | 288 |
212 void CopyFromCompositingSurfaceFinished( | 289 void CopyFromCompositingSurfaceFinished( |
213 const ReadbackRequestCallback& callback, | 290 const ReadbackRequestCallback& callback, |
214 std::unique_ptr<cc::SingleReleaseCallback> release_callback, | 291 std::unique_ptr<cc::SingleReleaseCallback> release_callback, |
215 std::unique_ptr<SkBitmap> bitmap, | 292 std::unique_ptr<SkBitmap> bitmap, |
216 const base::TimeTicks& start_time, | 293 const base::TimeTicks& start_time, |
217 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock, | 294 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock, |
| 295 scoped_refptr<PendingReadbackLock> readback_lock, |
218 bool result) { | 296 bool result) { |
219 TRACE_EVENT0( | 297 TRACE_EVENT0( |
220 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished"); | 298 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished"); |
221 bitmap_pixels_lock.reset(); | 299 bitmap_pixels_lock.reset(); |
222 gpu::SyncToken sync_token; | 300 gpu::SyncToken sync_token; |
223 if (result) { | 301 if (result) { |
224 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); | 302 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); |
225 if (gl_helper) | 303 if (gl_helper) |
226 gl_helper->GenerateSyncToken(&sync_token); | 304 gl_helper->GenerateSyncToken(&sync_token); |
227 } | 305 } |
| 306 |
| 307 // PostTask() to make sure the |readback_lock| is released. Also do this |
| 308 // synchronous GPU operation in a clean callstack. |
| 309 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 310 base::Bind(&ReleaseGLHelper)); |
| 311 |
228 const bool lost_resource = !sync_token.HasData(); | 312 const bool lost_resource = !sync_token.HasData(); |
229 release_callback->Run(sync_token, lost_resource); | 313 release_callback->Run(sync_token, lost_resource); |
230 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, | 314 UMA_HISTOGRAM_TIMES(kAsyncReadBackString, |
231 base::TimeTicks::Now() - start_time); | 315 base::TimeTicks::Now() - start_time); |
232 ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED; | 316 ReadbackResponse response = result ? READBACK_SUCCESS : READBACK_FAILED; |
233 callback.Run(*bitmap, response); | 317 callback.Run(*bitmap, response); |
234 } | 318 } |
235 | 319 |
236 std::unique_ptr<ui::TouchSelectionController> CreateSelectionController( | 320 std::unique_ptr<ui::TouchSelectionController> CreateSelectionController( |
237 ui::TouchSelectionControllerClient* client, | 321 ui::TouchSelectionControllerClient* client, |
(...skipping 23 matching lines...) Expand all Loading... |
261 gfx::RectF GetSelectionRect(const ui::TouchSelectionController& controller) { | 345 gfx::RectF GetSelectionRect(const ui::TouchSelectionController& controller) { |
262 gfx::RectF rect = controller.GetRectBetweenBounds(); | 346 gfx::RectF rect = controller.GetRectBetweenBounds(); |
263 if (rect.IsEmpty()) | 347 if (rect.IsEmpty()) |
264 return rect; | 348 return rect; |
265 | 349 |
266 rect.Union(controller.GetStartHandleRect()); | 350 rect.Union(controller.GetStartHandleRect()); |
267 rect.Union(controller.GetEndHandleRect()); | 351 rect.Union(controller.GetEndHandleRect()); |
268 return rect; | 352 return rect; |
269 } | 353 } |
270 | 354 |
271 } // anonymous namespace | 355 // TODO(wjmaclean): There is significant overlap between |
| 356 // PrepareTextureCopyOutputResult and CopyFromCompositingSurfaceFinished in |
| 357 // this file, and the versions in surface_utils.cc. They should |
| 358 // be merged. See https://crbug.com/582955 |
| 359 void PrepareTextureCopyOutputResult( |
| 360 const gfx::Size& dst_size_in_pixel, |
| 361 SkColorType color_type, |
| 362 const base::TimeTicks& start_time, |
| 363 const ReadbackRequestCallback& callback, |
| 364 scoped_refptr<PendingReadbackLock> readback_lock, |
| 365 std::unique_ptr<cc::CopyOutputResult> result) { |
| 366 base::ScopedClosureRunner scoped_callback_runner( |
| 367 base::Bind(callback, SkBitmap(), READBACK_FAILED)); |
| 368 TRACE_EVENT0("cc", |
| 369 "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult"); |
| 370 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) |
| 371 return; |
| 372 cc::TextureMailbox texture_mailbox; |
| 373 std::unique_ptr<cc::SingleReleaseCallback> release_callback; |
| 374 result->TakeTexture(&texture_mailbox, &release_callback); |
| 375 DCHECK(texture_mailbox.IsTexture()); |
| 376 if (!texture_mailbox.IsTexture()) |
| 377 return; |
| 378 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); |
| 379 if (!gl_helper) |
| 380 return; |
| 381 if (!gl_helper->IsReadbackConfigSupported(color_type)) |
| 382 color_type = kRGBA_8888_SkColorType; |
| 383 |
| 384 gfx::Size output_size_in_pixel; |
| 385 if (dst_size_in_pixel.IsEmpty()) |
| 386 output_size_in_pixel = result->size(); |
| 387 else |
| 388 output_size_in_pixel = dst_size_in_pixel; |
| 389 |
| 390 std::unique_ptr<SkBitmap> bitmap(new SkBitmap); |
| 391 if (!bitmap->tryAllocPixels(SkImageInfo::Make(output_size_in_pixel.width(), |
| 392 output_size_in_pixel.height(), |
| 393 color_type, |
| 394 kOpaque_SkAlphaType))) { |
| 395 scoped_callback_runner.ReplaceClosure( |
| 396 base::Bind(callback, SkBitmap(), READBACK_BITMAP_ALLOCATION_FAILURE)); |
| 397 return; |
| 398 } |
| 399 |
| 400 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock( |
| 401 new SkAutoLockPixels(*bitmap)); |
| 402 uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels()); |
| 403 |
| 404 ignore_result(scoped_callback_runner.Release()); |
| 405 |
| 406 gl_helper->CropScaleReadbackAndCleanMailbox( |
| 407 texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(), |
| 408 gfx::Rect(result->size()), output_size_in_pixel, pixels, color_type, |
| 409 base::Bind(&CopyFromCompositingSurfaceFinished, callback, |
| 410 base::Passed(&release_callback), base::Passed(&bitmap), |
| 411 start_time, base::Passed(&bitmap_pixels_lock), readback_lock), |
| 412 display_compositor::GLHelper::SCALER_QUALITY_GOOD); |
| 413 } |
| 414 |
| 415 } // namespace |
272 | 416 |
273 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo( | 417 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo( |
274 uint32_t compositor_frame_sink_id, | 418 uint32_t compositor_frame_sink_id, |
275 cc::CompositorFrame output_frame) | 419 cc::CompositorFrame output_frame) |
276 : compositor_frame_sink_id(compositor_frame_sink_id), | 420 : compositor_frame_sink_id(compositor_frame_sink_id), |
277 frame(std::move(output_frame)) {} | 421 frame(std::move(output_frame)) {} |
278 | 422 |
279 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {} | 423 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {} |
280 | 424 |
281 void RenderWidgetHostViewAndroid::OnContextLost() { | 425 void RenderWidgetHostViewAndroid::OnContextLost() { |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 preferred_color_type); | 1001 preferred_color_type); |
858 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous", | 1002 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous", |
859 base::TimeTicks::Now() - start_time); | 1003 base::TimeTicks::Now() - start_time); |
860 return; | 1004 return; |
861 } | 1005 } |
862 | 1006 |
863 ui::WindowAndroidCompositor* compositor = | 1007 ui::WindowAndroidCompositor* compositor = |
864 content_view_core_->GetWindowAndroid()->GetCompositor(); | 1008 content_view_core_->GetWindowAndroid()->GetCompositor(); |
865 DCHECK(compositor); | 1009 DCHECK(compositor); |
866 DCHECK(delegated_frame_host_); | 1010 DCHECK(delegated_frame_host_); |
| 1011 scoped_refptr<PendingReadbackLock> readback_lock( |
| 1012 g_pending_readback_lock ? g_pending_readback_lock |
| 1013 : new PendingReadbackLock); |
867 delegated_frame_host_->RequestCopyOfSurface( | 1014 delegated_frame_host_->RequestCopyOfSurface( |
868 compositor, src_subrect_in_pixel, | 1015 compositor, src_subrect_in_pixel, |
869 base::Bind(&PrepareTextureCopyOutputResult, dst_size_in_pixel, | 1016 base::Bind(&PrepareTextureCopyOutputResult, dst_size_in_pixel, |
870 preferred_color_type, start_time, callback)); | 1017 preferred_color_type, start_time, callback, readback_lock)); |
871 } | 1018 } |
872 | 1019 |
873 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame( | 1020 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame( |
874 const gfx::Rect& src_subrect, | 1021 const gfx::Rect& src_subrect, |
875 const scoped_refptr<media::VideoFrame>& target, | 1022 const scoped_refptr<media::VideoFrame>& target, |
876 const base::Callback<void(const gfx::Rect&, bool)>& callback) { | 1023 const base::Callback<void(const gfx::Rect&, bool)>& callback) { |
877 NOTIMPLEMENTED(); | 1024 NOTIMPLEMENTED(); |
878 callback.Run(gfx::Rect(), false); | 1025 callback.Run(gfx::Rect(), false); |
879 } | 1026 } |
880 | 1027 |
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 is_window_activity_started_ = true; | 1931 is_window_activity_started_ = true; |
1785 ShowInternal(); | 1932 ShowInternal(); |
1786 } | 1933 } |
1787 | 1934 |
1788 void RenderWidgetHostViewAndroid::OnLostResources() { | 1935 void RenderWidgetHostViewAndroid::OnLostResources() { |
1789 ReleaseLocksOnSurface(); | 1936 ReleaseLocksOnSurface(); |
1790 DestroyDelegatedContent(); | 1937 DestroyDelegatedContent(); |
1791 DCHECK(ack_callbacks_.empty()); | 1938 DCHECK(ack_callbacks_.empty()); |
1792 } | 1939 } |
1793 | 1940 |
1794 // TODO(wjmaclean): There is significant overlap between | |
1795 // PrepareTextureCopyOutputResult and CopyFromCompositingSurfaceFinished in | |
1796 // this file, and the versions in surface_utils.cc. They should | |
1797 // be merged. See https://crbug.com/582955 | |
1798 | |
1799 // static | |
1800 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( | |
1801 const gfx::Size& dst_size_in_pixel, | |
1802 SkColorType color_type, | |
1803 const base::TimeTicks& start_time, | |
1804 const ReadbackRequestCallback& callback, | |
1805 std::unique_ptr<cc::CopyOutputResult> result) { | |
1806 base::ScopedClosureRunner scoped_callback_runner( | |
1807 base::Bind(callback, SkBitmap(), READBACK_FAILED)); | |
1808 TRACE_EVENT0("cc", | |
1809 "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult"); | |
1810 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) | |
1811 return; | |
1812 cc::TextureMailbox texture_mailbox; | |
1813 std::unique_ptr<cc::SingleReleaseCallback> release_callback; | |
1814 result->TakeTexture(&texture_mailbox, &release_callback); | |
1815 DCHECK(texture_mailbox.IsTexture()); | |
1816 if (!texture_mailbox.IsTexture()) | |
1817 return; | |
1818 display_compositor::GLHelper* gl_helper = GetPostReadbackGLHelper(); | |
1819 if (!gl_helper) | |
1820 return; | |
1821 if (!gl_helper->IsReadbackConfigSupported(color_type)) | |
1822 color_type = kRGBA_8888_SkColorType; | |
1823 | |
1824 gfx::Size output_size_in_pixel; | |
1825 if (dst_size_in_pixel.IsEmpty()) | |
1826 output_size_in_pixel = result->size(); | |
1827 else | |
1828 output_size_in_pixel = dst_size_in_pixel; | |
1829 | |
1830 std::unique_ptr<SkBitmap> bitmap(new SkBitmap); | |
1831 if (!bitmap->tryAllocPixels(SkImageInfo::Make(output_size_in_pixel.width(), | |
1832 output_size_in_pixel.height(), | |
1833 color_type, | |
1834 kOpaque_SkAlphaType))) { | |
1835 scoped_callback_runner.ReplaceClosure( | |
1836 base::Bind(callback, SkBitmap(), READBACK_BITMAP_ALLOCATION_FAILURE)); | |
1837 return; | |
1838 } | |
1839 | |
1840 std::unique_ptr<SkAutoLockPixels> bitmap_pixels_lock( | |
1841 new SkAutoLockPixels(*bitmap)); | |
1842 uint8_t* pixels = static_cast<uint8_t*>(bitmap->getPixels()); | |
1843 | |
1844 ignore_result(scoped_callback_runner.Release()); | |
1845 | |
1846 gl_helper->CropScaleReadbackAndCleanMailbox( | |
1847 texture_mailbox.mailbox(), texture_mailbox.sync_token(), result->size(), | |
1848 gfx::Rect(result->size()), output_size_in_pixel, pixels, color_type, | |
1849 base::Bind(&CopyFromCompositingSurfaceFinished, callback, | |
1850 base::Passed(&release_callback), base::Passed(&bitmap), | |
1851 start_time, base::Passed(&bitmap_pixels_lock)), | |
1852 display_compositor::GLHelper::SCALER_QUALITY_GOOD); | |
1853 } | |
1854 | |
1855 void RenderWidgetHostViewAndroid::OnStylusSelectBegin(float x0, | 1941 void RenderWidgetHostViewAndroid::OnStylusSelectBegin(float x0, |
1856 float y0, | 1942 float y0, |
1857 float x1, | 1943 float x1, |
1858 float y1) { | 1944 float y1) { |
1859 SelectBetweenCoordinates(gfx::PointF(x0, y0), gfx::PointF(x1, y1)); | 1945 SelectBetweenCoordinates(gfx::PointF(x0, y0), gfx::PointF(x1, y1)); |
1860 } | 1946 } |
1861 | 1947 |
1862 void RenderWidgetHostViewAndroid::OnStylusSelectUpdate(float x, float y) { | 1948 void RenderWidgetHostViewAndroid::OnStylusSelectUpdate(float x, float y) { |
1863 MoveRangeSelectionExtent(gfx::PointF(x, y)); | 1949 MoveRangeSelectionExtent(gfx::PointF(x, y)); |
1864 } | 1950 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 case ui::MotionEvent::ACTION_UP: | 1982 case ui::MotionEvent::ACTION_UP: |
1897 case ui::MotionEvent::ACTION_POINTER_UP: | 1983 case ui::MotionEvent::ACTION_POINTER_UP: |
1898 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.OS.TOUCH_RELEASED", | 1984 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.OS.TOUCH_RELEASED", |
1899 delta.InMicroseconds(), 1, 1000000, 50); | 1985 delta.InMicroseconds(), 1, 1000000, 50); |
1900 default: | 1986 default: |
1901 return; | 1987 return; |
1902 } | 1988 } |
1903 } | 1989 } |
1904 | 1990 |
1905 } // namespace content | 1991 } // namespace content |
OLD | NEW |