1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/atomic_sequence_num.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace content { 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::StaticAtomicSequenceNumber g_next_buffer_id; 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Noop() { 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuMemoryBufferCreated( 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Size& size, 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GpuMemoryBufferImpl::CreationCallback& callback, 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::GpuMemoryBufferHandle& handle) { 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(gfx::IO_SURFACE_BUFFER, handle.type); 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(GpuMemoryBufferImplIOSurface::CreateFromHandle( 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle, size, internalformat, base::Bind(&Noop))); 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuMemoryBufferCreatedForChildProcess( 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GpuMemoryBufferImpl::AllocationCallback& callback, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::GpuMemoryBufferHandle& handle) { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(gfx::IO_SURFACE_BUFFER, handle.type); 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(handle); 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GpuMemoryBufferImplIOSurface::GpuMemoryBufferImplIOSurface( 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const gfx::Size& size, 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DestructionCallback& callback, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IOSurfaceRef io_surface) 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : GpuMemoryBufferImpl(size, internalformat, callback), 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_surface_(io_surface) { 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGpuMemoryBufferImplIOSurface::~GpuMemoryBufferImplIOSurface() { 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuMemoryBufferImplIOSurface::Create(const gfx::Size& size, 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned usage, 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int client_id, 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const CreationCallback& callback) { 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::GpuMemoryBufferHandle handle; 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle.type = gfx::IO_SURFACE_BUFFER; 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle.global_id.primary_id = g_next_buffer_id.GetNext(); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle.global_id.secondary_id = client_id; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer( 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle, 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size, 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci internalformat, 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci usage, 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&GpuMemoryBufferCreated, size, internalformat, callback)); 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuMemoryBufferImplIOSurface::AllocateForChildProcess( 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Size& size, 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned usage, 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int child_client_id, 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const AllocationCallback& callback) { 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::GpuMemoryBufferHandle handle; 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle.type = gfx::IO_SURFACE_BUFFER; 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle.global_id.primary_id = g_next_buffer_id.GetNext(); 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle.global_id.secondary_id = child_client_id; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer( 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size, 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci internalformat, 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci usage, 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&GpuMemoryBufferCreatedForChildProcess, callback)); 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImplIOSurface::CreateFromHandle( 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::GpuMemoryBufferHandle& handle, 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const gfx::Size& size, 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned internalformat, 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DestructionCallback& callback) { 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(IsFormatSupported(internalformat)); 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ScopedCFTypeRef<IOSurfaceRef> io_surface( 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IOSurfaceLookup(handle.io_surface_id)); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!io_surface) 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return scoped_ptr<GpuMemoryBufferImpl>(); 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return make_scoped_ptr<GpuMemoryBufferImpl>(new GpuMemoryBufferImplIOSurface( 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size, internalformat, callback, io_surface.get())); 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool GpuMemoryBufferImplIOSurface::IsFormatSupported(unsigned internalformat) { 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (internalformat) { 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case GL_BGRA8_EXT: 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) default: 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool GpuMemoryBufferImplIOSurface::IsUsageSupported(unsigned usage) { 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) switch (usage) { 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case GL_IMAGE_MAP_CHROMIUM: 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) default: 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool GpuMemoryBufferImplIOSurface::IsConfigurationSupported( 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unsigned internalformat, 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unsigned usage) { 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return IsFormatSupported(internalformat) && IsUsageSupported(usage); 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)uint32 GpuMemoryBufferImplIOSurface::PixelFormat(unsigned internalformat) { 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (internalformat) { 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case GL_BGRA8_EXT: 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 'BGRA'; 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) default: 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) NOTREACHED(); 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 0; 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void* GpuMemoryBufferImplIOSurface::Map() { 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!mapped_); 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IOSurfaceLock(io_surface_, 0, NULL); 149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mapped_ = true; 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return IOSurfaceGetBaseAddress(io_surface_); 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GpuMemoryBufferImplIOSurface::Unmap() { 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(mapped_); 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IOSurfaceUnlock(io_surface_, 0, NULL); 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mapped_ = false; 157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)uint32 GpuMemoryBufferImplIOSurface::GetStride() const { 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return IOSurfaceGetBytesPerRow(io_surface_); 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::GpuMemoryBufferHandle GpuMemoryBufferImplIOSurface::GetHandle() const { 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::GpuMemoryBufferHandle handle; 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) handle.type = gfx::IO_SURFACE_BUFFER; 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) handle.io_surface_id = IOSurfaceGetID(io_surface_); 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return handle; 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace content 171