12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/gpu/client/context_provider_command_buffer.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "base/callback_helpers.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/gpu/grcontext_for_webgraphicscontext3d.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ContextProviderCommandBuffer::LostContextCallbackProxy 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit LostContextCallbackProxy(ContextProviderCommandBuffer* provider) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : provider_(provider) { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider_->context3d_->setContextLostCallback(this); 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual ~LostContextCallbackProxy() { 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch provider_->context3d_->setContextLostCallback(NULL); 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void onContextLost() { 25fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch provider_->OnLostContext(); 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextProviderCommandBuffer* provider_; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ContextProviderCommandBuffer::MemoryAllocationCallbackProxy 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public WebKit::WebGraphicsContext3D:: 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebGraphicsMemoryAllocationChangedCallbackCHROMIUM { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit MemoryAllocationCallbackProxy(ContextProviderCommandBuffer* provider) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : provider_(provider) { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider_->context3d_->setMemoryAllocationChangedCallbackCHROMIUM(this); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual ~MemoryAllocationCallbackProxy() { 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch provider_->context3d_->setMemoryAllocationChangedCallbackCHROMIUM(NULL); 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void onMemoryAllocationChanged( 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebKit::WebGraphicsMemoryAllocation alloc) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider_->OnMemoryAllocationChanged(!!alloc.gpuResourceSizeInBytes); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ContextProviderCommandBuffer* provider_; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 54fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochscoped_refptr<ContextProviderCommandBuffer> 55fb250657ef40d7500f20882d5c9909c1013367d3Ben MurdochContextProviderCommandBuffer::Create(const CreateCallback& create_callback) { 56fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch scoped_refptr<ContextProviderCommandBuffer> provider = 57fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch new ContextProviderCommandBuffer; 58fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch if (!provider->InitializeOnMainThread(create_callback)) 59fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch return NULL; 60fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch return provider; 61fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch} 62fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ContextProviderCommandBuffer::ContextProviderCommandBuffer() 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : leak_on_destroy_(false), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) destroyed_(false) { 66fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(main_thread_checker_.CalledOnValidThread()); 67fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch context_thread_checker_.DetachFromThread(); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ContextProviderCommandBuffer::~ContextProviderCommandBuffer() { 71fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(main_thread_checker_.CalledOnValidThread() || 72fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch context_thread_checker_.CalledOnValidThread()); 73fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock lock(main_thread_lock_); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (leak_on_destroy_) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebGraphicsContext3DCommandBufferImpl* context3d ALLOW_UNUSED = 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context3d_.release(); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webkit::gpu::GrContextForWebGraphicsContext3D* gr_context ALLOW_UNUSED = 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gr_context_.release(); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 83fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochbool ContextProviderCommandBuffer::InitializeOnMainThread( 84fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch const CreateCallback& create_callback) { 85fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(main_thread_checker_.CalledOnValidThread()); 86fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!context3d_); 88fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(!create_callback.is_null()); 89fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch context3d_ = create_callback.Run(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !!context3d_; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextProviderCommandBuffer::BindToCurrentThread() { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context3d_); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 96fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch // This is called on the thread the context will be used. 97fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 98fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (lost_context_callback_proxy_) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context3d_->makeContextCurrent()) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lost_context_callback_proxy_.reset(new LostContextCallbackProxy(this)); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebGraphicsContext3DCommandBufferImpl* 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ContextProviderCommandBuffer::Context3d() { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context3d_); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(lost_context_callback_proxy_); // Is bound to thread. 113fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return context3d_.get(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GrContext* ContextProviderCommandBuffer::GrContext() { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context3d_); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(lost_context_callback_proxy_); // Is bound to thread. 121fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gr_context_) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gr_context_->get(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gr_context_.reset( 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new webkit::gpu::GrContextForWebGraphicsContext3D(context3d_.get())); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_allocation_callback_proxy_.reset( 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new MemoryAllocationCallbackProxy(this)); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gr_context_->get(); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextProviderCommandBuffer::VerifyContexts() { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context3d_); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(lost_context_callback_proxy_); // Is bound to thread. 136fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context3d_->isContextLost()) 139fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch OnLostContext(); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 142fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid ContextProviderCommandBuffer::OnLostContext() { 143fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock lock(main_thread_lock_); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (destroyed_) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) destroyed_ = true; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 150fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch if (!lost_context_callback_.is_null()) 151fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch base::ResetAndReturn(&lost_context_callback_).Run(); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextProviderCommandBuffer::DestroyedOnMainThread() { 155fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(main_thread_checker_.CalledOnValidThread()); 156fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock lock(main_thread_lock_); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return destroyed_; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 161fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid ContextProviderCommandBuffer::SetLostContextCallback( 162fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch const LostContextCallback& lost_context_callback) { 163fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 164fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(lost_context_callback_.is_null()); 165fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch lost_context_callback_ = lost_context_callback; 166fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch} 167fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextProviderCommandBuffer::OnMemoryAllocationChanged( 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool nonzero_allocation) { 170fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch DCHECK(context_thread_checker_.CalledOnValidThread()); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (gr_context_) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gr_context_->SetMemoryLimit(nonzero_allocation); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 176