Index: ui/compositor/test/in_process_context_provider.cc |
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 0000000000000000000000000000000000000000..9098bc0f1ff599f42b1bbb293578af0a89a4e382 |
--- /dev/null |
+++ b/ui/compositor/test/in_process_context_provider.cc |
@@ -0,0 +1,217 @@ |
+// 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); |
+}; |
+ |
+void ConvertAttributes( |
+ const blink::WebGraphicsContext3D::Attributes& attributes, |
+ gpu::gles2::ContextCreationAttribHelper* output_attribs) { |
+ output_attribs->alpha_size = attributes.alpha ? 8 : 0; |
+ output_attribs->depth_size = attributes.depth ? 24 : 0; |
+ output_attribs->stencil_size = attributes.stencil ? 8 : 0; |
+ output_attribs->samples = attributes.antialias ? 4 : 0; |
+ output_attribs->sample_buffers = attributes.antialias ? 1 : 0; |
+ output_attribs->fail_if_major_perf_caveat = |
+ attributes.failIfMajorPerformanceCaveat; |
+ output_attribs->bind_generates_resource = false; |
+} |
+ |
+base::LazyInstance<GLES2Initializer> g_gles2_initializer = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+} // namespace |
+ |
+// static |
+scoped_refptr<InProcessContextProvider> InProcessContextProvider::Create( |
+ const blink::WebGraphicsContext3D::Attributes& attributes, |
+ bool lose_context_when_out_of_memory, |
+ gfx::AcceleratedWidget window, |
+ const std::string& debug_name) { |
+ return new InProcessContextProvider( |
+ attributes, lose_context_when_out_of_memory, window, debug_name); |
+} |
+ |
+// static |
+scoped_refptr<InProcessContextProvider> |
+InProcessContextProvider::CreateOffscreen( |
+ bool lose_context_when_out_of_memory) { |
+ blink::WebGraphicsContext3D::Attributes attributes; |
+ attributes.depth = false; |
+ attributes.stencil = true; |
+ attributes.antialias = false; |
+ attributes.shareResources = true; |
+ attributes.noAutomaticFlushes = true; |
+ |
+ return InProcessContextProvider::Create( |
+ attributes, lose_context_when_out_of_memory, gfx::kNullAcceleratedWidget, |
+ "Offscreen"); |
+} |
+ |
+InProcessContextProvider::InProcessContextProvider( |
+ const blink::WebGraphicsContext3D::Attributes& attributes, |
+ bool lose_context_when_out_of_memory, |
+ gfx::AcceleratedWidget window, |
+ const std::string& debug_name) |
+ : lose_context_when_out_of_memory_(lose_context_when_out_of_memory), |
+ share_resources_(attributes.shareResources), |
piman
2015/01/21 22:37:39
This is always true, so you can remove.
tfarina
2015/01/22 00:05:32
Done.
|
+ window_(window), |
+ destroyed_(false), |
+ debug_name_(debug_name) { |
+ DCHECK(main_thread_checker_.CalledOnValidThread()); |
+ context_thread_checker_.DetachFromThread(); |
+ |
+ ConvertAttributes(attributes, &attributes_); |
+} |
+ |
+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 */ |
+ share_resources_, |
+ attributes_, |
+ gpu_preference, |
+ gpu::GLInProcessContextSharedMemoryLimits(), |
+ nullptr, |
+ nullptr)); |
+ } |
+ |
+ InitializeCapabilities(); |
+ |
+ 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; |
+} |
+ |
+void InProcessContextProvider::InitializeCapabilities() { |
+ capabilities_.gpu = context_->GetImplementation()->capabilities(); |
piman
2015/01/21 22:37:39
nit: you can simply do this in InProcessContextPro
tfarina
2015/01/22 00:05:32
Done.
|
+} |
+ |
+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()); |
+ |
+ return true; |
+} |
+ |
+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) { |
piman
2015/01/21 22:37:39
You need do keep the lost_context_callback around
tfarina
2015/01/22 00:05:32
Done.
piman
2015/01/22 00:18:17
I would expect lost_context_callback_ = lost_conte
|
+} |
+ |
+void InProcessContextProvider::SetMemoryPolicyChangedCallback( |
+ const MemoryPolicyChangedCallback& memory_policy_changed_callback) { |
+ // There's no memory manager for the in-process implementation. |
+} |
+ |
+} // namespace ui |