Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / android_webview / browser / deferred_gpu_command_service.cc
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.
4
5 #include "android_webview/browser/deferred_gpu_command_service.h"
6
7 #include "android_webview/browser/gl_view_renderer_manager.h"
8 #include "android_webview/browser/shared_renderer_state.h"
9 #include "content/public/browser/android/synchronous_compositor.h"
10 #include "gpu/command_buffer/service/shader_translator_cache.h"
11
12 namespace android_webview {
13
14 namespace {
15 base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
16     g_service = LAZY_INSTANCE_INITIALIZER;
17 }  // namespace
18
19 base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
20
21 // static
22 bool ScopedAllowGL::IsAllowed() {
23   return allow_gl.Get().Get();
24 }
25
26 ScopedAllowGL::ScopedAllowGL() {
27   DCHECK(!allow_gl.Get().Get());
28   allow_gl.Get().Set(true);
29
30   if (g_service.Get())
31     g_service.Get()->RunTasks();
32 }
33
34 ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); }
35
36 // static
37 void DeferredGpuCommandService::SetInstance() {
38   if (!g_service.Get()) {
39     g_service.Get() = new DeferredGpuCommandService;
40     content::SynchronousCompositor::SetGpuService(g_service.Get());
41   }
42 }
43
44 DeferredGpuCommandService::DeferredGpuCommandService() {}
45
46 DeferredGpuCommandService::~DeferredGpuCommandService() {
47   base::AutoLock lock(tasks_lock_);
48   DCHECK(tasks_.empty());
49 }
50
51 // static
52 void DeferredGpuCommandService::RequestProcessGLOnUIThread() {
53   SharedRendererState* renderer_state =
54       GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
55   if (!renderer_state) {
56     LOG(ERROR) << "No hardware renderer. Deadlock likely";
57     return;
58   }
59   renderer_state->ClientRequestDrawGL();
60 }
61
62 // Called from different threads!
63 void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
64   {
65     base::AutoLock lock(tasks_lock_);
66     tasks_.push(task);
67   }
68   if (ScopedAllowGL::IsAllowed()) {
69     RunTasks();
70   } else {
71     RequestProcessGLOnUIThread();
72   }
73 }
74
75 void DeferredGpuCommandService::ScheduleIdleWork(
76     const base::Closure& callback) {
77   // TODO(sievers): Should this do anything?
78 }
79
80 bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; }
81
82 scoped_refptr<gpu::gles2::ShaderTranslatorCache>
83 DeferredGpuCommandService::shader_translator_cache() {
84   if (!shader_translator_cache_.get())
85     shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
86   return shader_translator_cache_;
87 }
88
89 void DeferredGpuCommandService::RunTasks() {
90   bool has_more_tasks;
91   {
92     base::AutoLock lock(tasks_lock_);
93     has_more_tasks = tasks_.size() > 0;
94   }
95
96   while (has_more_tasks) {
97     base::Closure task;
98     {
99       base::AutoLock lock(tasks_lock_);
100       task = tasks_.front();
101       tasks_.pop();
102     }
103     task.Run();
104     {
105       base::AutoLock lock(tasks_lock_);
106       has_more_tasks = tasks_.size() > 0;
107     }
108   }
109 }
110
111 void DeferredGpuCommandService::AddRef() const {
112   base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
113 }
114
115 void DeferredGpuCommandService::Release() const {
116   base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
117 }
118
119 }  // namespace android_webview