OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/in_process_view_renderer.h" | 5 #include "android_webview/browser/in_process_view_renderer.h" |
6 | 6 |
7 #include <android/bitmap.h> | 7 #include <android/bitmap.h> |
8 | 8 |
9 #include "android_webview/browser/aw_gl_surface.h" | 9 #include "android_webview/browser/aw_gl_surface.h" |
10 #include "android_webview/browser/scoped_app_gl_state_restore.h" | 10 #include "android_webview/browser/scoped_app_gl_state_restore.h" |
11 #include "android_webview/common/aw_switches.h" | 11 #include "android_webview/common/aw_switches.h" |
12 #include "android_webview/public/browser/draw_gl.h" | 12 #include "android_webview/public/browser/draw_gl.h" |
13 #include "android_webview/public/browser/draw_sw.h" | 13 #include "android_webview/public/browser/draw_sw.h" |
14 #include "base/android/jni_android.h" | 14 #include "base/android/jni_android.h" |
15 #include "base/auto_reset.h" | 15 #include "base/auto_reset.h" |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
17 #include "base/debug/trace_event.h" | 17 #include "base/debug/trace_event.h" |
18 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
22 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
23 #include "content/public/browser/web_contents.h" | 23 #include "content/public/browser/web_contents.h" |
24 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
25 #include "gpu/command_buffer/service/in_process_command_buffer.h" | |
26 #include "third_party/skia/include/core/SkBitmap.h" | 25 #include "third_party/skia/include/core/SkBitmap.h" |
27 #include "third_party/skia/include/core/SkBitmapDevice.h" | 26 #include "third_party/skia/include/core/SkBitmapDevice.h" |
28 #include "third_party/skia/include/core/SkCanvas.h" | 27 #include "third_party/skia/include/core/SkCanvas.h" |
29 #include "third_party/skia/include/core/SkGraphics.h" | 28 #include "third_party/skia/include/core/SkGraphics.h" |
30 #include "third_party/skia/include/core/SkPicture.h" | 29 #include "third_party/skia/include/core/SkPicture.h" |
31 #include "third_party/skia/include/utils/SkCanvasStateUtils.h" | 30 #include "third_party/skia/include/utils/SkCanvasStateUtils.h" |
32 #include "ui/gfx/skia_util.h" | 31 #include "ui/gfx/skia_util.h" |
33 #include "ui/gfx/transform.h" | 32 #include "ui/gfx/transform.h" |
34 #include "ui/gfx/vector2d_conversions.h" | 33 #include "ui/gfx/vector2d_conversions.h" |
35 #include "ui/gfx/vector2d_f.h" | 34 #include "ui/gfx/vector2d_f.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 InProcessViewRenderer* renderer = static_cast<InProcessViewRenderer*>( | 184 InProcessViewRenderer* renderer = static_cast<InProcessViewRenderer*>( |
186 g_view_renderer_manager.Get().GetMostRecentlyDrawn()); | 185 g_view_renderer_manager.Get().GetMostRecentlyDrawn()); |
187 if (!renderer || !renderer->RequestProcessGL()) { | 186 if (!renderer || !renderer->RequestProcessGL()) { |
188 LOG(ERROR) << "Failed to request GL process. Deadlock likely: " | 187 LOG(ERROR) << "Failed to request GL process. Deadlock likely: " |
189 << !!renderer; | 188 << !!renderer; |
190 } | 189 } |
191 } | 190 } |
192 | 191 |
193 } // namespace | 192 } // namespace |
194 | 193 |
194 DeferredGpuCommandService::DeferredGpuCommandService() {} | |
195 | |
196 DeferredGpuCommandService::~DeferredGpuCommandService() { | |
197 base::AutoLock lock(tasks_lock_); | |
198 DCHECK(tasks_.empty()); | |
199 } | |
200 | |
195 // Called from different threads! | 201 // Called from different threads! |
196 static void ScheduleGpuWork() { | 202 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) { |
197 if (ScopedAllowGL::IsAllowed()) { | 203 if (ScopedAllowGL::IsAllowed()) { |
198 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 204 task.Run(); |
199 } else { | 205 } else { |
206 base::AutoLock lock(tasks_lock_); | |
207 tasks_.push(task); | |
200 RequestProcessGLOnUIThread(); | 208 RequestProcessGLOnUIThread(); |
201 } | 209 } |
202 } | 210 } |
203 | 211 |
212 void DeferredGpuCommandService::ScheduleIdleWork(const base::Closure& callback) { | |
213 // TODO(sievers): Should this do anything? | |
boliu
2014/02/08 18:55:54
We can make this work, if it's needed.
| |
214 } | |
215 | |
216 void DeferredGpuCommandService::RunTasks() { | |
217 size_t num_tasks; | |
boliu
2014/02/08 18:55:54
bool has_more_tasks?
no sievers
2014/02/12 03:09:15
Done.
| |
218 { | |
219 base::AutoLock lock(tasks_lock_); | |
boliu
2014/02/08 18:55:54
Do we need a lock? We are single threaded here :)
no sievers
2014/02/12 03:09:15
Yes, because of the video context which queues tas
| |
220 num_tasks = tasks_.size(); | |
221 } | |
222 | |
223 while (num_tasks) { | |
224 base::Closure task; | |
225 { | |
226 base::AutoLock lock(tasks_lock_); | |
227 task = tasks_.front(); | |
228 tasks_.pop(); | |
229 } | |
230 task.Run(); | |
231 { | |
232 base::AutoLock lock(tasks_lock_); | |
233 num_tasks = tasks_.size(); | |
234 } | |
235 | |
236 } | |
237 } | |
238 | |
204 // static | 239 // static |
205 void BrowserViewRenderer::SetAwDrawSWFunctionTable( | 240 void BrowserViewRenderer::SetAwDrawSWFunctionTable( |
206 AwDrawSWFunctionTable* table) { | 241 AwDrawSWFunctionTable* table) { |
207 g_sw_draw_functions = table; | 242 g_sw_draw_functions = table; |
208 gpu::InProcessCommandBuffer::SetScheduleCallback( | |
209 base::Bind(&ScheduleGpuWork)); | |
210 } | 243 } |
211 | 244 |
212 // static | 245 // static |
213 AwDrawSWFunctionTable* BrowserViewRenderer::GetAwDrawSWFunctionTable() { | 246 AwDrawSWFunctionTable* BrowserViewRenderer::GetAwDrawSWFunctionTable() { |
214 return g_sw_draw_functions; | 247 return g_sw_draw_functions; |
215 } | 248 } |
216 | 249 |
217 InProcessViewRenderer::InProcessViewRenderer( | 250 InProcessViewRenderer::InProcessViewRenderer( |
218 BrowserViewRenderer::Client* client, | 251 BrowserViewRenderer::Client* client, |
219 JavaHelper* java_helper, | 252 JavaHelper* java_helper, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 // normal levels in the next DrawGL call. | 377 // normal levels in the next DrawGL call. |
345 content::SynchronousCompositorMemoryPolicy policy; | 378 content::SynchronousCompositorMemoryPolicy policy; |
346 policy.bytes_limit = 0; | 379 policy.bytes_limit = 0; |
347 policy.num_resources_limit = 0; | 380 policy.num_resources_limit = 0; |
348 if (memory_policy_ == policy) | 381 if (memory_policy_ == policy) |
349 return; | 382 return; |
350 | 383 |
351 TRACE_EVENT0("android_webview", "InProcessViewRenderer::TrimMemory"); | 384 TRACE_EVENT0("android_webview", "InProcessViewRenderer::TrimMemory"); |
352 ScopedAppGLStateRestore state_restore( | 385 ScopedAppGLStateRestore state_restore( |
353 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | 386 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); |
354 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 387 gl_queue_->RunTasks(); |
355 ScopedAllowGL allow_gl; | 388 ScopedAllowGL allow_gl; |
356 | 389 |
357 SetMemoryPolicy(policy); | 390 SetMemoryPolicy(policy); |
358 ForceFakeCompositeSW(); | 391 ForceFakeCompositeSW(); |
359 } | 392 } |
360 | 393 |
361 void InProcessViewRenderer::SetMemoryPolicy( | 394 void InProcessViewRenderer::SetMemoryPolicy( |
362 content::SynchronousCompositorMemoryPolicy& new_policy) { | 395 content::SynchronousCompositorMemoryPolicy& new_policy) { |
363 if (memory_policy_ == new_policy) | 396 if (memory_policy_ == new_policy) |
364 return; | 397 return; |
(...skipping 20 matching lines...) Expand all Loading... | |
385 return compositor_ && client_->RequestDrawGL(java_canvas); | 418 return compositor_ && client_->RequestDrawGL(java_canvas); |
386 } | 419 } |
387 // Perform a software draw | 420 // Perform a software draw |
388 return DrawSWInternal(java_canvas, clip); | 421 return DrawSWInternal(java_canvas, clip); |
389 } | 422 } |
390 | 423 |
391 bool InProcessViewRenderer::InitializeHwDraw() { | 424 bool InProcessViewRenderer::InitializeHwDraw() { |
392 TRACE_EVENT0("android_webview", "InitializeHwDraw"); | 425 TRACE_EVENT0("android_webview", "InitializeHwDraw"); |
393 DCHECK(!gl_surface_); | 426 DCHECK(!gl_surface_); |
394 gl_surface_ = new AwGLSurface; | 427 gl_surface_ = new AwGLSurface; |
395 hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_); | 428 gl_queue_ = new DeferredGpuCommandQueue; |
429 hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_, gl_queue_); | |
396 hardware_initialized_ = true; | 430 hardware_initialized_ = true; |
397 | 431 |
398 if (hardware_failed_) | 432 if (hardware_failed_) { |
399 gl_surface_ = NULL; | 433 gl_surface_ = NULL; |
434 gl_queue_ = NULL; | |
435 } | |
400 | 436 |
401 return !hardware_failed_; | 437 return !hardware_failed_; |
402 } | 438 } |
403 | 439 |
404 void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { | 440 void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { |
405 TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawGL"); | 441 TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawGL"); |
406 | 442 |
407 manager_key_ = g_view_renderer_manager.Get().DidDrawGL(manager_key_, this); | 443 manager_key_ = g_view_renderer_manager.Get().DidDrawGL(manager_key_, this); |
408 | 444 |
409 // We need to watch if the current Android context has changed and enforce | 445 // We need to watch if the current Android context has changed and enforce |
410 // a clean-up in the compositor. | 446 // a clean-up in the compositor. |
411 EGLContext current_context = eglGetCurrentContext(); | 447 EGLContext current_context = eglGetCurrentContext(); |
412 if (!current_context) { | 448 if (!current_context) { |
413 TRACE_EVENT_INSTANT0( | 449 TRACE_EVENT_INSTANT0( |
414 "android_webview", "EarlyOut_NullEGLContext", TRACE_EVENT_SCOPE_THREAD); | 450 "android_webview", "EarlyOut_NullEGLContext", TRACE_EVENT_SCOPE_THREAD); |
415 return; | 451 return; |
416 } | 452 } |
417 | 453 |
418 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); | 454 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); |
419 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 455 gl_queue_->RunTasks(); |
420 ScopedAllowGL allow_gl; | 456 ScopedAllowGL allow_gl; |
421 | 457 |
422 if (!attached_to_window_) { | 458 if (!attached_to_window_) { |
423 TRACE_EVENT_INSTANT0( | 459 TRACE_EVENT_INSTANT0( |
424 "android_webview", "EarlyOut_NotAttached", TRACE_EVENT_SCOPE_THREAD); | 460 "android_webview", "EarlyOut_NotAttached", TRACE_EVENT_SCOPE_THREAD); |
425 return; | 461 return; |
426 } | 462 } |
427 | 463 |
428 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { | 464 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { |
429 TRACE_EVENT_INSTANT0( | 465 TRACE_EVENT_INSTANT0( |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
698 void InProcessViewRenderer::OnDetachedFromWindow() { | 734 void InProcessViewRenderer::OnDetachedFromWindow() { |
699 TRACE_EVENT0("android_webview", | 735 TRACE_EVENT0("android_webview", |
700 "InProcessViewRenderer::OnDetachedFromWindow"); | 736 "InProcessViewRenderer::OnDetachedFromWindow"); |
701 | 737 |
702 NoLongerExpectsDrawGL(); | 738 NoLongerExpectsDrawGL(); |
703 if (hardware_initialized_) { | 739 if (hardware_initialized_) { |
704 DCHECK(compositor_); | 740 DCHECK(compositor_); |
705 | 741 |
706 ScopedAppGLStateRestore state_restore( | 742 ScopedAppGLStateRestore state_restore( |
707 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | 743 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); |
708 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 744 gl_queue->RunTasks(); |
709 ScopedAllowGL allow_gl; | 745 ScopedAllowGL allow_gl; |
710 compositor_->ReleaseHwDraw(); | 746 compositor_->ReleaseHwDraw(); |
711 hardware_initialized_ = false; | 747 hardware_initialized_ = false; |
712 } | 748 } |
713 | 749 |
714 gl_surface_ = NULL; | 750 gl_surface_ = NULL; |
751 gl_queue_ = NULL; | |
715 attached_to_window_ = false; | 752 attached_to_window_ = false; |
716 } | 753 } |
717 | 754 |
718 bool InProcessViewRenderer::IsAttachedToWindow() { | 755 bool InProcessViewRenderer::IsAttachedToWindow() { |
719 return attached_to_window_; | 756 return attached_to_window_; |
720 } | 757 } |
721 | 758 |
722 bool InProcessViewRenderer::IsVisible() { | 759 bool InProcessViewRenderer::IsVisible() { |
723 // Ignore |window_visible_| if |attached_to_window_| is false. | 760 // Ignore |window_visible_| if |attached_to_window_| is false. |
724 return view_visible_ && (!attached_to_window_ || window_visible_); | 761 return view_visible_ && (!attached_to_window_ || window_visible_); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1016 base::StringAppendF(&str, | 1053 base::StringAppendF(&str, |
1017 "surface width height: [%d %d] ", | 1054 "surface width height: [%d %d] ", |
1018 draw_info->width, | 1055 draw_info->width, |
1019 draw_info->height); | 1056 draw_info->height); |
1020 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 1057 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
1021 } | 1058 } |
1022 return str; | 1059 return str; |
1023 } | 1060 } |
1024 | 1061 |
1025 } // namespace android_webview | 1062 } // namespace android_webview |
OLD | NEW |