Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / android_webview / browser / deferred_gpu_command_service.cc
blobef0542c559f4042e0a4f9644938d1e92a08486aa
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/framebuffer_completeness_cache.h"
14 #include "gpu/command_buffer/service/shader_translator_cache.h"
15 #include "gpu/command_buffer/service/sync_point_manager.h"
17 namespace android_webview {
19 namespace {
20 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
21 g_service = LAZY_INSTANCE_INITIALIZER;
22 } // namespace
24 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
26 // static
27 bool ScopedAllowGL::IsAllowed() {
28 return allow_gl.Get().Get();
31 ScopedAllowGL::ScopedAllowGL() {
32 DCHECK(!allow_gl.Get().Get());
33 allow_gl.Get().Set(true);
35 if (g_service.Get().get())
36 g_service.Get()->RunTasks();
39 ScopedAllowGL::~ScopedAllowGL() {
40 allow_gl.Get().Set(false);
42 DeferredGpuCommandService* service = g_service.Get().get();
43 if (service) {
44 service->RunTasks();
45 if (service->IdleQueueSize()) {
46 service->RequestProcessGL(true);
51 // static
52 void DeferredGpuCommandService::SetInstance() {
53 if (!g_service.Get().get()) {
54 g_service.Get() = new DeferredGpuCommandService;
55 content::SynchronousCompositor::SetGpuService(g_service.Get());
59 // static
60 DeferredGpuCommandService* DeferredGpuCommandService::GetInstance() {
61 DCHECK(g_service.Get().get());
62 return g_service.Get().get();
65 DeferredGpuCommandService::DeferredGpuCommandService()
66 : sync_point_manager_(new gpu::SyncPointManager(true)) {}
68 DeferredGpuCommandService::~DeferredGpuCommandService() {
69 base::AutoLock lock(tasks_lock_);
70 DCHECK(tasks_.empty());
73 // This method can be called on any thread.
74 // static
75 void DeferredGpuCommandService::RequestProcessGL(bool for_idle) {
76 SharedRendererState* renderer_state =
77 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
78 if (!renderer_state) {
79 LOG(ERROR) << "No hardware renderer. Deadlock likely";
80 return;
82 renderer_state->ClientRequestDrawGL(for_idle);
85 // Called from different threads!
86 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
88 base::AutoLock lock(tasks_lock_);
89 tasks_.push(task);
91 if (ScopedAllowGL::IsAllowed()) {
92 RunTasks();
93 } else {
94 RequestProcessGL(false);
98 size_t DeferredGpuCommandService::IdleQueueSize() {
99 base::AutoLock lock(tasks_lock_);
100 return idle_tasks_.size();
103 void DeferredGpuCommandService::ScheduleIdleWork(
104 const base::Closure& callback) {
106 base::AutoLock lock(tasks_lock_);
107 idle_tasks_.push(std::make_pair(base::Time::Now(), callback));
109 RequestProcessGL(true);
112 void DeferredGpuCommandService::PerformIdleWork(bool is_idle) {
113 TRACE_EVENT1("android_webview",
114 "DeferredGpuCommandService::PerformIdleWork",
115 "is_idle",
116 is_idle);
117 DCHECK(ScopedAllowGL::IsAllowed());
118 static const base::TimeDelta kMaxIdleAge =
119 base::TimeDelta::FromMilliseconds(16);
121 const base::Time now = base::Time::Now();
122 size_t queue_size = IdleQueueSize();
123 while (queue_size--) {
124 base::Closure task;
126 base::AutoLock lock(tasks_lock_);
127 if (!is_idle) {
128 // Only run old tasks if we are not really idle right now.
129 base::TimeDelta age(now - idle_tasks_.front().first);
130 if (age < kMaxIdleAge)
131 break;
133 task = idle_tasks_.front().second;
134 idle_tasks_.pop();
136 task.Run();
140 void DeferredGpuCommandService::PerformAllIdleWork() {
141 TRACE_EVENT0("android_webview",
142 "DeferredGpuCommandService::PerformAllIdleWork");
143 while (IdleQueueSize()) {
144 PerformIdleWork(true);
148 bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; }
150 scoped_refptr<gpu::gles2::ShaderTranslatorCache>
151 DeferredGpuCommandService::shader_translator_cache() {
152 if (!shader_translator_cache_.get())
153 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
154 return shader_translator_cache_;
157 scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
158 DeferredGpuCommandService::framebuffer_completeness_cache() {
159 if (!framebuffer_completeness_cache_.get()) {
160 framebuffer_completeness_cache_ =
161 new gpu::gles2::FramebufferCompletenessCache;
163 return framebuffer_completeness_cache_;
166 gpu::SyncPointManager* DeferredGpuCommandService::sync_point_manager() {
167 return sync_point_manager_.get();
170 void DeferredGpuCommandService::RunTasks() {
171 TRACE_EVENT0("android_webview", "DeferredGpuCommandService::RunTasks");
172 bool has_more_tasks;
174 base::AutoLock lock(tasks_lock_);
175 has_more_tasks = tasks_.size() > 0;
178 while (has_more_tasks) {
179 base::Closure task;
181 base::AutoLock lock(tasks_lock_);
182 task = tasks_.front();
183 tasks_.pop();
185 task.Run();
187 base::AutoLock lock(tasks_lock_);
188 has_more_tasks = tasks_.size() > 0;
193 void DeferredGpuCommandService::AddRef() const {
194 base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
197 void DeferredGpuCommandService::Release() const {
198 base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
201 } // namespace android_webview