Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / android_webview / browser / deferred_gpu_command_service.cc
blob8e0591e656164367bbdafb76f037e000b9ac0cc3
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
3 // found in the LICENSE file.
5 #include "android_webview/browser/deferred_gpu_command_service.h"
7 #include "android_webview/browser/gl_view_renderer_manager.h"
8 #include "android_webview/browser/shared_renderer_state.h"
9 #include "base/lazy_instance.h"
10 #include "base/synchronization/lock.h"
11 #include "base/trace_event/trace_event.h"
12 #include "content/public/browser/android/synchronous_compositor.h"
13 #include "gpu/command_buffer/service/shader_translator_cache.h"
14 #include "gpu/command_buffer/service/sync_point_manager.h"
16 namespace android_webview {
18 namespace {
19 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
20 g_service = LAZY_INSTANCE_INITIALIZER;
21 } // namespace
23 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
25 // static
26 bool ScopedAllowGL::IsAllowed() {
27 return allow_gl.Get().Get();
30 ScopedAllowGL::ScopedAllowGL() {
31 DCHECK(!allow_gl.Get().Get());
32 allow_gl.Get().Set(true);
34 if (g_service.Get().get())
35 g_service.Get()->RunTasks();
38 ScopedAllowGL::~ScopedAllowGL() {
39 allow_gl.Get().Set(false);
41 DeferredGpuCommandService* service = g_service.Get().get();
42 if (service) {
43 service->RunTasks();
44 if (service->IdleQueueSize()) {
45 service->RequestProcessGL(true);
50 // static
51 void DeferredGpuCommandService::SetInstance() {
52 if (!g_service.Get().get()) {
53 g_service.Get() = new DeferredGpuCommandService;
54 content::SynchronousCompositor::SetGpuService(g_service.Get());
58 // static
59 DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() {
60 DCHECK(g_service.Get().get());
61 return g_service.Get().get();
64 DeferredGpuCommandService::DeferredGpuCommandService()
65 : sync_point_manager_(new gpu::SyncPointManager(true)) {}
67 DeferredGpuCommandService::~DeferredGpuCommandService() {
68 base::AutoLock lock(tasks_lock_);
69 DCHECK(tasks_.empty());
72 // This method can be called on any thread.
73 // static
74 void DeferredGpuCommandService::RequestProcessGL(bool for_idle) {
75 SharedRendererState* renderer_state =
76 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
77 if (!renderer_state) {
78 LOG(ERROR) << "No hardware renderer. Deadlock likely";
79 return;
81 renderer_state->ClientRequestDrawGL(for_idle);
84 // Called from different threads!
85 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
87 base::AutoLock lock(tasks_lock_);
88 tasks_.push(task);
90 if (ScopedAllowGL::IsAllowed()) {
91 RunTasks();
92 } else {
93 RequestProcessGL(false);
97 size_t DeferredGpuCommandService::IdleQueueSize() {
98 base::AutoLock lock(tasks_lock_);
99 return idle_tasks_.size();
102 void DeferredGpuCommandService::ScheduleIdleWork(
103 const base::Closure& callback) {
105 base::AutoLock lock(tasks_lock_);
106 idle_tasks_.push(std::make_pair(base::Time::Now(), callback));
108 RequestProcessGL(true);
111 void DeferredGpuCommandService::PerformIdleWork(bool is_idle) {
112 TRACE_EVENT1("android_webview",
113 "DeferredGpuCommandService::PerformIdleWork",
114 "is_idle",
115 is_idle);
116 DCHECK(ScopedAllowGL::IsAllowed());
117 static const base::TimeDelta kMaxIdleAge =
118 base::TimeDelta::FromMilliseconds(16);
120 const base::Time now = base::Time::Now();
121 size_t queue_size = IdleQueueSize();
122 while (queue_size--) {
123 base::Closure task;
125 base::AutoLock lock(tasks_lock_);
126 if (!is_idle) {
127 // Only run old tasks if we are not really idle right now.
128 base::TimeDelta age(now - idle_tasks_.front().first);
129 if (age < kMaxIdleAge)
130 break;
132 task = idle_tasks_.front().second;
133 idle_tasks_.pop();
135 task.Run();
139 void DeferredGpuCommandService::PerformAllIdleWork() {
140 TRACE_EVENT0("android_webview",
141 "DeferredGpuCommandService::PerformAllIdleWork");
142 while (IdleQueueSize()) {
143 PerformIdleWork(true);
147 bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; }
149 scoped_refptr<gpu::gles2::ShaderTranslatorCache>
150 DeferredGpuCommandService::shader_translator_cache() {
151 if (!shader_translator_cache_.get())
152 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
153 return shader_translator_cache_;
156 gpu::SyncPointManager* DeferredGpuCommandService::sync_point_manager() {
157 return sync_point_manager_.get();
160 void DeferredGpuCommandService::RunTasks() {
161 TRACE_EVENT0("android_webview", "DeferredGpuCommandService::RunTasks");
162 bool has_more_tasks;
164 base::AutoLock lock(tasks_lock_);
165 has_more_tasks = tasks_.size() > 0;
168 while (has_more_tasks) {
169 base::Closure task;
171 base::AutoLock lock(tasks_lock_);
172 task = tasks_.front();
173 tasks_.pop();
175 task.Run();
177 base::AutoLock lock(tasks_lock_);
178 has_more_tasks = tasks_.size() > 0;
183 void DeferredGpuCommandService::AddRef() const {
184 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
187 void DeferredGpuCommandService::Release() const {
188 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
191 } // namespace android_webview