| Index: android_webview/browser/deferred_gpu_command_service.cc
|
| diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..601334ae7f923f6860811a76a163ad612ecc4585
|
| --- /dev/null
|
| +++ b/android_webview/browser/deferred_gpu_command_service.cc
|
| @@ -0,0 +1,119 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "android_webview/browser/deferred_gpu_command_service.h"
|
| +
|
| +#include "android_webview/browser/gl_view_renderer_manager.h"
|
| +#include "android_webview/browser/shared_renderer_state.h"
|
| +#include "content/public/browser/android/synchronous_compositor.h"
|
| +#include "gpu/command_buffer/service/shader_translator_cache.h"
|
| +
|
| +namespace android_webview {
|
| +
|
| +namespace {
|
| +base::LazyInstance<scoped_refptr<DeferredGpuCommandService> >
|
| + g_service = LAZY_INSTANCE_INITIALIZER;
|
| +} // namespace
|
| +
|
| +base::LazyInstance<base::ThreadLocalBoolean> ScopedAllowGL::allow_gl;
|
| +
|
| +// static
|
| +bool ScopedAllowGL::IsAllowed() {
|
| + return allow_gl.Get().Get();
|
| +}
|
| +
|
| +ScopedAllowGL::ScopedAllowGL() {
|
| + DCHECK(!allow_gl.Get().Get());
|
| + allow_gl.Get().Set(true);
|
| +
|
| + if (g_service.Get())
|
| + g_service.Get()->RunTasks();
|
| +}
|
| +
|
| +ScopedAllowGL::~ScopedAllowGL() { allow_gl.Get().Set(false); }
|
| +
|
| +// static
|
| +void DeferredGpuCommandService::SetInstance() {
|
| + if (!g_service.Get()) {
|
| + g_service.Get() = new DeferredGpuCommandService;
|
| + content::SynchronousCompositor::SetGpuService(g_service.Get());
|
| + }
|
| +}
|
| +
|
| +DeferredGpuCommandService::DeferredGpuCommandService() {}
|
| +
|
| +DeferredGpuCommandService::~DeferredGpuCommandService() {
|
| + base::AutoLock lock(tasks_lock_);
|
| + DCHECK(tasks_.empty());
|
| +}
|
| +
|
| +// static
|
| +void DeferredGpuCommandService::RequestProcessGLOnUIThread() {
|
| + SharedRendererState* renderer_state =
|
| + GLViewRendererManager::GetInstance()->GetMostRecentlyDrawn();
|
| + if (!renderer_state) {
|
| + LOG(ERROR) << "No hardware renderer. Deadlock likely";
|
| + return;
|
| + }
|
| + renderer_state->ClientRequestDrawGL();
|
| +}
|
| +
|
| +// Called from different threads!
|
| +void DeferredGpuCommandService::ScheduleTask(const base::Closure& task) {
|
| + {
|
| + base::AutoLock lock(tasks_lock_);
|
| + tasks_.push(task);
|
| + }
|
| + if (ScopedAllowGL::IsAllowed()) {
|
| + RunTasks();
|
| + } else {
|
| + RequestProcessGLOnUIThread();
|
| + }
|
| +}
|
| +
|
| +void DeferredGpuCommandService::ScheduleIdleWork(
|
| + const base::Closure& callback) {
|
| + // TODO(sievers): Should this do anything?
|
| +}
|
| +
|
| +bool DeferredGpuCommandService::UseVirtualizedGLContexts() { return true; }
|
| +
|
| +scoped_refptr<gpu::gles2::ShaderTranslatorCache>
|
| +DeferredGpuCommandService::shader_translator_cache() {
|
| + if (!shader_translator_cache_.get())
|
| + shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
|
| + return shader_translator_cache_;
|
| +}
|
| +
|
| +void DeferredGpuCommandService::RunTasks() {
|
| + bool has_more_tasks;
|
| + {
|
| + base::AutoLock lock(tasks_lock_);
|
| + has_more_tasks = tasks_.size() > 0;
|
| + }
|
| +
|
| + while (has_more_tasks) {
|
| + base::Closure task;
|
| + {
|
| + base::AutoLock lock(tasks_lock_);
|
| + task = tasks_.front();
|
| + tasks_.pop();
|
| + }
|
| + task.Run();
|
| + {
|
| + base::AutoLock lock(tasks_lock_);
|
| + has_more_tasks = tasks_.size() > 0;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void DeferredGpuCommandService::AddRef() const {
|
| + base::RefCountedThreadSafe<DeferredGpuCommandService>::AddRef();
|
| +}
|
| +
|
| +void DeferredGpuCommandService::Release() const {
|
| + base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
|
| +}
|
| +
|
| +} // namespace android_webview
|
|
|