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_client.h" | 7 #include "android_webview/browser/browser_view_renderer_client.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/lazy_instance.h" |
9 #include "base/location.h" | 10 #include "base/location.h" |
10 | 11 |
11 namespace android_webview { | 12 namespace android_webview { |
12 | 13 |
| 14 namespace internal { |
| 15 |
| 16 class RequestDrawGLTracker { |
| 17 public: |
| 18 RequestDrawGLTracker(); |
| 19 bool ShouldRequestOnNoneUiThread(SharedRendererState* state); |
| 20 bool ShouldRequestOnUiThread(SharedRendererState* state); |
| 21 void DidRequestOnUiThread(); |
| 22 void ResetPending(); |
| 23 |
| 24 private: |
| 25 base::Lock lock_; |
| 26 SharedRendererState* pending_ui_; |
| 27 SharedRendererState* pending_non_ui_; |
| 28 }; |
| 29 |
| 30 RequestDrawGLTracker::RequestDrawGLTracker() |
| 31 : pending_ui_(NULL), pending_non_ui_(NULL) { |
| 32 } |
| 33 |
| 34 bool RequestDrawGLTracker::ShouldRequestOnNoneUiThread( |
| 35 SharedRendererState* state) { |
| 36 base::AutoLock lock(lock_); |
| 37 if (pending_ui_ || pending_non_ui_) |
| 38 return false; |
| 39 pending_non_ui_ = state; |
| 40 return true; |
| 41 } |
| 42 |
| 43 bool RequestDrawGLTracker::ShouldRequestOnUiThread(SharedRendererState* state) { |
| 44 base::AutoLock lock(lock_); |
| 45 if (pending_non_ui_) { |
| 46 pending_non_ui_->ResetRequestDrawGLCallback(); |
| 47 pending_non_ui_ = NULL; |
| 48 } |
| 49 if (pending_ui_) |
| 50 return false; |
| 51 pending_ui_ = state; |
| 52 return true; |
| 53 } |
| 54 |
| 55 void RequestDrawGLTracker::ResetPending() { |
| 56 base::AutoLock lock(lock_); |
| 57 pending_non_ui_ = NULL; |
| 58 pending_ui_ = NULL; |
| 59 } |
| 60 |
| 61 } // namespace internal |
| 62 |
| 63 namespace { |
| 64 |
| 65 base::LazyInstance<internal::RequestDrawGLTracker> g_request_draw_gl_tracker = |
| 66 LAZY_INSTANCE_INITIALIZER; |
| 67 |
| 68 } |
| 69 |
13 DrawGLInput::DrawGLInput() : width(0), height(0) { | 70 DrawGLInput::DrawGLInput() : width(0), height(0) { |
14 } | 71 } |
15 | 72 |
16 DrawGLInput::~DrawGLInput() { | 73 DrawGLInput::~DrawGLInput() { |
17 } | 74 } |
18 | 75 |
19 SharedRendererState::SharedRendererState( | 76 SharedRendererState::SharedRendererState( |
20 scoped_refptr<base::MessageLoopProxy> ui_loop, | 77 scoped_refptr<base::MessageLoopProxy> ui_loop, |
21 BrowserViewRendererClient* client) | 78 BrowserViewRendererClient* client) |
22 : ui_loop_(ui_loop), | 79 : ui_loop_(ui_loop), |
23 client_on_ui_(client), | 80 client_on_ui_(client), |
24 weak_factory_on_ui_thread_(this), | 81 weak_factory_on_ui_thread_(this), |
25 ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), | 82 ui_thread_weak_ptr_(weak_factory_on_ui_thread_.GetWeakPtr()), |
26 inside_hardware_release_(false), | 83 inside_hardware_release_(false), |
27 share_context_(NULL) { | 84 share_context_(NULL) { |
28 DCHECK(ui_loop_->BelongsToCurrentThread()); | 85 DCHECK(ui_loop_->BelongsToCurrentThread()); |
29 DCHECK(client_on_ui_); | 86 DCHECK(client_on_ui_); |
| 87 ResetRequestDrawGLCallback(); |
30 } | 88 } |
31 | 89 |
32 SharedRendererState::~SharedRendererState() { | 90 SharedRendererState::~SharedRendererState() { |
33 DCHECK(ui_loop_->BelongsToCurrentThread()); | 91 DCHECK(ui_loop_->BelongsToCurrentThread()); |
34 } | 92 } |
35 | 93 |
36 bool SharedRendererState::CurrentlyOnUIThread() { | 94 void SharedRendererState::ClientRequestDrawGL() { |
37 return ui_loop_->BelongsToCurrentThread(); | 95 if (ui_loop_->BelongsToCurrentThread()) { |
| 96 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnUiThread(this)) |
| 97 return; |
| 98 ClientRequestDrawGLOnUIThread(); |
| 99 } else { |
| 100 if (!g_request_draw_gl_tracker.Get().ShouldRequestOnNoneUiThread(this)) |
| 101 return; |
| 102 base::Closure callback; |
| 103 { |
| 104 base::AutoLock lock(lock_); |
| 105 callback = request_draw_gl_closure_; |
| 106 } |
| 107 ui_loop_->PostTask(FROM_HERE, callback); |
| 108 } |
38 } | 109 } |
39 | 110 |
40 void SharedRendererState::ClientRequestDrawGL() { | 111 void SharedRendererState::DidDrawGLProcess() { |
41 if (ui_loop_->BelongsToCurrentThread()) { | 112 g_request_draw_gl_tracker.Get().ResetPending(); |
42 ClientRequestDrawGLOnUIThread(); | 113 } |
43 } else { | 114 |
44 ui_loop_->PostTask( | 115 void SharedRendererState::ResetRequestDrawGLCallback() { |
45 FROM_HERE, | 116 DCHECK(ui_loop_->BelongsToCurrentThread()); |
46 base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, | 117 base::AutoLock lock(lock_); |
47 ui_thread_weak_ptr_)); | 118 request_draw_gl_cancelable_closure_.Reset( |
48 } | 119 base::Bind(&SharedRendererState::ClientRequestDrawGLOnUIThread, |
| 120 base::Unretained(this))); |
| 121 request_draw_gl_closure_ = request_draw_gl_cancelable_closure_.callback(); |
49 } | 122 } |
50 | 123 |
51 void SharedRendererState::ClientRequestDrawGLOnUIThread() { | 124 void SharedRendererState::ClientRequestDrawGLOnUIThread() { |
52 DCHECK(ui_loop_->BelongsToCurrentThread()); | 125 DCHECK(ui_loop_->BelongsToCurrentThread()); |
| 126 ResetRequestDrawGLCallback(); |
53 if (!client_on_ui_->RequestDrawGL(NULL, false)) { | 127 if (!client_on_ui_->RequestDrawGL(NULL, false)) { |
| 128 g_request_draw_gl_tracker.Get().ResetPending(); |
54 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; | 129 LOG(ERROR) << "Failed to request GL process. Deadlock likely"; |
55 } | 130 } |
56 } | 131 } |
57 | 132 |
58 void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() { | 133 void SharedRendererState::UpdateParentDrawConstraintsOnUIThread() { |
59 DCHECK(ui_loop_->BelongsToCurrentThread()); | 134 DCHECK(ui_loop_->BelongsToCurrentThread()); |
60 client_on_ui_->UpdateParentDrawConstraints(); | 135 client_on_ui_->UpdateParentDrawConstraints(); |
61 } | 136 } |
62 | 137 |
63 void SharedRendererState::SetDrawGLInput(scoped_ptr<DrawGLInput> input) { | 138 void SharedRendererState::SetDrawGLInput(scoped_ptr<DrawGLInput> input) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 : shared_renderer_state_(shared_renderer_state) { | 212 : shared_renderer_state_(shared_renderer_state) { |
138 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); | 213 DCHECK(!shared_renderer_state_->IsInsideHardwareRelease()); |
139 shared_renderer_state_->SetInsideHardwareRelease(true); | 214 shared_renderer_state_->SetInsideHardwareRelease(true); |
140 } | 215 } |
141 | 216 |
142 InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { | 217 InsideHardwareReleaseReset::~InsideHardwareReleaseReset() { |
143 shared_renderer_state_->SetInsideHardwareRelease(false); | 218 shared_renderer_state_->SetInsideHardwareRelease(false); |
144 } | 219 } |
145 | 220 |
146 } // namespace android_webview | 221 } // namespace android_webview |
OLD | NEW |