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/synchronization/lock.h"
10 #include "content/public/browser/android/synchronous_compositor.h"
11 #include "gpu/command_buffer/service/shader_translator_cache.h"
13 namespace android_webview
{
17 // TODO(boliu): Consider using base/atomicops.h.
18 class ThreadSafeBool
{
21 void Set(bool boolean
);
27 DISALLOW_COPY_AND_ASSIGN(ThreadSafeBool
);
30 ThreadSafeBool::ThreadSafeBool() : boolean_(false) {
33 void ThreadSafeBool::Set(bool boolean
) {
34 base::AutoLock
lock(lock_
);
38 bool ThreadSafeBool::Get() {
39 base::AutoLock
lock(lock_
);
43 base::LazyInstance
<ThreadSafeBool
> g_request_pending
=
44 LAZY_INSTANCE_INITIALIZER
;
46 base::LazyInstance
<scoped_refptr
<DeferredGpuCommandService
> >
47 g_service
= LAZY_INSTANCE_INITIALIZER
;
50 base::LazyInstance
<base::ThreadLocalBoolean
> ScopedAllowGL::allow_gl
;
53 bool ScopedAllowGL::IsAllowed() {
54 return allow_gl
.Get().Get();
57 ScopedAllowGL::ScopedAllowGL() {
58 DCHECK(!allow_gl
.Get().Get());
59 allow_gl
.Get().Set(true);
62 g_service
.Get()->RunTasks();
65 ScopedAllowGL::~ScopedAllowGL() {
66 allow_gl
.Get().Set(false);
67 g_request_pending
.Get().Set(false);
70 g_service
.Get()->RunTasks();
74 void DeferredGpuCommandService::SetInstance() {
75 if (!g_service
.Get()) {
76 g_service
.Get() = new DeferredGpuCommandService
;
77 content::SynchronousCompositor::SetGpuService(g_service
.Get());
79 // Initialize global booleans.
80 g_request_pending
.Get().Set(false);
85 DeferredGpuCommandService
* DeferredGpuCommandService::GetInstance() {
86 DCHECK(g_service
.Get().get());
87 return g_service
.Get().get();
90 DeferredGpuCommandService::DeferredGpuCommandService() {}
92 DeferredGpuCommandService::~DeferredGpuCommandService() {
93 base::AutoLock
lock(tasks_lock_
);
94 DCHECK(tasks_
.empty());
97 // This method can be called on any thread.
99 void DeferredGpuCommandService::RequestProcessGL() {
100 SharedRendererState
* renderer_state
=
101 GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
102 if (!renderer_state
) {
103 LOG(ERROR
) << "No hardware renderer. Deadlock likely";
107 if (!g_request_pending
.Get().Get()) {
108 g_request_pending
.Get().Set(true);
109 renderer_state
->ClientRequestDrawGL();
113 // Called from different threads!
114 void DeferredGpuCommandService::ScheduleTask(const base::Closure
& task
) {
116 base::AutoLock
lock(tasks_lock_
);
119 if (ScopedAllowGL::IsAllowed()) {
126 void DeferredGpuCommandService::ScheduleIdleWork(
127 const base::Closure
& callback
) {
128 // TODO(sievers): Should this do anything?
131 bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; }
133 scoped_refptr
<gpu::gles2::ShaderTranslatorCache
>
134 DeferredGpuCommandService::shader_translator_cache() {
135 if (!shader_translator_cache_
.get())
136 shader_translator_cache_
= new gpu::gles2::ShaderTranslatorCache
;
137 return shader_translator_cache_
;
140 void DeferredGpuCommandService::RunTasks() {
143 base::AutoLock
lock(tasks_lock_
);
144 has_more_tasks
= tasks_
.size() > 0;
147 while (has_more_tasks
) {
150 base::AutoLock
lock(tasks_lock_
);
151 task
= tasks_
.front();
156 base::AutoLock
lock(tasks_lock_
);
157 has_more_tasks
= tasks_
.size() > 0;
162 void DeferredGpuCommandService::AddRef() const {
163 base::RefCountedThreadSafe
<DeferredGpuCommandService
>::AddRef();
166 void DeferredGpuCommandService::Release() const {
167 base::RefCountedThreadSafe
<DeferredGpuCommandService
>::Release();
170 } // namespace android_webview