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

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: 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/synchronization/lock.h" 9 #include "base/synchronization/lock.h"
10 #include "content/public/browser/android/synchronous_compositor.h" 10 #include "content/public/browser/android/synchronous_compositor.h"
11 #include "gpu/command_buffer/service/shader_translator_cache.h" 11 #include "gpu/command_buffer/service/shader_translator_cache.h"
12 12
13 namespace android_webview { 13 namespace android_webview {
14 14
15 namespace { 15 namespace {
16 16
17 // TODO(boliu): Consider using base/atomicops.h. 17 // TODO(boliu): Consider using base/atomicops.h.
18 class ThreadSafeBool { 18 class ThreadSafeBool {
19 public: 19 public:
20 ThreadSafeBool(); 20 ThreadSafeBool();
21 void Set(bool boolean); 21 void Set(bool boolean);
22 bool Get(); 22 bool Get();
23 bool GetAndSet();
23 24
24 private: 25 private:
25 base::Lock lock_; 26 base::Lock lock_;
26 bool boolean_; 27 bool boolean_;
27 DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool); 28 DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool);
28 }; 29 };
29 30
30 ThreadSafeBool::ThreadSafeBool() : boolean_(false) { 31 ThreadSafeBool::ThreadSafeBool() : boolean_(false) {
31 } 32 }
32 33
33 void ThreadSafeBool::Set(bool boolean) { 34 void ThreadSafeBool::Set(bool boolean) {
34 base::AutoLock lock(lock_); 35 base::AutoLock lock(lock_);
35 boolean_ = boolean; 36 boolean_ = boolean;
36 } 37 }
37 38
39 bool ThreadSafeBool::GetAndSet() {
40 base::AutoLock lock(lock_);
41 bool rv = boolean_;
42 boolean_ = true;
43 return rv;
44 }
45
38 bool ThreadSafeBool::Get() { 46 bool ThreadSafeBool::Get() {
39 base::AutoLock lock(lock_); 47 base::AutoLock lock(lock_);
40 return boolean_; 48 return boolean_;
41 } 49 }
42 50
43 base::LazyInstance<ThreadSafeBool> g_request_pending = 51 base::LazyInstance<ThreadSafeBool> g_request_pending =
44 LAZY_INSTANCE_INITIALIZER; 52 LAZY_INSTANCE_INITIALIZER;
45 53
54 // Because request is posted to UI thread, have to treat requests on UI thread
55 // specifically because UI can immediately block waiting for the request.
56 base::LazyInstance<ThreadSafeBool> g_request_pending_on_ui =
57 LAZY_INSTANCE_INITIALIZER;
58
46 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> > 59 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
47 g_service = LAZY_INSTANCE_INITIALIZER; 60 g_service = LAZY_INSTANCE_INITIALIZER;
48 } // namespace 61 } // namespace
49 62
50 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl; 63 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
51 64
52 // static 65 // static
53 bool ScopedAllowGL::IsAllowed() { 66 bool ScopedAllowGL::IsAllowed() {
54 return allow_gl.Get().Get(); 67 return allow_gl.Get().Get();
55 } 68 }
56 69
57 ScopedAllowGL::ScopedAllowGL() { 70 ScopedAllowGL::ScopedAllowGL() {
58 DCHECK(!allow_gl.Get().Get()); 71 DCHECK(!allow_gl.Get().Get());
59 allow_gl.Get().Set(true); 72 allow_gl.Get().Set(true);
60 73
61 if (g_service.Get()) 74 if (g_service.Get())
62 g_service.Get()->RunTasks(); 75 g_service.Get()->RunTasks();
63 } 76 }
64 77
65 ScopedAllowGL::~ScopedAllowGL() { 78 ScopedAllowGL::~ScopedAllowGL() {
66 allow_gl.Get().Set(false); 79 allow_gl.Get().Set(false);
67 g_request_pending.Get().Set(false); 80 g_request_pending.Get().Set(false);
81 g_request_pending_on_ui.Get().Set(false);
68 82
69 DeferredGpuCommandService* service = g_service.Get(); 83 DeferredGpuCommandService* service = g_service.Get();
70 if (service) { 84 if (service) {
71 service->RunTasks(); 85 service->RunTasks();
72 if (service->HasIdleWork()) { 86 if (service->HasIdleWork()) {
73 service->RequestProcessGL(); 87 service->RequestProcessGL();
74 } 88 }
75 } 89 }
76 } 90 }
77 91
78 // static 92 // static
79 void DeferredGpuCommandService::SetInstance() { 93 void DeferredGpuCommandService::SetInstance() {
80 if (!g_service.Get()) { 94 if (!g_service.Get()) {
81 g_service.Get() = new DeferredGpuCommandService; 95 g_service.Get() = new DeferredGpuCommandService;
82 content::SynchronousCompositor::SetGpuService(g_service.Get()); 96 content::SynchronousCompositor::SetGpuService(g_service.Get());
83 97
84 // Initialize global booleans. 98 // Initialize global booleans.
85 g_request_pending.Get().Set(false); 99 g_request_pending.Get().Set(false);
100 g_request_pending_on_ui.Get().Set(false);
86 } 101 }
87 } 102 }
88 103
89 // static 104 // static
90 DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() { 105 DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() {
91 DCHECK(g_service.Get().get()); 106 DCHECK(g_service.Get().get());
92 return g_service.Get().get(); 107 return g_service.Get().get();
93 } 108 }
94 109
95 DeferredGpuCommandService::DeferredGpuCommandService() {} 110 DeferredGpuCommandService::DeferredGpuCommandService() {}
96 111
97 DeferredGpuCommandService::~DeferredGpuCommandService() { 112 DeferredGpuCommandService::~DeferredGpuCommandService() {
98 base::AutoLock lock(tasks_lock_); 113 base::AutoLock lock(tasks_lock_);
99 DCHECK(tasks_.empty()); 114 DCHECK(tasks_.empty());
100 } 115 }
101 116
102 // This method can be called on any thread. 117 // This method can be called on any thread.
103 // static 118 // static
104 void DeferredGpuCommandService::RequestProcessGL() { 119 void DeferredGpuCommandService::RequestProcessGL() {
105 SharedRendererState* renderer_state = 120 SharedRendererState* renderer_state =
106 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn(); 121 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
107 if (!renderer_state) { 122 if (!renderer_state) {
108 LOG(ERROR) << "No hardware renderer. Deadlock likely"; 123 LOG(ERROR) << "No hardware renderer. Deadlock likely";
109 return; 124 return;
110 } 125 }
111 126
112 if (!g_request_pending.Get().Get()) { 127 bool on_ui_thread = renderer_state->CurrentlyOnUIThread();
hush (inactive) 2014/08/05 23:04:39 on_ui_thread only means render state was running o
boliu 2014/08/05 23:07:55 That's how things work today, before or after this
113 g_request_pending.Get().Set(true); 128 bool need_request = on_ui_thread ? !g_request_pending_on_ui.Get().GetAndSet()
129 : !g_request_pending.Get().GetAndSet();
130 if (need_request) {
131 if (on_ui_thread) {
132 g_request_pending.Get().Set(true);
133 }
hush (inactive) 2014/08/05 23:04:39 if g_request_pending_on_ui is true, g_request_pend
boliu 2014/08/05 23:07:55 Yep, that's what I wanted to do here.
hush (inactive) 2014/08/05 23:55:15 yes. if on_ui_thread is false, you will set g_requ
boliu 2014/08/06 00:05:46 Done.
114 renderer_state->ClientRequestDrawGL(); 134 renderer_state->ClientRequestDrawGL();
115 } 135 }
116 } 136 }
117 137
118 // Called from different threads! 138 // Called from different threads!
119 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) { 139 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
120 { 140 {
121 base::AutoLock lock(tasks_lock_); 141 base::AutoLock lock(tasks_lock_);
122 tasks_.push(task); 142 tasks_.push(task);
123 } 143 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 218
199 void DeferredGpuCommandService::AddRef() const { 219 void DeferredGpuCommandService::AddRef() const {
200 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef(); 220 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
201 } 221 }
202 222
203 void DeferredGpuCommandService::Release() const { 223 void DeferredGpuCommandService::Release() const {
204 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release(); 224 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
205 } 225 }
206 226
207 } // namespace android_webview 227 } // 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