Add ICU message format support
[chromium-blink-merge.git] / content / common / gpu / client / context_provider_command_buffer.cc
blobba9f0ebfbed6a6f75196c29a7bf89da933557773
1 // Copyright (c) 2013 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.
5 #include "content/common/gpu/client/context_provider_command_buffer.h"
7 #include <set>
8 #include <vector>
10 #include "base/callback_helpers.h"
11 #include "base/strings/stringprintf.h"
12 #include "cc/output/managed_memory_policy.h"
13 #include "content/common/gpu/client/grcontext_for_webgraphicscontext3d.h"
14 #include "gpu/command_buffer/client/gles2_implementation.h"
15 #include "third_party/skia/include/gpu/GrContext.h"
17 namespace content {
19 class ContextProviderCommandBuffer::LostContextCallbackProxy
20 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
21 public:
22 explicit LostContextCallbackProxy(ContextProviderCommandBuffer* provider)
23 : provider_(provider) {
24 provider_->context3d_->setContextLostCallback(this);
27 virtual ~LostContextCallbackProxy() {
28 provider_->context3d_->setContextLostCallback(NULL);
31 virtual void onContextLost() {
32 provider_->OnLostContext();
35 private:
36 ContextProviderCommandBuffer* provider_;
39 scoped_refptr<ContextProviderCommandBuffer>
40 ContextProviderCommandBuffer::Create(
41 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d,
42 CommandBufferContextType type) {
43 if (!context3d)
44 return NULL;
46 return new ContextProviderCommandBuffer(context3d.Pass(), type);
49 ContextProviderCommandBuffer::ContextProviderCommandBuffer(
50 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3d,
51 CommandBufferContextType type)
52 : context3d_(context3d.Pass()),
53 context_type_(type),
54 debug_name_(CommandBufferContextTypeToString(type)),
55 destroyed_(false) {
56 DCHECK(main_thread_checker_.CalledOnValidThread());
57 DCHECK(context3d_);
58 context_thread_checker_.DetachFromThread();
61 ContextProviderCommandBuffer::~ContextProviderCommandBuffer() {
62 DCHECK(main_thread_checker_.CalledOnValidThread() ||
63 context_thread_checker_.CalledOnValidThread());
65 base::AutoLock lock(main_thread_lock_);
67 // Destroy references to the context3d_ before leaking it.
68 if (context3d_->GetCommandBufferProxy()) {
69 context3d_->GetCommandBufferProxy()->SetLock(nullptr);
70 context3d_->GetCommandBufferProxy()->SetMemoryAllocationChangedCallback(
71 CommandBufferProxyImpl::MemoryAllocationChangedCallback());
73 lost_context_callback_proxy_.reset();
77 CommandBufferProxyImpl* ContextProviderCommandBuffer::GetCommandBufferProxy() {
78 return context3d_->GetCommandBufferProxy();
81 WebGraphicsContext3DCommandBufferImpl*
82 ContextProviderCommandBuffer::WebContext3D() {
83 DCHECK(context3d_);
84 DCHECK(lost_context_callback_proxy_); // Is bound to thread.
85 DCHECK(context_thread_checker_.CalledOnValidThread());
87 return context3d_.get();
90 bool ContextProviderCommandBuffer::BindToCurrentThread() {
91 // This is called on the thread the context will be used.
92 DCHECK(context_thread_checker_.CalledOnValidThread());
94 if (lost_context_callback_proxy_)
95 return true;
97 context3d_->SetContextType(context_type_);
98 if (!context3d_->InitializeOnCurrentThread())
99 return false;
101 InitializeCapabilities();
103 std::string unique_context_name =
104 base::StringPrintf("%s-%p", debug_name_.c_str(), context3d_.get());
105 context3d_->traceBeginCHROMIUM("gpu_toplevel", unique_context_name.c_str());
107 lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this));
108 return true;
111 void ContextProviderCommandBuffer::DetachFromThread() {
112 context_thread_checker_.DetachFromThread();
115 gpu::gles2::GLES2Interface* ContextProviderCommandBuffer::ContextGL() {
116 DCHECK(context3d_);
117 DCHECK(lost_context_callback_proxy_); // Is bound to thread.
118 DCHECK(context_thread_checker_.CalledOnValidThread());
120 return context3d_->GetImplementation();
123 gpu::ContextSupport* ContextProviderCommandBuffer::ContextSupport() {
124 return context3d_->GetContextSupport();
127 class GrContext* ContextProviderCommandBuffer::GrContext() {
128 DCHECK(lost_context_callback_proxy_); // Is bound to thread.
129 DCHECK(context_thread_checker_.CalledOnValidThread());
131 if (gr_context_)
132 return gr_context_->get();
134 gr_context_.reset(new GrContextForWebGraphicsContext3D(context3d_.get()));
136 // If GlContext is already lost, also abandon the new GrContext.
137 if (gr_context_->get() &&
138 ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
139 gr_context_->get()->abandonContext();
141 return gr_context_->get();
144 void ContextProviderCommandBuffer::InvalidateGrContext(uint32_t state) {
145 if (gr_context_) {
146 DCHECK(lost_context_callback_proxy_); // Is bound to thread.
147 DCHECK(context_thread_checker_.CalledOnValidThread());
148 gr_context_->get()->resetContext(state);
152 void ContextProviderCommandBuffer::SetupLock() {
153 DCHECK(context3d_);
154 context3d_->GetCommandBufferProxy()->SetLock(&context_lock_);
157 base::Lock* ContextProviderCommandBuffer::GetLock() {
158 return &context_lock_;
161 cc::ContextProvider::Capabilities
162 ContextProviderCommandBuffer::ContextCapabilities() {
163 DCHECK(lost_context_callback_proxy_); // Is bound to thread.
164 DCHECK(context_thread_checker_.CalledOnValidThread());
166 return capabilities_;
169 void ContextProviderCommandBuffer::VerifyContexts() {
170 DCHECK(lost_context_callback_proxy_); // Is bound to thread.
171 DCHECK(context_thread_checker_.CalledOnValidThread());
173 if (ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
174 OnLostContext();
177 void ContextProviderCommandBuffer::DeleteCachedResources() {
178 DCHECK(context_thread_checker_.CalledOnValidThread());
180 if (gr_context_)
181 gr_context_->FreeGpuResources();
184 void ContextProviderCommandBuffer::OnLostContext() {
185 DCHECK(context_thread_checker_.CalledOnValidThread());
187 base::AutoLock lock(main_thread_lock_);
188 if (destroyed_)
189 return;
190 destroyed_ = true;
192 if (!lost_context_callback_.is_null())
193 base::ResetAndReturn(&lost_context_callback_).Run();
194 if (gr_context_)
195 gr_context_->OnLostContext();
198 void ContextProviderCommandBuffer::OnMemoryAllocationChanged(
199 const gpu::MemoryAllocation& allocation) {
200 DCHECK(context_thread_checker_.CalledOnValidThread());
202 if (memory_policy_changed_callback_.is_null())
203 return;
205 memory_policy_changed_callback_.Run(cc::ManagedMemoryPolicy(allocation));
208 void ContextProviderCommandBuffer::InitializeCapabilities() {
209 Capabilities caps;
210 caps.gpu = context3d_->GetImplementation()->capabilities();
212 size_t mapped_memory_limit = context3d_->GetMappedMemoryLimit();
213 caps.max_transfer_buffer_usage_bytes =
214 mapped_memory_limit == WebGraphicsContext3DCommandBufferImpl::kNoLimit
215 ? std::numeric_limits<size_t>::max() : mapped_memory_limit;
217 capabilities_ = caps;
220 bool ContextProviderCommandBuffer::DestroyedOnMainThread() {
221 DCHECK(main_thread_checker_.CalledOnValidThread());
223 base::AutoLock lock(main_thread_lock_);
224 return destroyed_;
227 void ContextProviderCommandBuffer::SetLostContextCallback(
228 const LostContextCallback& lost_context_callback) {
229 DCHECK(context_thread_checker_.CalledOnValidThread());
230 DCHECK(lost_context_callback_.is_null() ||
231 lost_context_callback.is_null());
232 lost_context_callback_ = lost_context_callback;
235 void ContextProviderCommandBuffer::SetMemoryPolicyChangedCallback(
236 const MemoryPolicyChangedCallback& memory_policy_changed_callback) {
237 DCHECK(context_thread_checker_.CalledOnValidThread());
238 DCHECK(memory_policy_changed_callback_.is_null() ||
239 memory_policy_changed_callback.is_null());
240 memory_policy_changed_callback_ = memory_policy_changed_callback;
242 if (!memory_policy_changed_callback_.is_null()) {
243 DCHECK(context3d_->GetCommandBufferProxy());
244 context3d_->GetCommandBufferProxy()->SetMemoryAllocationChangedCallback(
245 base::Bind(&ContextProviderCommandBuffer::OnMemoryAllocationChanged,
246 base::Unretained(this)));
250 } // namespace content