Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(623)

Side by Side Diff: android_webview/browser/deferred_gpu_command_service.cc

Issue 431383003: aw: Track UI request GL separately from other threads (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add is_idle to trace event Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | android_webview/browser/shared_renderer_state.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/deferred_gpu_command_service.h" 5 #include "android_webview/browser/deferred_gpu_command_service.h"
6 6
7 #include "android_webview/browser/gl_view_renderer_manager.h" 7 #include "android_webview/browser/gl_view_renderer_manager.h"
8 #include "android_webview/browser/shared_renderer_state.h" 8 #include "android_webview/browser/shared_renderer_state.h"
9 #include "base/debug/trace_event.h"
9 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
10 #include "content/public/browser/android/synchronous_compositor.h" 11 #include "content/public/browser/android/synchronous_compositor.h"
11 #include "gpu/command_buffer/service/shader_translator_cache.h" 12 #include "gpu/command_buffer/service/shader_translator_cache.h"
12 13
13 namespace android_webview { 14 namespace android_webview {
14 15
15 namespace { 16 namespace {
16 17
17 // TODO(boliu): Consider using base/atomicops.h. 18 // TODO(boliu): Consider using base/atomicops.h.
18 class ThreadSafeBool { 19 class ThreadSafeBool {
19 public: 20 public:
20 ThreadSafeBool(); 21 ThreadSafeBool();
21 void Set(bool boolean); 22 void Set(bool boolean);
22 bool Get(); 23 bool Get();
24 bool GetAndSet();
23 25
24 private: 26 private:
25 base::Lock lock_; 27 base::Lock lock_;
26 bool boolean_; 28 bool boolean_;
27 DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool); 29 DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool);
28 }; 30 };
29 31
30 ThreadSafeBool::ThreadSafeBool() : boolean_(false) { 32 ThreadSafeBool::ThreadSafeBool() : boolean_(false) {
31 } 33 }
32 34
33 void ThreadSafeBool::Set(bool boolean) { 35 void ThreadSafeBool::Set(bool boolean) {
34 base::AutoLock lock(lock_); 36 base::AutoLock lock(lock_);
35 boolean_ = boolean; 37 boolean_ = boolean;
36 } 38 }
37 39
40 bool ThreadSafeBool::GetAndSet() {
41 base::AutoLock lock(lock_);
42 bool rv = boolean_;
43 boolean_ = true;
44 return rv;
45 }
46
38 bool ThreadSafeBool::Get() { 47 bool ThreadSafeBool::Get() {
39 base::AutoLock lock(lock_); 48 base::AutoLock lock(lock_);
40 return boolean_; 49 return boolean_;
41 } 50 }
42 51
43 base::LazyInstance<ThreadSafeBool> g_request_pending = 52 base::LazyInstance<ThreadSafeBool> g_request_pending =
44 LAZY_INSTANCE_INITIALIZER; 53 LAZY_INSTANCE_INITIALIZER;
45 54
55 // Because request is posted to UI thread, have to treat requests on UI thread
56 // specifically because UI can immediately block waiting for the request.
57 base::LazyInstance<ThreadSafeBool> g_request_pending_on_ui =
58 LAZY_INSTANCE_INITIALIZER;
59
46 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> > 60 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
47 g_service = LAZY_INSTANCE_INITIALIZER; 61 g_service = LAZY_INSTANCE_INITIALIZER;
48 } // namespace 62 } // namespace
49 63
50 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl; 64 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
51 65
52 // static 66 // static
53 bool ScopedAllowGL::IsAllowed() { 67 bool ScopedAllowGL::IsAllowed() {
54 return allow_gl.Get().Get(); 68 return allow_gl.Get().Get();
55 } 69 }
56 70
57 ScopedAllowGL::ScopedAllowGL() { 71 ScopedAllowGL::ScopedAllowGL() {
58 DCHECK(!allow_gl.Get().Get()); 72 DCHECK(!allow_gl.Get().Get());
59 allow_gl.Get().Set(true); 73 allow_gl.Get().Set(true);
60 74
61 if (g_service.Get()) 75 if (g_service.Get())
62 g_service.Get()->RunTasks(); 76 g_service.Get()->RunTasks();
63 } 77 }
64 78
65 ScopedAllowGL::~ScopedAllowGL() { 79 ScopedAllowGL::~ScopedAllowGL() {
66 allow_gl.Get().Set(false); 80 allow_gl.Get().Set(false);
67 g_request_pending.Get().Set(false); 81 g_request_pending.Get().Set(false);
82 g_request_pending_on_ui.Get().Set(false);
68 83
69 DeferredGpuCommandService* service = g_service.Get(); 84 DeferredGpuCommandService* service = g_service.Get();
70 if (service) { 85 if (service) {
71 service->RunTasks(); 86 service->RunTasks();
72 if (service->HasIdleWork()) { 87 if (service->HasIdleWork()) {
73 service->RequestProcessGL(); 88 service->RequestProcessGL();
74 } 89 }
75 } 90 }
76 } 91 }
77 92
78 // static 93 // static
79 void DeferredGpuCommandService::SetInstance() { 94 void DeferredGpuCommandService::SetInstance() {
80 if (!g_service.Get()) { 95 if (!g_service.Get()) {
81 g_service.Get() = new DeferredGpuCommandService; 96 g_service.Get() = new DeferredGpuCommandService;
82 content::SynchronousCompositor::SetGpuService(g_service.Get()); 97 content::SynchronousCompositor::SetGpuService(g_service.Get());
83 98
84 // Initialize global booleans. 99 // Initialize global booleans.
85 g_request_pending.Get().Set(false); 100 g_request_pending.Get().Set(false);
101 g_request_pending_on_ui.Get().Set(false);
86 } 102 }
87 } 103 }
88 104
89 // static 105 // static
90 DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() { 106 DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() {
91 DCHECK(g_service.Get().get()); 107 DCHECK(g_service.Get().get());
92 return g_service.Get().get(); 108 return g_service.Get().get();
93 } 109 }
94 110
95 DeferredGpuCommandService::DeferredGpuCommandService() {} 111 DeferredGpuCommandService::DeferredGpuCommandService() {}
96 112
97 DeferredGpuCommandService::~DeferredGpuCommandService() { 113 DeferredGpuCommandService::~DeferredGpuCommandService() {
98 base::AutoLock lock(tasks_lock_); 114 base::AutoLock lock(tasks_lock_);
99 DCHECK(tasks_.empty()); 115 DCHECK(tasks_.empty());
100 } 116 }
101 117
102 // This method can be called on any thread. 118 // This method can be called on any thread.
103 // static 119 // static
104 void DeferredGpuCommandService::RequestProcessGL() { 120 void DeferredGpuCommandService::RequestProcessGL() {
105 SharedRendererState* renderer_state = 121 SharedRendererState* renderer_state =
106 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn(); 122 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
107 if (!renderer_state) { 123 if (!renderer_state) {
108 LOG(ERROR) << "No hardware renderer. Deadlock likely"; 124 LOG(ERROR) << "No hardware renderer. Deadlock likely";
109 return; 125 return;
110 } 126 }
111 127
112 if (!g_request_pending.Get().Get()) { 128 bool on_ui_thread = renderer_state->CurrentlyOnUIThread();
129 bool need_request = on_ui_thread ? !g_request_pending_on_ui.Get().GetAndSet()
130 : !g_request_pending.Get().GetAndSet();
131 if (need_request) {
113 g_request_pending.Get().Set(true); 132 g_request_pending.Get().Set(true);
114 renderer_state->ClientRequestDrawGL(); 133 renderer_state->ClientRequestDrawGL();
115 } 134 }
116 } 135 }
117 136
118 // Called from different threads! 137 // Called from different threads!
119 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) { 138 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
120 { 139 {
121 base::AutoLock lock(tasks_lock_); 140 base::AutoLock lock(tasks_lock_);
122 tasks_.push(task); 141 tasks_.push(task);
(...skipping 13 matching lines...) Expand all
136 void DeferredGpuCommandService::ScheduleIdleWork( 155 void DeferredGpuCommandService::ScheduleIdleWork(
137 const base::Closure& callback) { 156 const base::Closure& callback) {
138 { 157 {
139 base::AutoLock lock(tasks_lock_); 158 base::AutoLock lock(tasks_lock_);
140 idle_tasks_.push(std::make_pair(base::Time::Now(), callback)); 159 idle_tasks_.push(std::make_pair(base::Time::Now(), callback));
141 } 160 }
142 RequestProcessGL(); 161 RequestProcessGL();
143 } 162 }
144 163
145 void DeferredGpuCommandService::PerformIdleWork(bool is_idle) { 164 void DeferredGpuCommandService::PerformIdleWork(bool is_idle) {
165 TRACE_EVENT1("android_webview",
166 "DeferredGpuCommandService::PerformIdleWork",
167 "is_idle",
168 is_idle);
146 DCHECK(ScopedAllowGL::IsAllowed()); 169 DCHECK(ScopedAllowGL::IsAllowed());
147 static const base::TimeDelta kMaxIdleAge = 170 static const base::TimeDelta kMaxIdleAge =
148 base::TimeDelta::FromMilliseconds(16); 171 base::TimeDelta::FromMilliseconds(16);
149 172
150 const base::Time now = base::Time::Now(); 173 const base::Time now = base::Time::Now();
151 while (HasIdleWork()) { 174 while (HasIdleWork()) {
152 base::Closure task; 175 base::Closure task;
153 { 176 {
154 base::AutoLock lock(tasks_lock_); 177 base::AutoLock lock(tasks_lock_);
155 if (!is_idle) { 178 if (!is_idle) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 221
199 void DeferredGpuCommandService::AddRef() const { 222 void DeferredGpuCommandService::AddRef() const {
200 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef(); 223 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
201 } 224 }
202 225
203 void DeferredGpuCommandService::Release() const { 226 void DeferredGpuCommandService::Release() const {
204 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release(); 227 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
205 } 228 }
206 229
207 } // namespace android_webview 230 } // namespace android_webview
OLDNEW
« no previous file with comments | « no previous file | android_webview/browser/shared_renderer_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698