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..0de385227a64423a9ca8aebfc75730e79dc5fef6 |
--- /dev/null |
+++ b/ui/compositor/test/in_process_context_provider.cc |
@@ -0,0 +1,273 @@ |
+// 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 { |
+ |
+//const int kNoLimit = 0; |
jamesr
2015/01/21 21:39:05
delete
tfarina
2015/01/21 21:53:35
Done.
|
+ |
+// 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 |
+ |
+class InProcessContextProvider::LostContextCallbackProxy |
jamesr
2015/01/21 21:39:05
delete this class, you don't need it
tfarina
2015/01/21 21:53:35
Done.
|
+ : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback { |
+ public: |
+ explicit LostContextCallbackProxy(InProcessContextProvider* provider) |
+ : provider_(provider) { |
+ //provider_->context3d_->setContextLostCallback(this); |
+ } |
+ |
+ virtual ~LostContextCallbackProxy() { |
+ //provider_->context3d_->setContextLostCallback(NULL); |
+ } |
+ |
+ virtual void onContextLost() { |
+ provider_->OnLostContext(); |
+ } |
+ |
+ private: |
+ InProcessContextProvider* provider_; |
+}; |
+ |
+// static |
+scoped_refptr<InProcessContextProvider> InProcessContextProvider::Create( |
+ const blink::WebGraphicsContext3D::Attributes& attributes, |
jamesr
2015/01/21 21:39:05
don't use this type. are there any attributes that
tfarina
2015/01/21 21:53:35
I don't know how to answer that yet. I'm thinking
|
+ 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), |
+ 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 (lost_context_callback_proxy_) |
+ return true; |
+ |
+ 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_->traceBeginCHROMIUM("gpu_toplevel", |
jamesr
2015/01/21 21:39:05
do
context_->TraceBeginCHROMIUM(....)
tfarina
2015/01/21 21:53:35
../../../ui/compositor/test/in_process_context_pro
|
+ // unique_context_name.c_str()); |
+ |
+ lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); |
+ return true; |
+} |
+ |
+void InProcessContextProvider::InitializeCapabilities() { |
+ capabilities_.gpu = context_->GetImplementation()->capabilities(); |
+ |
+// size_t mapped_memory_limit = context3d_->GetMappedMemoryLimit(); |
jamesr
2015/01/21 21:39:05
you don't care about this, just delete the block
tfarina
2015/01/21 21:53:35
Done.
|
+// capabilities_.max_transfer_buffer_usage_bytes = |
+// mapped_memory_limit == kNoLimit ? std::numeric_limits<size_t>::max() |
+// : mapped_memory_limit; |
+} |
+ |
+cc::ContextProvider::Capabilities |
+InProcessContextProvider::ContextCapabilities() { |
+ DCHECK(lost_context_callback_proxy_); // Is bound to thread. |
+ DCHECK(context_thread_checker_.CalledOnValidThread()); |
+ return capabilities_; |
+} |
+ |
+::gpu::gles2::GLES2Interface* InProcessContextProvider::ContextGL() { |
+ DCHECK(lost_context_callback_proxy_); // Is bound to thread. |
+ DCHECK(context_thread_checker_.CalledOnValidThread()); |
+ |
+ return context_->GetImplementation(); |
+} |
+ |
+::gpu::ContextSupport* InProcessContextProvider::ContextSupport() { |
+ if (!lost_context_callback_proxy_) |
+ return NULL; // Not bound to anything. |
+ |
+ 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(lost_context_callback_proxy_); // Is bound to thread. |
+ 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(lost_context_callback_proxy_); // Is bound to thread. |
+ 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(); |
+ } |
+} |
+ |
+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(); |
+} |
+ |
+bool InProcessContextProvider::DestroyedOnMainThread() { |
+ DCHECK(main_thread_checker_.CalledOnValidThread()); |
+ |
+ base::AutoLock lock(destroyed_lock_); |
+ return destroyed_; |
+} |
+ |
+void InProcessContextProvider::SetLostContextCallback( |
+ const LostContextCallback& lost_context_callback) { |
+ DCHECK(context_thread_checker_.CalledOnValidThread()); |
+ DCHECK(lost_context_callback_.is_null() || |
+ lost_context_callback.is_null()); |
+ 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. |
+} |
+ |
+} // namespace ui |