Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/shared_renderer_state.h" | 5 #include "android_webview/browser/shared_renderer_state.h" |
| 6 | 6 |
| 7 #include "android_webview/browser/browser_view_renderer.h" | 7 #include "android_webview/browser/browser_view_renderer.h" |
| 8 #include "android_webview/browser/deferred_gpu_command_service.h" | 8 #include "android_webview/browser/deferred_gpu_command_service.h" |
| 9 #include "android_webview/browser/hardware_renderer.h" | 9 #include "android_webview/browser/hardware_renderer.h" |
| 10 #include "android_webview/browser/scoped_app_gl_state_restore.h" | 10 #include "android_webview/browser/scoped_app_gl_state_restore.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 | 62 |
| 63 void RequestDrawGLTracker::ResetPending() { | 63 void RequestDrawGLTracker::ResetPending() { |
| 64 base::AutoLock lock(lock_); | 64 base::AutoLock lock(lock_); |
| 65 pending_non_ui_ = NULL; | 65 pending_non_ui_ = NULL; |
| 66 pending_ui_ = NULL; | 66 pending_ui_ = NULL; |
| 67 } | 67 } |
| 68 | 68 |
| 69 void RequestDrawGLTracker::SetQueuedFunctorOnUi(SharedRendererState* state) { | 69 void RequestDrawGLTracker::SetQueuedFunctorOnUi(SharedRendererState* state) { |
| 70 base::AutoLock lock(lock_); | 70 base::AutoLock lock(lock_); |
| 71 DCHECK(state); | 71 DCHECK(state); |
| 72 DCHECK(pending_ui_ == state || pending_non_ui_ == state); | 72 // DCHECK(pending_ui_ == state || pending_non_ui_ == state); |
|
boliu
2015/02/05 17:10:22
Just remove it.
We usually don't comment things o
| |
| 73 pending_ui_ = state; | 73 pending_ui_ = state; |
| 74 pending_non_ui_ = NULL; | 74 pending_non_ui_ = NULL; |
| 75 } | 75 } |
| 76 | 76 |
| 77 } // namespace internal | 77 } // namespace internal |
| 78 | 78 |
| 79 namespace { | 79 namespace { |
| 80 | 80 |
| 81 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = | 81 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = |
| 82 LAZY_INSTANCE_INITIALIZER; | 82 LAZY_INSTANCE_INITIALIZER; |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { | 272 void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { |
| 273 TRACE_EVENT0("android_webview", "DrawFunctor"); | 273 TRACE_EVENT0("android_webview", "DrawFunctor"); |
| 274 if (draw_info->mode == AwDrawGLInfo::kModeSync) { | 274 if (draw_info->mode == AwDrawGLInfo::kModeSync) { |
| 275 TRACE_EVENT_INSTANT0("android_webview", "kModeSync", | 275 TRACE_EVENT_INSTANT0("android_webview", "kModeSync", |
| 276 TRACE_EVENT_SCOPE_THREAD); | 276 TRACE_EVENT_SCOPE_THREAD); |
| 277 if (hardware_renderer_) | 277 if (hardware_renderer_) |
| 278 hardware_renderer_->CommitFrame(); | 278 hardware_renderer_->CommitFrame(); |
| 279 return; | 279 return; |
| 280 } | 280 } |
| 281 | 281 |
| 282 // kModeProcessNoContext should never happen because we tear down hardware | |
| 283 // in onTrimMemory. However that guarantee is maintained outside of chromium | |
| 284 // code. Not notifying shared state in kModeProcessNoContext can lead to | |
| 285 // immediate deadlock, which is slightly more catastrophic than leaks or | |
| 286 // corruption. | |
| 287 if (draw_info->mode == AwDrawGLInfo::kModeProcess || | |
| 288 draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { | |
| 289 DidDrawGLProcess(); | |
| 290 } | |
| 291 | |
| 292 { | 282 { |
| 293 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | 283 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); |
| 294 base::AutoLock lock(lock_); | 284 base::AutoLock lock(lock_); |
| 295 if (renderer_manager_key_ != manager->NullKey()) { | 285 if (renderer_manager_key_ != manager->NullKey()) { |
| 296 manager->DidDrawGL(renderer_manager_key_); | 286 manager->DidDrawGL(renderer_manager_key_); |
| 297 } | 287 } |
| 298 } | 288 } |
| 299 | 289 |
| 300 ScopedAppGLStateRestore state_restore( | 290 ScopedAppGLStateRestore state_restore( |
| 301 draw_info->mode == AwDrawGLInfo::kModeDraw | 291 draw_info->mode == AwDrawGLInfo::kModeDraw |
| 302 ? ScopedAppGLStateRestore::MODE_DRAW | 292 ? ScopedAppGLStateRestore::MODE_DRAW |
| 303 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); | 293 : ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT); |
| 304 ScopedAllowGL allow_gl; | 294 ScopedAllowGL allow_gl; |
| 305 | 295 |
| 306 if (draw_info->mode == AwDrawGLInfo::kModeProcessNoContext) { | 296 switch (draw_info->mode) { |
| 297 case AwDrawGLInfo::kModeProcessNoContext: { | |
|
boliu
2015/02/05 17:10:22
Indent here is wrong.
See http://google-styleguid
Tobias Sargeant
2015/02/05 17:29:39
Done.
| |
| 307 LOG(ERROR) << "Received unexpected kModeProcessNoContext"; | 298 LOG(ERROR) << "Received unexpected kModeProcessNoContext"; |
| 299 DidDrawGLProcess(); | |
| 300 break; | |
| 308 } | 301 } |
| 309 | 302 |
| 310 if (IsInsideHardwareRelease()) { | 303 case AwDrawGLInfo::kModeProcess: { |
| 311 hardware_renderer_.reset(); | 304 // kModeProcessNoContext should never happen because we tear down hardware |
|
boliu
2015/02/05 17:10:22
Move this comment up.
Tobias Sargeant
2015/02/05 17:29:39
Done.
| |
| 312 // Flush the idle queue in tear down. | 305 // in onTrimMemory. However that guarantee is maintained outside of chromium |
| 313 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); | 306 // code. Not notifying shared state in kModeProcessNoContext can lead to |
| 314 return; | 307 // immediate deadlock, which is slightly more catastrophic than leaks or |
| 308 // corruption. | |
| 309 DidDrawGLProcess(); | |
| 310 | |
| 311 if (IsInsideHardwareRelease()) { | |
| 312 hardware_renderer_.reset(); | |
| 313 // Flush the idle queue in tear down. | |
| 314 DeferredGpuCommandService::GetInstance()->PerformAllIdleWork(); | |
| 315 } else { | |
| 316 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true); | |
| 317 } | |
| 318 break; | |
| 315 } | 319 } |
| 316 | 320 |
| 317 if (draw_info->mode != AwDrawGLInfo::kModeDraw) { | 321 case AwDrawGLInfo::kModeDraw: { |
| 318 if (draw_info->mode == AwDrawGLInfo::kModeProcess) { | 322 if (browser_view_renderer_->IsVisible()) { |
|
boliu
2015/02/05 17:10:22
Not thread safe. BVR is a UI thread only object, a
Tobias Sargeant
2015/02/05 17:29:39
The problem is that it seems possible to get draw
boliu
2015/02/05 17:36:17
And that call is kModeDraw (not kModeProcess)? The
| |
| 319 DeferredGpuCommandService::GetInstance()->PerformIdleWork(true); | 323 if (!hardware_renderer_) { |
| 324 hardware_renderer_.reset(new HardwareRenderer(this)); | |
| 325 hardware_renderer_->CommitFrame(); | |
| 326 } | |
| 327 | |
| 328 hardware_renderer_->DrawGL(state_restore.stencil_enabled(), | |
| 329 state_restore.framebuffer_binding_ext(), | |
| 330 draw_info); | |
| 331 DeferredGpuCommandService::GetInstance()->PerformIdleWork(false); | |
| 320 } | 332 } |
| 321 return; | 333 break; |
| 322 } | 334 } |
| 323 | 335 |
| 324 if (!hardware_renderer_) { | 336 default: { |
| 325 hardware_renderer_.reset(new HardwareRenderer(this)); | 337 break; |
| 326 hardware_renderer_->CommitFrame(); | |
| 327 } | 338 } |
| 328 | 339 } |
| 329 hardware_renderer_->DrawGL(state_restore.stencil_enabled(), | |
| 330 state_restore.framebuffer_binding_ext(), | |
| 331 draw_info); | |
| 332 DeferredGpuCommandService::GetInstance()->PerformIdleWork(false); | |
| 333 } | 340 } |
| 334 | 341 |
| 335 void SharedRendererState::ReleaseHardwareDrawIfNeededOnUI() { | 342 void SharedRendererState::ReleaseHardwareDrawIfNeededOnUI() { |
| 336 DCHECK(ui_loop_->BelongsToCurrentThread()); | 343 DCHECK(ui_loop_->BelongsToCurrentThread()); |
| 337 InsideHardwareReleaseReset auto_inside_hardware_release_reset(this); | |
| 338 | |
| 339 browser_view_renderer_->InvalidateOnFunctorDestroy(); | 344 browser_view_renderer_->InvalidateOnFunctorDestroy(); |
| 340 bool hardware_initialized = browser_view_renderer_->hardware_enabled(); | 345 bool hardware_initialized = browser_view_renderer_->hardware_enabled(); |
| 341 if (hardware_initialized) { | 346 if (hardware_initialized) { |
| 342 bool draw_functor_succeeded = browser_view_renderer_->RequestDrawGL(true); | 347 { |
| 343 if (!draw_functor_succeeded) { | 348 InsideHardwareReleaseReset auto_inside_hardware_release_reset(this); |
|
boliu
2015/02/05 17:10:22
This used to wrap BVR::ReleaseHardware too.
| |
| 344 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?"; | 349 |
| 345 // Calling release on wrong thread intentionally. | 350 bool draw_functor_succeeded = browser_view_renderer_->RequestDrawGL(true); |
| 346 AwDrawGLInfo info; | 351 if (!draw_functor_succeeded) { |
| 347 info.mode = AwDrawGLInfo::kModeProcess; | 352 LOG(ERROR) << "Unable to free GL resources. Has the Window leaked?"; |
| 348 DrawGL(&info); | 353 // Calling release on wrong thread intentionally. |
| 354 AwDrawGLInfo info; | |
| 355 info.mode = AwDrawGLInfo::kModeProcess; | |
| 356 DrawGL(&info); | |
| 357 } | |
| 349 } | 358 } |
| 350 | |
| 351 browser_view_renderer_->ReleaseHardware(); | 359 browser_view_renderer_->ReleaseHardware(); |
| 352 } | 360 } |
| 353 | 361 |
| 354 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); | 362 GLViewRendererManager* manager = GLViewRendererManager::GetInstance(); |
| 355 | 363 |
| 356 { | 364 { |
| 357 base::AutoLock lock(lock_); | 365 base::AutoLock lock(lock_); |
| 358 if (renderer_manager_key_ != manager->NullKey()) { | 366 if (renderer_manager_key_ != manager->NullKey()) { |
| 359 manager->Remove(renderer_manager_key_); | 367 manager->Remove(renderer_manager_key_); |
| 360 renderer_manager_key_ = manager->NullKey(); | 368 renderer_manager_key_ = manager->NullKey(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 383 : shared_renderer_state_(shared_renderer_state) { | 391 : shared_renderer_state_(shared_renderer_state) { |
| 384 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); | 392 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); |
| 385 shared_renderer_state_->SetInsideHardwareRelease(true); | 393 shared_renderer_state_->SetInsideHardwareRelease(true); |
| 386 } | 394 } |
| 387 | 395 |
| 388 SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { | 396 SharedRendererState::InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { |
| 389 shared_renderer_state_->SetInsideHardwareRelease(false); | 397 shared_renderer_state_->SetInsideHardwareRelease(false); |
| 390 } | 398 } |
| 391 | 399 |
| 392 } // namespace android_webview | 400 } // namespace android_webview |
| OLD | NEW |