2015-10-15 18:53:33 +03:00
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// * This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
# include "BufferTexture.h"
# include "mozilla/layers/ImageDataSerializer.h"
# include "mozilla/layers/ISurfaceAllocator.h"
2016-02-25 16:15:52 +03:00
# include "mozilla/layers/CompositableForwarder.h"
2015-10-15 18:53:33 +03:00
# include "mozilla/gfx/Logging.h"
# include "mozilla/gfx/2D.h"
# include "mozilla/fallible.h"
2016-03-18 23:58:55 +03:00
# include <algorithm>
2015-10-15 18:53:33 +03:00
2016-02-25 16:15:52 +03:00
# ifdef MOZ_WIDGET_GTK
# include "gfxPlatformGtk.h"
# endif
2015-10-15 18:53:33 +03:00
namespace mozilla {
namespace layers {
class MemoryTextureData : public BufferTextureData
{
public :
static MemoryTextureData * Create ( gfx : : IntSize aSize , gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend , TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ,
2016-03-21 17:18:20 +03:00
ClientIPCAllocator * aAllocator ) ;
2015-10-15 18:53:33 +03:00
virtual TextureData *
2016-03-21 17:18:20 +03:00
CreateSimilar ( ClientIPCAllocator * aAllocator ,
2015-10-15 18:53:33 +03:00
TextureFlags aFlags = TextureFlags : : DEFAULT ,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT ) const override ;
virtual bool Serialize ( SurfaceDescriptor & aOutDescriptor ) override ;
2016-03-21 17:18:20 +03:00
virtual void Deallocate ( ClientIPCAllocator * ) override ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
MemoryTextureData ( const BufferDescriptor & aDesc ,
2015-10-15 18:53:33 +03:00
gfx : : BackendType aMoz2DBackend ,
uint8_t * aBuffer , size_t aBufferSize )
2015-12-16 21:50:58 +03:00
: BufferTextureData ( aDesc , aMoz2DBackend )
2015-10-15 18:53:33 +03:00
, mBuffer ( aBuffer )
, mBufferSize ( aBufferSize )
{
MOZ_ASSERT ( aBuffer ) ;
MOZ_ASSERT ( aBufferSize ) ;
}
virtual uint8_t * GetBuffer ( ) override { return mBuffer ; }
virtual size_t GetBufferSize ( ) override { return mBufferSize ; }
protected :
uint8_t * mBuffer ;
size_t mBufferSize ;
} ;
class ShmemTextureData : public BufferTextureData
{
public :
static ShmemTextureData * Create ( gfx : : IntSize aSize , gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend , TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ,
2016-03-21 17:18:20 +03:00
ClientIPCAllocator * aAllocator ) ;
2015-10-15 18:53:33 +03:00
virtual TextureData *
2016-03-21 17:18:20 +03:00
CreateSimilar ( ClientIPCAllocator * aAllocator ,
2015-10-15 18:53:33 +03:00
TextureFlags aFlags = TextureFlags : : DEFAULT ,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT ) const override ;
virtual bool Serialize ( SurfaceDescriptor & aOutDescriptor ) override ;
2016-03-21 17:18:20 +03:00
virtual void Deallocate ( ClientIPCAllocator * aAllocator ) override ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
ShmemTextureData ( const BufferDescriptor & aDesc ,
2015-10-15 18:53:33 +03:00
gfx : : BackendType aMoz2DBackend , mozilla : : ipc : : Shmem aShmem )
2015-12-16 21:50:58 +03:00
: BufferTextureData ( aDesc , aMoz2DBackend )
2015-10-15 18:53:33 +03:00
, mShmem ( aShmem )
{
MOZ_ASSERT ( mShmem . Size < uint8_t > ( ) ) ;
}
virtual uint8_t * GetBuffer ( ) override { return mShmem . get < uint8_t > ( ) ; }
virtual size_t GetBufferSize ( ) override { return mShmem . Size < uint8_t > ( ) ; }
protected :
mozilla : : ipc : : Shmem mShmem ;
} ;
2016-02-25 16:15:52 +03:00
static bool UsingX11Compositor ( )
{
# ifdef MOZ_WIDGET_GTK
return gfxPlatformGtk : : GetPlatform ( ) - > UseXRender ( ) ;
# endif
return false ;
}
static bool ComputeHasIntermediateBuffer ( gfx : : SurfaceFormat aFormat ,
LayersBackend aLayersBackend )
{
return aLayersBackend ! = LayersBackend : : LAYERS_BASIC
| | UsingX11Compositor ( )
| | aFormat = = gfx : : SurfaceFormat : : UNKNOWN
| | aFormat = = gfx : : SurfaceFormat : : YUV
| | aFormat = = gfx : : SurfaceFormat : : NV12 ;
}
2015-10-15 18:53:33 +03:00
BufferTextureData *
BufferTextureData : : Create ( gfx : : IntSize aSize , gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend , TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ,
2016-03-21 17:18:20 +03:00
ClientIPCAllocator * aAllocator )
2015-10-15 18:53:33 +03:00
{
if ( ! aAllocator | | aAllocator - > IsSameProcess ( ) ) {
2016-02-25 16:15:52 +03:00
return MemoryTextureData : : Create ( aSize , aFormat , aMoz2DBackend , aFlags ,
aAllocFlags , aAllocator ) ;
2016-03-17 16:58:58 +03:00
} else if ( aAllocator - > AsShmemAllocator ( ) ) {
2016-02-25 16:15:52 +03:00
return ShmemTextureData : : Create ( aSize , aFormat , aMoz2DBackend , aFlags ,
aAllocFlags , aAllocator ) ;
2015-10-15 18:53:33 +03:00
}
2016-03-17 16:58:58 +03:00
return nullptr ;
2015-10-15 18:53:33 +03:00
}
BufferTextureData *
2016-03-21 17:18:20 +03:00
BufferTextureData : : CreateInternal ( ClientIPCAllocator * aAllocator ,
2015-12-16 21:50:58 +03:00
const BufferDescriptor & aDesc ,
gfx : : BackendType aMoz2DBackend ,
int32_t aBufferSize ,
TextureFlags aTextureFlags )
2015-10-15 18:53:33 +03:00
{
if ( ! aAllocator | | aAllocator - > IsSameProcess ( ) ) {
2015-12-16 21:50:58 +03:00
uint8_t * buffer = new ( fallible ) uint8_t [ aBufferSize ] ;
2015-10-15 18:53:33 +03:00
if ( ! buffer ) {
return nullptr ;
}
2016-01-06 05:26:29 +03:00
GfxMemoryImageReporter : : DidAlloc ( buffer ) ;
2015-12-16 21:50:58 +03:00
return new MemoryTextureData ( aDesc , aMoz2DBackend , buffer , aBufferSize ) ;
2016-03-17 16:58:58 +03:00
} else if ( aAllocator - > AsShmemAllocator ( ) ) {
2015-10-15 18:53:33 +03:00
ipc : : Shmem shm ;
2016-03-17 16:58:58 +03:00
if ( ! aAllocator - > AsShmemAllocator ( ) - > AllocUnsafeShmem ( aBufferSize , OptimalShmemType ( ) , & shm ) ) {
2015-10-15 18:53:33 +03:00
return nullptr ;
}
2015-12-16 21:50:58 +03:00
return new ShmemTextureData ( aDesc , aMoz2DBackend , shm ) ;
}
2016-03-17 16:58:58 +03:00
return nullptr ;
2015-12-16 21:50:58 +03:00
}
BufferTextureData *
2016-03-21 17:18:20 +03:00
BufferTextureData : : CreateForYCbCrWithBufferSize ( ClientIPCAllocator * aAllocator ,
2015-12-16 21:50:58 +03:00
gfx : : SurfaceFormat aFormat ,
int32_t aBufferSize ,
TextureFlags aTextureFlags )
{
if ( aBufferSize = = 0 | | ! gfx : : Factory : : CheckBufferSize ( aBufferSize ) ) {
return nullptr ;
2015-10-15 18:53:33 +03:00
}
// Initialize the metadata with something, even if it will have to be rewritten
// afterwards since we don't know the dimensions of the texture at this point.
2015-12-16 21:50:58 +03:00
BufferDescriptor desc = YCbCrDescriptor ( gfx : : IntSize ( ) , gfx : : IntSize ( ) ,
0 , 0 , 0 , StereoMode : : MONO ) ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
return CreateInternal ( aAllocator , desc , gfx : : BackendType : : NONE , aBufferSize ,
aTextureFlags ) ;
2015-10-15 18:53:33 +03:00
}
BufferTextureData *
2016-03-21 17:18:20 +03:00
BufferTextureData : : CreateForYCbCr ( ClientIPCAllocator * aAllocator ,
2015-10-15 18:53:33 +03:00
gfx : : IntSize aYSize ,
gfx : : IntSize aCbCrSize ,
StereoMode aStereoMode ,
TextureFlags aTextureFlags )
{
2015-12-16 21:50:58 +03:00
uint32_t bufSize = ImageDataSerializer : : ComputeYCbCrBufferSize ( aYSize , aCbCrSize ) ;
if ( bufSize = = 0 ) {
2015-10-15 18:53:33 +03:00
return nullptr ;
}
2015-12-16 21:50:58 +03:00
uint32_t yOffset ;
uint32_t cbOffset ;
uint32_t crOffset ;
ImageDataSerializer : : ComputeYCbCrOffsets ( aYSize . width , aYSize . height ,
aCbCrSize . width , aCbCrSize . height ,
yOffset , cbOffset , crOffset ) ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
YCbCrDescriptor descriptor = YCbCrDescriptor ( aYSize , aCbCrSize , yOffset , cbOffset ,
crOffset , aStereoMode ) ;
return CreateInternal ( aAllocator , descriptor , gfx : : BackendType : : NONE , bufSize ,
aTextureFlags ) ;
}
2016-04-22 19:05:26 +03:00
void
BufferTextureData : : FillInfo ( TextureData : : Info & aInfo ) const
2015-12-16 21:50:58 +03:00
{
2016-04-22 19:05:26 +03:00
aInfo . size = GetSize ( ) ;
aInfo . format = GetFormat ( ) ;
aInfo . hasSynchronization = false ;
aInfo . canExposeMappedData = true ;
2015-12-16 21:50:58 +03:00
2016-02-25 16:15:52 +03:00
if ( mDescriptor . type ( ) = = BufferDescriptor : : TYCbCrDescriptor ) {
2016-04-22 19:05:26 +03:00
aInfo . hasIntermediateBuffer = true ;
} else {
aInfo . hasIntermediateBuffer = mDescriptor . get_RGBDescriptor ( ) . hasIntermediateBuffer ( ) ;
2016-02-25 16:15:52 +03:00
}
2016-04-22 19:05:26 +03:00
switch ( aInfo . format ) {
2015-10-15 18:53:33 +03:00
case gfx : : SurfaceFormat : : YUV :
case gfx : : SurfaceFormat : : NV12 :
case gfx : : SurfaceFormat : : UNKNOWN :
2016-04-22 19:05:26 +03:00
aInfo . supportsMoz2D = false ;
break ;
2015-10-15 18:53:33 +03:00
default :
2016-04-22 19:05:26 +03:00
aInfo . supportsMoz2D = true ;
2015-10-15 18:53:33 +03:00
}
}
2016-04-22 19:05:26 +03:00
gfx : : IntSize
BufferTextureData : : GetSize ( ) const
{
return ImageDataSerializer : : SizeFromBufferDescriptor ( mDescriptor ) ;
}
gfx : : SurfaceFormat
BufferTextureData : : GetFormat ( ) const
{
return ImageDataSerializer : : FormatFromBufferDescriptor ( mDescriptor ) ;
}
2015-10-15 18:53:33 +03:00
already_AddRefed < gfx : : DrawTarget >
BufferTextureData : : BorrowDrawTarget ( )
{
if ( mDrawTarget ) {
mDrawTarget - > SetTransform ( gfx : : Matrix ( ) ) ;
RefPtr < gfx : : DrawTarget > dt = mDrawTarget ;
return dt . forget ( ) ;
}
2015-12-16 21:50:58 +03:00
if ( mDescriptor . type ( ) ! = BufferDescriptor : : TRGBDescriptor ) {
2015-10-15 18:53:33 +03:00
return nullptr ;
}
2015-12-16 21:50:58 +03:00
const RGBDescriptor & rgb = mDescriptor . get_RGBDescriptor ( ) ;
uint32_t stride = ImageDataSerializer : : GetRGBStride ( rgb ) ;
mDrawTarget = gfx : : Factory : : CreateDrawTargetForData ( mMoz2DBackend ,
GetBuffer ( ) , rgb . size ( ) ,
2016-03-18 23:58:55 +03:00
stride , rgb . format ( ) , true ) ;
2015-12-16 21:50:58 +03:00
2015-10-15 18:53:33 +03:00
if ( mDrawTarget ) {
RefPtr < gfx : : DrawTarget > dt = mDrawTarget ;
return dt . forget ( ) ;
}
// TODO - should we warn? should we really fallback to cairo? perhaps
// at least update mMoz2DBackend...
2015-12-16 21:50:58 +03:00
if ( mMoz2DBackend ! = gfx : : BackendType : : CAIRO ) {
mDrawTarget = gfx : : Factory : : CreateDrawTargetForData ( gfx : : BackendType : : CAIRO ,
GetBuffer ( ) , rgb . size ( ) ,
2016-03-18 23:58:55 +03:00
stride , rgb . format ( ) , true ) ;
2015-12-16 21:50:58 +03:00
}
2015-10-15 18:53:33 +03:00
if ( ! mDrawTarget ) {
gfxCriticalNote < < " BorrowDrawTarget failure, original backend " < < ( int ) mMoz2DBackend ;
}
RefPtr < gfx : : DrawTarget > dt = mDrawTarget ;
return dt . forget ( ) ;
}
bool
BufferTextureData : : BorrowMappedData ( MappedTextureData & aData )
{
2015-12-16 21:50:58 +03:00
if ( GetFormat ( ) = = gfx : : SurfaceFormat : : YUV ) {
2015-10-15 18:53:33 +03:00
return false ;
}
2015-12-16 21:50:58 +03:00
gfx : : IntSize size = GetSize ( ) ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
aData . data = GetBuffer ( ) ;
aData . size = size ;
aData . format = GetFormat ( ) ;
aData . stride = ImageDataSerializer : : ComputeRGBStride ( aData . format , size . width ) ;
2015-10-15 18:53:33 +03:00
return true ;
}
bool
BufferTextureData : : BorrowMappedYCbCrData ( MappedYCbCrTextureData & aMap )
{
2015-12-16 21:50:58 +03:00
if ( mDescriptor . type ( ) ! = BufferDescriptor : : TYCbCrDescriptor ) {
2015-10-15 18:53:33 +03:00
return false ;
}
2015-12-16 21:50:58 +03:00
const YCbCrDescriptor & desc = mDescriptor . get_YCbCrDescriptor ( ) ;
uint8_t * data = GetBuffer ( ) ;
auto ySize = desc . ySize ( ) ;
auto cbCrSize = desc . cbCrSize ( ) ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
aMap . stereoMode = desc . stereoMode ( ) ;
aMap . metadata = nullptr ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
aMap . y . data = data + desc . yOffset ( ) ;
aMap . y . size = ySize ;
aMap . y . stride = ySize . width ;
2015-10-15 18:53:33 +03:00
aMap . y . skip = 0 ;
2015-12-16 21:50:58 +03:00
aMap . cb . data = data + desc . cbOffset ( ) ;
aMap . cb . size = cbCrSize ;
aMap . cb . stride = cbCrSize . width ;
2015-10-15 18:53:33 +03:00
aMap . cb . skip = 0 ;
2015-12-16 21:50:58 +03:00
aMap . cr . data = data + desc . crOffset ( ) ;
aMap . cr . size = cbCrSize ;
aMap . cr . stride = cbCrSize . width ;
2015-10-15 18:53:33 +03:00
aMap . cr . skip = 0 ;
return true ;
}
bool
BufferTextureData : : UpdateFromSurface ( gfx : : SourceSurface * aSurface )
{
2015-12-16 21:50:58 +03:00
if ( mDescriptor . type ( ) ! = BufferDescriptor : : TRGBDescriptor ) {
return false ;
}
const RGBDescriptor & rgb = mDescriptor . get_RGBDescriptor ( ) ;
2015-10-15 18:53:33 +03:00
2015-12-16 21:50:58 +03:00
uint32_t stride = ImageDataSerializer : : GetRGBStride ( rgb ) ;
RefPtr < gfx : : DataSourceSurface > surface =
gfx : : Factory : : CreateWrappingDataSourceSurface ( GetBuffer ( ) , stride ,
rgb . size ( ) , rgb . format ( ) ) ;
2015-10-15 18:53:33 +03:00
if ( ! surface ) {
gfxCriticalError ( ) < < " Failed to get serializer as surface! " ;
return false ;
}
RefPtr < gfx : : DataSourceSurface > srcSurf = aSurface - > GetDataSurface ( ) ;
if ( ! srcSurf ) {
2015-12-29 22:03:58 +03:00
gfxCriticalError ( ) < < " Failed to GetDataSurface in UpdateFromSurface (BT). " ;
2015-10-15 18:53:33 +03:00
return false ;
}
if ( surface - > GetSize ( ) ! = srcSurf - > GetSize ( ) | | surface - > GetFormat ( ) ! = srcSurf - > GetFormat ( ) ) {
2015-12-29 22:03:58 +03:00
gfxCriticalError ( ) < < " Attempt to update texture client from a surface with a different size or format (BT)! This: " < < surface - > GetSize ( ) < < " " < < surface - > GetFormat ( ) < < " Other: " < < aSurface - > GetSize ( ) < < " " < < aSurface - > GetFormat ( ) ;
2015-10-15 18:53:33 +03:00
return false ;
}
gfx : : DataSourceSurface : : MappedSurface sourceMap ;
gfx : : DataSourceSurface : : MappedSurface destMap ;
if ( ! srcSurf - > Map ( gfx : : DataSourceSurface : : READ , & sourceMap ) ) {
2015-12-29 22:03:58 +03:00
gfxCriticalError ( ) < < " Failed to map source surface for UpdateFromSurface (BT). " ;
2015-10-15 18:53:33 +03:00
return false ;
}
if ( ! surface - > Map ( gfx : : DataSourceSurface : : WRITE , & destMap ) ) {
srcSurf - > Unmap ( ) ;
gfxCriticalError ( ) < < " Failed to map destination surface for UpdateFromSurface. " ;
return false ;
}
for ( int y = 0 ; y < srcSurf - > GetSize ( ) . height ; y + + ) {
memcpy ( destMap . mData + destMap . mStride * y ,
sourceMap . mData + sourceMap . mStride * y ,
srcSurf - > GetSize ( ) . width * BytesPerPixel ( srcSurf - > GetFormat ( ) ) ) ;
}
srcSurf - > Unmap ( ) ;
surface - > Unmap ( ) ;
return true ;
}
2015-12-16 21:50:58 +03:00
void
BufferTextureData : : SetDesciptor ( const BufferDescriptor & aDescriptor )
{
MOZ_ASSERT ( mDescriptor . type ( ) = = BufferDescriptor : : TYCbCrDescriptor ) ;
MOZ_ASSERT ( mDescriptor . get_YCbCrDescriptor ( ) . ySize ( ) = = gfx : : IntSize ( ) ) ;
mDescriptor = aDescriptor ;
}
2015-10-15 18:53:33 +03:00
bool
MemoryTextureData : : Serialize ( SurfaceDescriptor & aOutDescriptor )
{
MOZ_ASSERT ( GetFormat ( ) ! = gfx : : SurfaceFormat : : UNKNOWN ) ;
if ( GetFormat ( ) = = gfx : : SurfaceFormat : : UNKNOWN ) {
return false ;
}
2015-12-16 21:50:58 +03:00
uintptr_t ptr = reinterpret_cast < uintptr_t > ( mBuffer ) ;
aOutDescriptor = SurfaceDescriptorBuffer ( mDescriptor , MemoryOrShmem ( ptr ) ) ;
2015-10-15 18:53:33 +03:00
return true ;
}
2016-03-12 07:24:21 +03:00
static bool
InitBuffer ( uint8_t * buf , size_t bufSize ,
gfx : : SurfaceFormat aFormat , TextureAllocationFlags aAllocFlags ,
bool aAlreadyZero )
2015-10-15 18:53:33 +03:00
{
if ( ! buf ) {
gfxDebug ( ) < < " BufferTextureData: Failed to allocate " < < bufSize < < " bytes " ;
return false ;
}
2016-02-17 18:34:37 +03:00
if ( ( aAllocFlags & ALLOC_CLEAR_BUFFER ) | |
( aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK ) ) {
2016-03-18 23:58:55 +03:00
if ( aFormat = = gfx : : SurfaceFormat : : B8G8R8X8 ) {
// Even though BGRX was requested, XRGB_UINT32 is what is meant,
// so use 0xFF000000 to put alpha in the right place.
std : : fill_n ( reinterpret_cast < uint32_t * > ( buf ) , bufSize / sizeof ( uint32_t ) , 0xFF000000 ) ;
2016-03-12 07:24:21 +03:00
} else if ( ! aAlreadyZero ) {
2016-03-18 23:58:55 +03:00
memset ( buf , 0 , bufSize ) ;
}
2015-10-15 18:53:33 +03:00
}
2016-02-17 18:34:37 +03:00
2015-10-15 18:53:33 +03:00
if ( aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE ) {
memset ( buf , 0xFF , bufSize ) ;
}
return true ;
}
MemoryTextureData *
MemoryTextureData : : Create ( gfx : : IntSize aSize , gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend , TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ,
2016-03-21 17:18:20 +03:00
ClientIPCAllocator * aAllocator )
2015-10-15 18:53:33 +03:00
{
2015-12-16 21:50:58 +03:00
// Should have used CreateForYCbCr.
MOZ_ASSERT ( aFormat ! = gfx : : SurfaceFormat : : YUV ) ;
2015-10-15 18:53:33 +03:00
if ( aSize . width < = 0 | | aSize . height < = 0 ) {
gfxDebug ( ) < < " Asking for buffer of invalid size " < < aSize . width < < " x " < < aSize . height ;
return nullptr ;
}
2015-12-16 21:50:58 +03:00
uint32_t bufSize = ImageDataSerializer : : ComputeRGBBufferSize ( aSize , aFormat ) ;
2015-10-15 18:53:33 +03:00
if ( ! bufSize ) {
return nullptr ;
}
uint8_t * buf = new ( fallible ) uint8_t [ bufSize ] ;
2016-03-12 07:24:21 +03:00
if ( ! InitBuffer ( buf , bufSize , aFormat , aAllocFlags , false ) ) {
2015-12-16 21:50:58 +03:00
return nullptr ;
2015-10-15 18:53:33 +03:00
}
2016-02-25 16:15:52 +03:00
auto fwd = aAllocator ? aAllocator - > AsCompositableForwarder ( ) : nullptr ;
2016-02-25 16:15:58 +03:00
bool hasIntermediateBuffer = fwd ? ComputeHasIntermediateBuffer ( aFormat ,
2016-02-25 16:15:52 +03:00
fwd - > GetCompositorBackendType ( ) )
2016-02-25 16:15:58 +03:00
: true ;
2016-02-25 16:15:52 +03:00
2015-12-16 21:50:58 +03:00
GfxMemoryImageReporter : : DidAlloc ( buf ) ;
2016-02-25 16:15:58 +03:00
BufferDescriptor descriptor = RGBDescriptor ( aSize , aFormat , hasIntermediateBuffer ) ;
2015-12-16 21:50:58 +03:00
return new MemoryTextureData ( descriptor , aMoz2DBackend , buf , bufSize ) ;
2015-10-15 18:53:33 +03:00
}
void
2016-03-21 17:18:20 +03:00
MemoryTextureData : : Deallocate ( ClientIPCAllocator * )
2015-10-15 18:53:33 +03:00
{
MOZ_ASSERT ( mBuffer ) ;
GfxMemoryImageReporter : : WillFree ( mBuffer ) ;
delete [ ] mBuffer ;
mBuffer = nullptr ;
}
TextureData *
2016-03-21 17:18:20 +03:00
MemoryTextureData : : CreateSimilar ( ClientIPCAllocator * aAllocator ,
2015-10-15 18:53:33 +03:00
TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ) const
{
2015-12-16 21:50:58 +03:00
return MemoryTextureData : : Create ( GetSize ( ) , GetFormat ( ) , mMoz2DBackend ,
2015-10-15 18:53:33 +03:00
aFlags , aAllocFlags , aAllocator ) ;
}
bool
ShmemTextureData : : Serialize ( SurfaceDescriptor & aOutDescriptor )
{
MOZ_ASSERT ( GetFormat ( ) ! = gfx : : SurfaceFormat : : UNKNOWN ) ;
if ( GetFormat ( ) = = gfx : : SurfaceFormat : : UNKNOWN ) {
return false ;
}
2015-12-16 21:50:58 +03:00
aOutDescriptor = SurfaceDescriptorBuffer ( mDescriptor , MemoryOrShmem ( mShmem ) ) ;
2015-10-15 18:53:33 +03:00
return true ;
}
ShmemTextureData *
ShmemTextureData : : Create ( gfx : : IntSize aSize , gfx : : SurfaceFormat aFormat ,
gfx : : BackendType aMoz2DBackend , TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ,
2016-03-21 17:18:20 +03:00
ClientIPCAllocator * aAllocator )
2015-10-15 18:53:33 +03:00
{
MOZ_ASSERT ( aAllocator ) ;
2015-12-16 21:50:58 +03:00
// Should have used CreateForYCbCr.
MOZ_ASSERT ( aFormat ! = gfx : : SurfaceFormat : : YUV ) ;
2016-03-17 16:58:58 +03:00
if ( ! aAllocator | | ! aAllocator - > AsShmemAllocator ( ) ) {
2015-10-15 18:53:33 +03:00
return nullptr ;
}
if ( aSize . width < = 0 | | aSize . height < = 0 ) {
gfxDebug ( ) < < " Asking for buffer of invalid size " < < aSize . width < < " x " < < aSize . height ;
return nullptr ;
}
2015-12-16 21:50:58 +03:00
uint32_t bufSize = ImageDataSerializer : : ComputeRGBBufferSize ( aSize , aFormat ) ;
2015-10-15 18:53:33 +03:00
if ( ! bufSize ) {
return nullptr ;
}
mozilla : : ipc : : Shmem shm ;
2016-03-17 16:58:58 +03:00
if ( ! aAllocator - > AsShmemAllocator ( ) - > AllocUnsafeShmem ( bufSize , OptimalShmemType ( ) , & shm ) ) {
2015-10-15 18:53:33 +03:00
return nullptr ;
}
uint8_t * buf = shm . get < uint8_t > ( ) ;
2016-03-12 07:24:21 +03:00
if ( ! InitBuffer ( buf , bufSize , aFormat , aAllocFlags , true ) ) {
2015-12-16 21:50:58 +03:00
return nullptr ;
2015-10-15 18:53:33 +03:00
}
2016-02-25 16:15:52 +03:00
auto fwd = aAllocator - > AsCompositableForwarder ( ) ;
2016-02-25 16:15:58 +03:00
bool hasIntermediateBuffer = fwd ? ComputeHasIntermediateBuffer ( aFormat ,
2016-02-25 16:15:52 +03:00
fwd - > GetCompositorBackendType ( ) )
2016-02-25 16:15:58 +03:00
: true ;
2016-02-25 16:15:52 +03:00
2016-02-25 16:15:58 +03:00
BufferDescriptor descriptor = RGBDescriptor ( aSize , aFormat , hasIntermediateBuffer ) ;
2015-12-16 21:50:58 +03:00
return new ShmemTextureData ( descriptor , aMoz2DBackend , shm ) ;
2015-10-15 18:53:33 +03:00
return nullptr ;
}
TextureData *
2016-03-21 17:18:20 +03:00
ShmemTextureData : : CreateSimilar ( ClientIPCAllocator * aAllocator ,
2015-10-15 18:53:33 +03:00
TextureFlags aFlags ,
TextureAllocationFlags aAllocFlags ) const
{
2015-12-16 21:50:58 +03:00
return ShmemTextureData : : Create ( GetSize ( ) , GetFormat ( ) , mMoz2DBackend ,
2015-10-15 18:53:33 +03:00
aFlags , aAllocFlags , aAllocator ) ;
}
void
2016-03-21 17:18:20 +03:00
ShmemTextureData : : Deallocate ( ClientIPCAllocator * aAllocator )
2015-10-15 18:53:33 +03:00
{
2016-03-17 16:58:58 +03:00
aAllocator - > AsShmemAllocator ( ) - > DeallocShmem ( mShmem ) ;
2015-10-15 18:53:33 +03:00
}
} // namespace
} // namespace