diff options
author | tfarina <tfarina@chromium.org> | 2015-01-24 08:00:45 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-24 16:01:41 +0000 |
commit | bca2a0be0924009ef5f8dc0e299c0efbb95a4d67 (patch) | |
tree | bbd961cedbcf8255df1b98119bbd28ac39cd34da | |
parent | a95182ddbaa0e0e0a2504a0c4e0954f62cd9791c (diff) | |
download | chromium_src-bca2a0be0924009ef5f8dc0e299c0efbb95a4d67.zip chromium_src-bca2a0be0924009ef5f8dc0e299c0efbb95a4d67.tar.gz chromium_src-bca2a0be0924009ef5f8dc0e299c0efbb95a4d67.tar.bz2 |
ui/compositor: Provide its own 'in process' ContextProvider.
InProcessContextProvider is twin brother of the ContextProviderInProcess
from webkit/common/gpu. We built one here specifically for compositor
in order to remove the dependency on webkit/.
We did that for some reasons: one is that webkit/ abstraction glue is going
away, the second is that compositor can't depend on content, and thus we
couldn't simply move the code into content and make compositor use it.
BUG=338338
TEST=compositor_unittests
R=piman@chromium.org
TBR=reed@google.com (for skia/ext deps addition)
Review URL: https://codereview.chromium.org/853353003
Cr-Commit-Position: refs/heads/master@{#313022}
-rw-r--r-- | ui/compositor/BUILD.gn | 4 | ||||
-rw-r--r-- | ui/compositor/compositor.gyp | 4 | ||||
-rw-r--r-- | ui/compositor/test/DEPS | 5 | ||||
-rw-r--r-- | ui/compositor/test/in_process_context_factory.cc | 37 | ||||
-rw-r--r-- | ui/compositor/test/in_process_context_factory.h | 9 | ||||
-rw-r--r-- | ui/compositor/test/in_process_context_provider.cc | 224 | ||||
-rw-r--r-- | ui/compositor/test/in_process_context_provider.h | 85 |
7 files changed, 335 insertions, 33 deletions
diff --git a/ui/compositor/BUILD.gn b/ui/compositor/BUILD.gn index 414a64a..6436712 100644 --- a/ui/compositor/BUILD.gn +++ b/ui/compositor/BUILD.gn @@ -88,6 +88,8 @@ source_set("test_support") { "test/draw_waiter_for_test.h", "test/in_process_context_factory.cc", "test/in_process_context_factory.h", + "test/in_process_context_provider.cc", + "test/in_process_context_provider.h", "test/layer_animator_test_controller.cc", "test/layer_animator_test_controller.h", "test/test_compositor_host.h", @@ -113,7 +115,6 @@ source_set("test_support") { "//cc", "//cc/surfaces", "//cc:test_support", - "//gpu/blink", "//skia", "//testing/gtest", "//third_party/WebKit/public:blink_minimal", @@ -121,7 +122,6 @@ source_set("test_support") { "//ui/gfx", "//ui/gfx/geometry", "//ui/gl", - "//webkit/common/gpu", ] if (use_x11) { diff --git a/ui/compositor/compositor.gyp b/ui/compositor/compositor.gyp index c8c7dba6..796fb40 100644 --- a/ui/compositor/compositor.gyp +++ b/ui/compositor/compositor.gyp @@ -90,7 +90,6 @@ '<(DEPTH)/cc/cc.gyp:cc', '<(DEPTH)/cc/cc.gyp:cc_surfaces', '<(DEPTH)/cc/cc_tests.gyp:cc_test_support', - '<(DEPTH)/gpu/blink/gpu_blink.gyp:gpu_blink', '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/testing/gtest.gyp:gtest', '<(DEPTH)/third_party/WebKit/public/blink.gyp:blink_minimal', @@ -98,7 +97,6 @@ '<(DEPTH)/ui/gfx/gfx.gyp:gfx', '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry', '<(DEPTH)/ui/gl/gl.gyp:gl', - '<(DEPTH)/webkit/common/gpu/webkit_gpu.gyp:webkit_gpu', 'compositor', ], 'sources': [ @@ -108,6 +106,8 @@ 'test/draw_waiter_for_test.h', 'test/in_process_context_factory.cc', 'test/in_process_context_factory.h', + 'test/in_process_context_provider.cc', + 'test/in_process_context_provider.h', 'test/layer_animator_test_controller.cc', 'test/layer_animator_test_controller.h', 'test/test_compositor_host.h', diff --git a/ui/compositor/test/DEPS b/ui/compositor/test/DEPS index 7f9b273..bc87fe1 100644 --- a/ui/compositor/test/DEPS +++ b/ui/compositor/test/DEPS @@ -1,5 +1,6 @@ include_rules = [ - "+gpu/blink", "+gpu/command_buffer/client", - "+webkit/common/gpu", + "+gpu/command_buffer/common", + "+gpu/skia_bindings", + "+skia/ext", ] diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index e471814..d51120a 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc @@ -13,14 +13,14 @@ #include "cc/surfaces/surface_id_allocator.h" #include "cc/test/pixel_test_output_surface.h" #include "cc/test/test_shared_bitmap_manager.h" -#include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "ui/compositor/compositor_switches.h" #include "ui/compositor/reflector.h" +#include "ui/compositor/test/in_process_context_provider.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface.h" -#include "webkit/common/gpu/context_provider_in_process.h" namespace ui { namespace { @@ -86,22 +86,22 @@ void InProcessContextFactory::CreateOutputSurface( base::WeakPtr<Compositor> compositor, bool software_fallback) { DCHECK(!software_fallback); - blink::WebGraphicsContext3D::Attributes attrs; - attrs.depth = false; - attrs.stencil = false; - attrs.antialias = false; - attrs.shareResources = true; + gpu::gles2::ContextCreationAttribHelper attribs; + attribs.alpha_size = 8; + attribs.blue_size = 8; + attribs.green_size = 8; + attribs.red_size = 8; + attribs.depth_size = 0; + attribs.stencil_size = 0; + attribs.samples = 0; + attribs.sample_buffers = 0; + attribs.fail_if_major_perf_caveat = false; + attribs.bind_generates_resource = false; bool lose_context_when_out_of_memory = true; - using gpu_blink::WebGraphicsContext3DInProcessCommandBufferImpl; - scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d( - WebGraphicsContext3DInProcessCommandBufferImpl::CreateViewContext( - attrs, lose_context_when_out_of_memory, compositor->widget())); - CHECK(context3d); - - using webkit::gpu::ContextProviderInProcess; - scoped_refptr<ContextProviderInProcess> context_provider = - ContextProviderInProcess::Create(context3d.Pass(), "UICompositor"); + scoped_refptr<InProcessContextProvider> context_provider = + InProcessContextProvider::Create(attribs, lose_context_when_out_of_memory, + compositor->widget(), "UICompositor"); if (use_test_surface_) { bool flipped_output_surface = false; @@ -129,9 +129,8 @@ InProcessContextFactory::SharedMainThreadContextProvider() { return shared_main_thread_contexts_; bool lose_context_when_out_of_memory = false; - shared_main_thread_contexts_ = - webkit::gpu::ContextProviderInProcess::CreateOffscreen( - lose_context_when_out_of_memory); + shared_main_thread_contexts_ = InProcessContextProvider::CreateOffscreen( + lose_context_when_out_of_memory); if (shared_main_thread_contexts_.get() && !shared_main_thread_contexts_->BindToCurrentThread()) shared_main_thread_contexts_ = NULL; diff --git a/ui/compositor/test/in_process_context_factory.h b/ui/compositor/test/in_process_context_factory.h index 23f7d48..7ac9f92 100644 --- a/ui/compositor/test/in_process_context_factory.h +++ b/ui/compositor/test/in_process_context_factory.h @@ -13,12 +13,6 @@ namespace base { class Thread; } -namespace webkit { -namespace gpu { -class ContextProviderWebContext; -} -} - namespace ui { class InProcessContextFactory : public ContextFactory { @@ -52,8 +46,7 @@ class InProcessContextFactory : public ContextFactory { private: scoped_ptr<base::Thread> compositor_thread_; - scoped_refptr<webkit::gpu::ContextProviderWebContext> - shared_main_thread_contexts_; + scoped_refptr<cc::ContextProvider> shared_main_thread_contexts_; cc::TestSharedBitmapManager shared_bitmap_manager_; cc::TestGpuMemoryBufferManager gpu_memory_buffer_manager_; uint32_t next_surface_id_namespace_; diff --git a/ui/compositor/test/in_process_context_provider.cc b/ui/compositor/test/in_process_context_provider.cc new file mode 100644 index 0000000..3ad2195 --- /dev/null +++ b/ui/compositor/test/in_process_context_provider.cc @@ -0,0 +1,224 @@ +// Copyright (c) 2013 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 "ui/compositor/test/in_process_context_provider.h" + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/debug/trace_event.h" +#include "base/lazy_instance.h" +#include "base/strings/stringprintf.h" +#include "cc/output/managed_memory_policy.h" +#include "gpu/command_buffer/client/gl_in_process_context.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/client/gles2_lib.h" +#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" +#include "third_party/skia/include/gpu/GrContext.h" +#include "third_party/skia/include/gpu/gl/GrGLInterface.h" + +namespace ui { + +namespace { + +// Singleton used to initialize and terminate the gles2 library. +class GLES2Initializer { + public: + GLES2Initializer() { gles2::Initialize(); } + + ~GLES2Initializer() { gles2::Terminate(); } + + private: + DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); +}; + +base::LazyInstance<GLES2Initializer> g_gles2_initializer = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + +// static +scoped_refptr<InProcessContextProvider> InProcessContextProvider::Create( + const gpu::gles2::ContextCreationAttribHelper& attribs, + bool lose_context_when_out_of_memory, + gfx::AcceleratedWidget window, + const std::string& debug_name) { + return new InProcessContextProvider( + attribs, lose_context_when_out_of_memory, window, debug_name); +} + +// static +scoped_refptr<InProcessContextProvider> +InProcessContextProvider::CreateOffscreen( + bool lose_context_when_out_of_memory) { + gpu::gles2::ContextCreationAttribHelper attribs; + attribs.alpha_size = 8; + attribs.blue_size = 8; + attribs.green_size = 8; + attribs.red_size = 8; + attribs.depth_size = 0; + attribs.stencil_size = 8; + attribs.samples = 0; + attribs.sample_buffers = 0; + attribs.fail_if_major_perf_caveat = false; + attribs.bind_generates_resource = false; + return new InProcessContextProvider( + attribs, lose_context_when_out_of_memory, gfx::kNullAcceleratedWidget, + "Offscreen"); +} + +InProcessContextProvider::InProcessContextProvider( + const gpu::gles2::ContextCreationAttribHelper& attribs, + bool lose_context_when_out_of_memory, + gfx::AcceleratedWidget window, + const std::string& debug_name) + : attribs_(attribs), + lose_context_when_out_of_memory_(lose_context_when_out_of_memory), + window_(window), + debug_name_(debug_name), + destroyed_(false) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + context_thread_checker_.DetachFromThread(); +} + +InProcessContextProvider::~InProcessContextProvider() { + DCHECK(main_thread_checker_.CalledOnValidThread() || + context_thread_checker_.CalledOnValidThread()); +} + +bool InProcessContextProvider::BindToCurrentThread() { + // This is called on the thread the context will be used. + DCHECK(context_thread_checker_.CalledOnValidThread()); + + if (!context_) { + gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; + context_.reset(gpu::GLInProcessContext::Create( + nullptr, /* service */ + nullptr, /* surface */ + true, /* is_offscreen */ + window_, + gfx::Size(1, 1), + nullptr, /* share_context */ + true, /* share_resources */ + attribs_, + gpu_preference, + gpu::GLInProcessContextSharedMemoryLimits(), + nullptr, + nullptr)); + + if (!context_) + return false; + + context_->SetContextLostCallback(base::Bind( + &InProcessContextProvider::OnLostContext, base::Unretained(this))); + } + + capabilities_.gpu = context_->GetImplementation()->capabilities(); + + std::string unique_context_name = + base::StringPrintf("%s-%p", debug_name_.c_str(), context_.get()); + context_->GetImplementation()->TraceBeginCHROMIUM( + "gpu_toplevel", unique_context_name.c_str()); + + return true; +} + +cc::ContextProvider::Capabilities +InProcessContextProvider::ContextCapabilities() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + return capabilities_; +} + +gpu::gles2::GLES2Interface* InProcessContextProvider::ContextGL() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + + return context_->GetImplementation(); +} + +gpu::ContextSupport* InProcessContextProvider::ContextSupport() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + + return context_->GetImplementation(); +} + +static void BindGrContextCallback(const GrGLInterface* interface) { + cc::ContextProvider* context_provider = + reinterpret_cast<InProcessContextProvider*>(interface->fCallbackData); + + gles2::SetGLContext(context_provider->ContextGL()); +} + +class GrContext* InProcessContextProvider::GrContext() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + + if (gr_context_) + return gr_context_.get(); + + // The GrGLInterface factory will make GL calls using the C GLES2 interface. + // Make sure the gles2 library is initialized first on exactly one thread. + g_gles2_initializer.Get(); + gles2::SetGLContext(ContextGL()); + + skia::RefPtr<GrGLInterface> interface = + skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding()); + interface->fCallback = BindGrContextCallback; + interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this); + + gr_context_ = skia::AdoptRef(GrContext::Create( + kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get()))); + + return gr_context_.get(); +} + +bool InProcessContextProvider::IsContextLost() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + + base::AutoLock lock(destroyed_lock_); + return destroyed_; +} + +void InProcessContextProvider::VerifyContexts() { +} + +void InProcessContextProvider::DeleteCachedResources() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + + if (gr_context_) { + TRACE_EVENT_INSTANT0("gpu", "GrContext::freeGpuResources", + TRACE_EVENT_SCOPE_THREAD); + gr_context_->freeGpuResources(); + } +} + +bool InProcessContextProvider::DestroyedOnMainThread() { + DCHECK(main_thread_checker_.CalledOnValidThread()); + + base::AutoLock lock(destroyed_lock_); + return destroyed_; +} + +void InProcessContextProvider::SetLostContextCallback( + const LostContextCallback& lost_context_callback) { + lost_context_callback_ = lost_context_callback; +} + +void InProcessContextProvider::SetMemoryPolicyChangedCallback( + const MemoryPolicyChangedCallback& memory_policy_changed_callback) { + // There's no memory manager for the in-process implementation. +} + +void InProcessContextProvider::OnLostContext() { + DCHECK(context_thread_checker_.CalledOnValidThread()); + { + base::AutoLock lock(destroyed_lock_); + if (destroyed_) + return; + destroyed_ = true; + } + if (!lost_context_callback_.is_null()) + base::ResetAndReturn(&lost_context_callback_).Run(); + if (gr_context_) + gr_context_->abandonContext(); +} + +} // namespace ui diff --git a/ui/compositor/test/in_process_context_provider.h b/ui/compositor/test/in_process_context_provider.h new file mode 100644 index 0000000..4b63ed4 --- /dev/null +++ b/ui/compositor/test/in_process_context_provider.h @@ -0,0 +1,85 @@ +// Copyright (c) 2013 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. + +#ifndef WEBKIT_COMMON_GPU_CONTEXT_PROVIDER_IN_PROCESS_H_ +#define WEBKIT_COMMON_GPU_CONTEXT_PROVIDER_IN_PROCESS_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" +#include "cc/output/context_provider.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "skia/ext/refptr.h" +#include "ui/gfx/native_widget_types.h" + +namespace gpu { +class GLInProcessContext; +} + +namespace ui { + +class InProcessContextProvider : public cc::ContextProvider { + public: + static scoped_refptr<InProcessContextProvider> Create( + const gpu::gles2::ContextCreationAttribHelper& attribs, + bool lose_context_when_out_of_memory, + gfx::AcceleratedWidget window, + const std::string& debug_name); + + // Uses default attributes for creating an offscreen context. + static scoped_refptr<InProcessContextProvider> CreateOffscreen( + bool lose_context_when_out_of_memory); + + private: + InProcessContextProvider( + const gpu::gles2::ContextCreationAttribHelper& attribs, + bool lose_context_when_out_of_memory, + gfx::AcceleratedWidget window, + const std::string& debug_name); + ~InProcessContextProvider() override; + + // cc::ContextProvider: + bool BindToCurrentThread() override; + Capabilities ContextCapabilities() override; + gpu::gles2::GLES2Interface* ContextGL() override; + gpu::ContextSupport* ContextSupport() override; + class GrContext* GrContext() override; + bool IsContextLost() override; + void VerifyContexts() override; + void DeleteCachedResources() override; + bool DestroyedOnMainThread() override; + void SetLostContextCallback( + const LostContextCallback& lost_context_callback) override; + void SetMemoryPolicyChangedCallback( + const MemoryPolicyChangedCallback& memory_policy_changed_callback) + override; + + void OnLostContext(); + + base::ThreadChecker main_thread_checker_; + base::ThreadChecker context_thread_checker_; + + scoped_ptr<gpu::GLInProcessContext> context_; + skia::RefPtr<class GrContext> gr_context_; + + gpu::gles2::ContextCreationAttribHelper attribs_; + bool lose_context_when_out_of_memory_; + gfx::AcceleratedWidget window_; + std::string debug_name_; + cc::ContextProvider::Capabilities capabilities_; + + LostContextCallback lost_context_callback_; + + base::Lock destroyed_lock_; + bool destroyed_; + + DISALLOW_COPY_AND_ASSIGN(InProcessContextProvider); +}; + +} // namespace ui + +#endif // WEBKIT_COMMON_GPU_CONTEXT_PROVIDER_IN_PROCESS_H_ |