| 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) { |
| 203 { |
| 204 base::AutoLock lock(tasks_lock_); |
| 205 tasks_.push(task); |
| 206 } |
| 197 if (ScopedAllowGL::IsAllowed()) { | 207 if (ScopedAllowGL::IsAllowed()) { |
| 198 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 208 RunTasks(); |
| 199 } else { | 209 } else { |
| 200 RequestProcessGLOnUIThread(); | 210 RequestProcessGLOnUIThread(); |
| 201 } | 211 } |
| 202 } | 212 } |
| 203 | 213 |
| 214 void DeferredGpuCommandService::ScheduleIdleWork( |
| 215 const base::Closure& callback) { |
| 216 // TODO(sievers): Should this do anything? |
| 217 } |
| 218 |
| 219 void DeferredGpuCommandService::RunTasks() { |
| 220 bool has_more_tasks; |
| 221 { |
| 222 base::AutoLock lock(tasks_lock_); |
| 223 has_more_tasks = tasks_.size() > 0; |
| 224 } |
| 225 |
| 226 while (has_more_tasks) { |
| 227 base::Closure task; |
| 228 { |
| 229 base::AutoLock lock(tasks_lock_); |
| 230 task = tasks_.front(); |
| 231 tasks_.pop(); |
| 232 } |
| 233 task.Run(); |
| 234 { |
| 235 base::AutoLock lock(tasks_lock_); |
| 236 has_more_tasks = tasks_.size() > 0; |
| 237 } |
| 238 |
| 239 } |
| 240 } |
| 241 |
| 204 // static | 242 // static |
| 205 void BrowserViewRenderer::SetAwDrawSWFunctionTable( | 243 void BrowserViewRenderer::SetAwDrawSWFunctionTable( |
| 206 AwDrawSWFunctionTable* table) { | 244 AwDrawSWFunctionTable* table) { |
| 207 g_sw_draw_functions = table; | 245 g_sw_draw_functions = table; |
| 208 gpu::InProcessCommandBuffer::SetScheduleCallback( | |
| 209 base::Bind(&ScheduleGpuWork)); | |
| 210 } | 246 } |
| 211 | 247 |
| 212 // static | 248 // static |
| 213 AwDrawSWFunctionTable* BrowserViewRenderer::GetAwDrawSWFunctionTable() { | 249 AwDrawSWFunctionTable* BrowserViewRenderer::GetAwDrawSWFunctionTable() { |
| 214 return g_sw_draw_functions; | 250 return g_sw_draw_functions; |
| 215 } | 251 } |
| 216 | 252 |
| 217 InProcessViewRenderer::InProcessViewRenderer( | 253 InProcessViewRenderer::InProcessViewRenderer( |
| 218 BrowserViewRenderer::Client* client, | 254 BrowserViewRenderer::Client* client, |
| 219 JavaHelper* java_helper, | 255 JavaHelper* java_helper, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 // normal levels in the next DrawGL call. | 380 // normal levels in the next DrawGL call. |
| 345 content::SynchronousCompositorMemoryPolicy policy; | 381 content::SynchronousCompositorMemoryPolicy policy; |
| 346 policy.bytes_limit = 0; | 382 policy.bytes_limit = 0; |
| 347 policy.num_resources_limit = 0; | 383 policy.num_resources_limit = 0; |
| 348 if (memory_policy_ == policy) | 384 if (memory_policy_ == policy) |
| 349 return; | 385 return; |
| 350 | 386 |
| 351 TRACE_EVENT0("android_webview", "InProcessViewRenderer::TrimMemory"); | 387 TRACE_EVENT0("android_webview", "InProcessViewRenderer::TrimMemory"); |
| 352 ScopedAppGLStateRestore state_restore( | 388 ScopedAppGLStateRestore state_restore( |
| 353 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | 389 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); |
| 354 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 390 gl_queue_->RunTasks(); |
| 355 ScopedAllowGL allow_gl; | 391 ScopedAllowGL allow_gl; |
| 356 | 392 |
| 357 SetMemoryPolicy(policy); | 393 SetMemoryPolicy(policy); |
| 358 ForceFakeCompositeSW(); | 394 ForceFakeCompositeSW(); |
| 359 } | 395 } |
| 360 | 396 |
| 361 void InProcessViewRenderer::SetMemoryPolicy( | 397 void InProcessViewRenderer::SetMemoryPolicy( |
| 362 content::SynchronousCompositorMemoryPolicy& new_policy) { | 398 content::SynchronousCompositorMemoryPolicy& new_policy) { |
| 363 if (memory_policy_ == new_policy) | 399 if (memory_policy_ == new_policy) |
| 364 return; | 400 return; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 385 return compositor_ && client_->RequestDrawGL(java_canvas); | 421 return compositor_ && client_->RequestDrawGL(java_canvas); |
| 386 } | 422 } |
| 387 // Perform a software draw | 423 // Perform a software draw |
| 388 return DrawSWInternal(java_canvas, clip); | 424 return DrawSWInternal(java_canvas, clip); |
| 389 } | 425 } |
| 390 | 426 |
| 391 bool InProcessViewRenderer::InitializeHwDraw() { | 427 bool InProcessViewRenderer::InitializeHwDraw() { |
| 392 TRACE_EVENT0("android_webview", "InitializeHwDraw"); | 428 TRACE_EVENT0("android_webview", "InitializeHwDraw"); |
| 393 DCHECK(!gl_surface_); | 429 DCHECK(!gl_surface_); |
| 394 gl_surface_ = new AwGLSurface; | 430 gl_surface_ = new AwGLSurface; |
| 395 hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_); | 431 gl_queue_ = new DeferredGpuCommandService; |
| 432 hardware_failed_ = !compositor_->InitializeHwDraw(gl_surface_, gl_queue_); |
| 396 hardware_initialized_ = true; | 433 hardware_initialized_ = true; |
| 397 | 434 |
| 398 if (hardware_failed_) | 435 if (hardware_failed_) { |
| 399 gl_surface_ = NULL; | 436 gl_surface_ = NULL; |
| 437 gl_queue_ = NULL; |
| 438 } |
| 400 | 439 |
| 401 return !hardware_failed_; | 440 return !hardware_failed_; |
| 402 } | 441 } |
| 403 | 442 |
| 404 void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { | 443 void InProcessViewRenderer::DrawGL(AwDrawGLInfo* draw_info) { |
| 405 TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawGL"); | 444 TRACE_EVENT0("android_webview", "InProcessViewRenderer::DrawGL"); |
| 406 | 445 |
| 407 manager_key_ = g_view_renderer_manager.Get().DidDrawGL(manager_key_, this); | 446 manager_key_ = g_view_renderer_manager.Get().DidDrawGL(manager_key_, this); |
| 408 | 447 |
| 409 // We need to watch if the current Android context has changed and enforce | 448 // We need to watch if the current Android context has changed and enforce |
| 410 // a clean-up in the compositor. | 449 // a clean-up in the compositor. |
| 411 EGLContext current_context = eglGetCurrentContext(); | 450 EGLContext current_context = eglGetCurrentContext(); |
| 412 if (!current_context) { | 451 if (!current_context) { |
| 413 TRACE_EVENT_INSTANT0( | 452 TRACE_EVENT_INSTANT0( |
| 414 "android_webview", "EarlyOut_NullEGLContext", TRACE_EVENT_SCOPE_THREAD); | 453 "android_webview", "EarlyOut_NullEGLContext", TRACE_EVENT_SCOPE_THREAD); |
| 415 return; | 454 return; |
| 416 } | 455 } |
| 417 | 456 |
| 418 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); | 457 ScopedAppGLStateRestore state_restore(ScopedAppGLStateRestore::MODE_DRAW); |
| 419 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 458 if (gl_queue_) |
| 459 gl_queue_->RunTasks(); |
| 420 ScopedAllowGL allow_gl; | 460 ScopedAllowGL allow_gl; |
| 421 | 461 |
| 422 if (!attached_to_window_) { | 462 if (!attached_to_window_) { |
| 423 TRACE_EVENT_INSTANT0( | 463 TRACE_EVENT_INSTANT0( |
| 424 "android_webview", "EarlyOut_NotAttached", TRACE_EVENT_SCOPE_THREAD); | 464 "android_webview", "EarlyOut_NotAttached", TRACE_EVENT_SCOPE_THREAD); |
| 425 return; | 465 return; |
| 426 } | 466 } |
| 427 | 467 |
| 428 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { | 468 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { |
| 429 TRACE_EVENT_INSTANT0( | 469 TRACE_EVENT_INSTANT0( |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 void InProcessViewRenderer::OnDetachedFromWindow() { | 738 void InProcessViewRenderer::OnDetachedFromWindow() { |
| 699 TRACE_EVENT0("android_webview", | 739 TRACE_EVENT0("android_webview", |
| 700 "InProcessViewRenderer::OnDetachedFromWindow"); | 740 "InProcessViewRenderer::OnDetachedFromWindow"); |
| 701 | 741 |
| 702 NoLongerExpectsDrawGL(); | 742 NoLongerExpectsDrawGL(); |
| 703 if (hardware_initialized_) { | 743 if (hardware_initialized_) { |
| 704 DCHECK(compositor_); | 744 DCHECK(compositor_); |
| 705 | 745 |
| 706 ScopedAppGLStateRestore state_restore( | 746 ScopedAppGLStateRestore state_restore( |
| 707 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | 747 ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); |
| 708 gpu::InProcessCommandBuffer::ProcessGpuWorkOnCurrentThread(); | 748 gl_queue_->RunTasks(); |
| 709 ScopedAllowGL allow_gl; | 749 ScopedAllowGL allow_gl; |
| 710 compositor_->ReleaseHwDraw(); | 750 compositor_->ReleaseHwDraw(); |
| 711 hardware_initialized_ = false; | 751 hardware_initialized_ = false; |
| 712 } | 752 } |
| 713 | 753 |
| 714 gl_surface_ = NULL; | 754 gl_surface_ = NULL; |
| 755 gl_queue_ = NULL; |
| 715 attached_to_window_ = false; | 756 attached_to_window_ = false; |
| 716 } | 757 } |
| 717 | 758 |
| 718 bool InProcessViewRenderer::IsAttachedToWindow() { | 759 bool InProcessViewRenderer::IsAttachedToWindow() { |
| 719 return attached_to_window_; | 760 return attached_to_window_; |
| 720 } | 761 } |
| 721 | 762 |
| 722 bool InProcessViewRenderer::IsVisible() { | 763 bool InProcessViewRenderer::IsVisible() { |
| 723 // Ignore |window_visible_| if |attached_to_window_| is false. | 764 // Ignore |window_visible_| if |attached_to_window_| is false. |
| 724 return view_visible_ && (!attached_to_window_ || window_visible_); | 765 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, | 1057 base::StringAppendF(&str, |
| 1017 "surface width height: [%d %d] ", | 1058 "surface width height: [%d %d] ", |
| 1018 draw_info->width, | 1059 draw_info->width, |
| 1019 draw_info->height); | 1060 draw_info->height); |
| 1020 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 1061 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
| 1021 } | 1062 } |
| 1022 return str; | 1063 return str; |
| 1023 } | 1064 } |
| 1024 | 1065 |
| 1025 } // namespace android_webview | 1066 } // namespace android_webview |
| OLD | NEW |