LCOV - code coverage report
Current view: top level - gfx/layers - BufferTexture.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 97 251 38.6 %
Date: 2017-07-14 16:53:18 Functions: 18 36 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             : //  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "BufferTexture.h"
       7             : #include "mozilla/layers/ImageDataSerializer.h"
       8             : #include "mozilla/layers/ISurfaceAllocator.h"
       9             : #include "mozilla/layers/CompositableForwarder.h"
      10             : #include "mozilla/gfx/Logging.h"
      11             : #include "mozilla/gfx/2D.h"
      12             : #include "mozilla/fallible.h"
      13             : #include "libyuv.h"
      14             : 
      15             : #ifdef MOZ_WIDGET_GTK
      16             : #include "gfxPlatformGtk.h"
      17             : #endif
      18             : 
      19             : namespace mozilla {
      20             : namespace layers {
      21             : 
      22          18 : class MemoryTextureData : public BufferTextureData
      23             : {
      24             : public:
      25             :   static MemoryTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
      26             :                                    gfx::BackendType aMoz2DBackend,
      27             :                                    LayersBackend aLayersBackend,
      28             :                                    TextureFlags aFlags,
      29             :                                    TextureAllocationFlags aAllocFlags,
      30             :                                    LayersIPCChannel* aAllocator);
      31             : 
      32             :   virtual TextureData*
      33             :   CreateSimilar(LayersIPCChannel* aAllocator,
      34             :                 LayersBackend aLayersBackend,
      35             :                 TextureFlags aFlags = TextureFlags::DEFAULT,
      36             :                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
      37             : 
      38             :   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
      39             : 
      40             :   virtual void Deallocate(LayersIPCChannel*) override;
      41             : 
      42           8 :   MemoryTextureData(const BufferDescriptor& aDesc,
      43             :                     gfx::BackendType aMoz2DBackend,
      44             :                     uint8_t* aBuffer, size_t aBufferSize)
      45           8 :   : BufferTextureData(aDesc, aMoz2DBackend)
      46             :   , mBuffer(aBuffer)
      47           8 :   , mBufferSize(aBufferSize)
      48             :   {
      49           8 :     MOZ_ASSERT(aBuffer);
      50           8 :     MOZ_ASSERT(aBufferSize);
      51           8 :   }
      52             : 
      53           8 :   virtual uint8_t* GetBuffer() override { return mBuffer; }
      54             : 
      55           0 :   virtual size_t GetBufferSize() override { return mBufferSize; }
      56             : 
      57             : protected:
      58             :   uint8_t* mBuffer;
      59             :   size_t mBufferSize;
      60             : };
      61             : 
      62           0 : class ShmemTextureData : public BufferTextureData
      63             : {
      64             : public:
      65             :   static ShmemTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
      66             :                                   gfx::BackendType aMoz2DBackend,
      67             :                                   LayersBackend aLayersBackend,
      68             :                                   TextureFlags aFlags,
      69             :                                   TextureAllocationFlags aAllocFlags,
      70             :                                   LayersIPCChannel* aAllocator);
      71             : 
      72             :   virtual TextureData*
      73             :   CreateSimilar(LayersIPCChannel* aAllocator,
      74             :                 LayersBackend aLayersBackend,
      75             :                 TextureFlags aFlags = TextureFlags::DEFAULT,
      76             :                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
      77             : 
      78             :   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
      79             : 
      80             :   virtual void Deallocate(LayersIPCChannel* aAllocator) override;
      81             : 
      82           1 :   ShmemTextureData(const BufferDescriptor& aDesc,
      83             :                    gfx::BackendType aMoz2DBackend, mozilla::ipc::Shmem aShmem)
      84           1 :   : BufferTextureData(aDesc, aMoz2DBackend)
      85           1 :   , mShmem(aShmem)
      86             :   {
      87           1 :     MOZ_ASSERT(mShmem.Size<uint8_t>());
      88           1 :   }
      89             : 
      90           1 :   virtual uint8_t* GetBuffer() override { return mShmem.get<uint8_t>(); }
      91             : 
      92           0 :   virtual size_t GetBufferSize() override { return mShmem.Size<uint8_t>(); }
      93             : 
      94             : protected:
      95             :   mozilla::ipc::Shmem mShmem;
      96             : };
      97             : 
      98           9 : static bool UsingX11Compositor()
      99             : {
     100             : #ifdef MOZ_WIDGET_GTK
     101           9 :   return gfx::gfxVars::UseXRender();
     102             : #endif
     103             :   return false;
     104             : }
     105             : 
     106           9 : bool ComputeHasIntermediateBuffer(gfx::SurfaceFormat aFormat,
     107             :                                   LayersBackend aLayersBackend)
     108             : {
     109             :   return aLayersBackend != LayersBackend::LAYERS_BASIC
     110           9 :       || UsingX11Compositor()
     111          18 :       || aFormat == gfx::SurfaceFormat::UNKNOWN;
     112             : }
     113             : 
     114             : BufferTextureData*
     115           9 : BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
     116             :                           gfx::BackendType aMoz2DBackend,
     117             :                           LayersBackend aLayersBackend, TextureFlags aFlags,
     118             :                           TextureAllocationFlags aAllocFlags,
     119             :                           LayersIPCChannel* aAllocator)
     120             : {
     121           9 :   if (!aAllocator || aAllocator->IsSameProcess()) {
     122             :     return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend,
     123             :                                      aLayersBackend, aFlags,
     124           8 :                                      aAllocFlags, aAllocator);
     125             :   } else {
     126             :     return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend,
     127             :                                     aLayersBackend, aFlags,
     128           1 :                                     aAllocFlags, aAllocator);
     129             :   }
     130             : }
     131             : 
     132             : BufferTextureData*
     133           0 : BufferTextureData::CreateInternal(LayersIPCChannel* aAllocator,
     134             :                                   const BufferDescriptor& aDesc,
     135             :                                   gfx::BackendType aMoz2DBackend,
     136             :                                   int32_t aBufferSize,
     137             :                                   TextureFlags aTextureFlags)
     138             : {
     139           0 :   if (!aAllocator || aAllocator->IsSameProcess()) {
     140           0 :     uint8_t* buffer = new (fallible) uint8_t[aBufferSize];
     141           0 :     if (!buffer) {
     142           0 :       return nullptr;
     143             :     }
     144             : 
     145           0 :     GfxMemoryImageReporter::DidAlloc(buffer);
     146             : 
     147           0 :     return new MemoryTextureData(aDesc, aMoz2DBackend, buffer, aBufferSize);
     148             :   } else {
     149           0 :     ipc::Shmem shm;
     150           0 :     if (!aAllocator->AllocUnsafeShmem(aBufferSize, OptimalShmemType(), &shm)) {
     151           0 :       return nullptr;
     152             :     }
     153             : 
     154           0 :     return new ShmemTextureData(aDesc, aMoz2DBackend, shm);
     155             :   }
     156             : }
     157             : 
     158             : BufferTextureData*
     159           0 : BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
     160             :                                                 int32_t aBufferSize,
     161             :                                                 YUVColorSpace aYUVColorSpace,
     162             :                                                 TextureFlags aTextureFlags)
     163             : {
     164           0 :   if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
     165           0 :     return nullptr;
     166             :   }
     167             : 
     168           0 :   bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
     169             :                                                                          aAllocator->GetCompositorBackendType())
     170           0 :                                           : true;
     171             : 
     172             :   // Initialize the metadata with something, even if it will have to be rewritten
     173             :   // afterwards since we don't know the dimensions of the texture at this point.
     174           0 :   BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), gfx::IntSize(),
     175             :                                           0, 0, 0, StereoMode::MONO,
     176             :                                           aYUVColorSpace,
     177           0 :                                           hasIntermediateBuffer);
     178             : 
     179           0 :   return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr,
     180           0 :                        desc, gfx::BackendType::NONE, aBufferSize, aTextureFlags);
     181             : }
     182             : 
     183             : BufferTextureData*
     184           0 : BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
     185             :                                   gfx::IntSize aYSize,
     186             :                                   gfx::IntSize aCbCrSize,
     187             :                                   StereoMode aStereoMode,
     188             :                                   YUVColorSpace aYUVColorSpace,
     189             :                                   TextureFlags aTextureFlags)
     190             : {
     191           0 :   uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
     192           0 :   if (bufSize == 0) {
     193           0 :     return nullptr;
     194             :   }
     195             : 
     196             :   uint32_t yOffset;
     197             :   uint32_t cbOffset;
     198             :   uint32_t crOffset;
     199           0 :   ImageDataSerializer::ComputeYCbCrOffsets(aYSize.width, aYSize.height,
     200             :                                           aCbCrSize.width, aCbCrSize.height,
     201           0 :                                           yOffset, cbOffset, crOffset);
     202             : 
     203           0 :   bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
     204             :                                                                          aAllocator->GetCompositorBackendType())
     205           0 :                                           : true;
     206             : 
     207             :   YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aCbCrSize, yOffset, cbOffset,
     208             :                                                crOffset, aStereoMode, aYUVColorSpace,
     209           0 :                                                hasIntermediateBuffer);
     210             : 
     211           0 :  return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr, descriptor,
     212           0 :                        gfx::BackendType::NONE, bufSize, aTextureFlags);
     213             : }
     214             : 
     215             : void
     216           9 : BufferTextureData::FillInfo(TextureData::Info& aInfo) const
     217             : {
     218           9 :   aInfo.size = GetSize();
     219           9 :   aInfo.format = GetFormat();
     220           9 :   aInfo.hasSynchronization = false;
     221           9 :   aInfo.canExposeMappedData = true;
     222             : 
     223           9 :   if (mDescriptor.type() == BufferDescriptor::TYCbCrDescriptor) {
     224           0 :     aInfo.hasIntermediateBuffer = mDescriptor.get_YCbCrDescriptor().hasIntermediateBuffer();
     225             :   } else {
     226           9 :     aInfo.hasIntermediateBuffer = mDescriptor.get_RGBDescriptor().hasIntermediateBuffer();
     227             :   }
     228             : 
     229           9 :   switch (aInfo.format) {
     230             :     case gfx::SurfaceFormat::YUV:
     231             :     case gfx::SurfaceFormat::UNKNOWN:
     232           0 :       aInfo.supportsMoz2D = false;
     233           0 :       break;
     234             :     default:
     235           9 :       aInfo.supportsMoz2D = true;
     236             :   }
     237           9 : }
     238             : 
     239             : gfx::IntSize
     240           9 : BufferTextureData::GetSize() const
     241             : {
     242           9 :   return ImageDataSerializer::SizeFromBufferDescriptor(mDescriptor);
     243             : }
     244             : 
     245             : Maybe<gfx::IntSize>
     246           0 : BufferTextureData::GetCbCrSize() const
     247             : {
     248           0 :   return ImageDataSerializer::CbCrSizeFromBufferDescriptor(mDescriptor);
     249             : }
     250             : 
     251             : Maybe<YUVColorSpace>
     252           0 : BufferTextureData::GetYUVColorSpace() const
     253             : {
     254           0 :   return ImageDataSerializer::YUVColorSpaceFromBufferDescriptor(mDescriptor);
     255             : }
     256             : 
     257             : Maybe<StereoMode>
     258           0 : BufferTextureData::GetStereoMode() const
     259             : {
     260           0 :   return ImageDataSerializer::StereoModeFromBufferDescriptor(mDescriptor);
     261             : }
     262             : 
     263             : gfx::SurfaceFormat
     264          27 : BufferTextureData::GetFormat() const
     265             : {
     266          27 :   return ImageDataSerializer::FormatFromBufferDescriptor(mDescriptor);
     267             : }
     268             : 
     269             : already_AddRefed<gfx::DrawTarget>
     270          47 : BufferTextureData::BorrowDrawTarget()
     271             : {
     272          47 :   if (mDrawTarget) {
     273          38 :     mDrawTarget->SetTransform(gfx::Matrix());
     274          76 :     RefPtr<gfx::DrawTarget> dt = mDrawTarget;
     275          38 :     return dt.forget();
     276             :   }
     277             : 
     278           9 :   if (mDescriptor.type() != BufferDescriptor::TRGBDescriptor) {
     279           0 :     return nullptr;
     280             :   }
     281             : 
     282           9 :   const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
     283             : 
     284           9 :   uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
     285           9 :   if (gfx::Factory::DoesBackendSupportDataDrawtarget(mMoz2DBackend)) {
     286          27 :     mDrawTarget = gfx::Factory::CreateDrawTargetForData(mMoz2DBackend,
     287           9 :                                                         GetBuffer(), rgb.size(),
     288          18 :                                                         stride, rgb.format(), true);
     289             :   } else {
     290             :     // Fall back to supported platform backend.  Note that mMoz2DBackend
     291             :     // does not match the draw target type.
     292           0 :     mDrawTarget = gfxPlatform::CreateDrawTargetForData(GetBuffer(), rgb.size(),
     293           0 :                                                        stride, rgb.format(),
     294           0 :                                                        true);
     295             :   }
     296             : 
     297           9 :   if (mDrawTarget) {
     298          18 :     RefPtr<gfx::DrawTarget> dt = mDrawTarget;
     299           9 :     return dt.forget();
     300             :   }
     301             : 
     302             :   // TODO - should we warn? should we really fallback to cairo? perhaps
     303             :   // at least update mMoz2DBackend...
     304           0 :   if (mMoz2DBackend != gfx::BackendType::CAIRO) {
     305           0 :     gfxCriticalNote << "Falling to CAIRO from " << (int)mMoz2DBackend;
     306           0 :     mDrawTarget = gfx::Factory::CreateDrawTargetForData(gfx::BackendType::CAIRO,
     307           0 :                                                         GetBuffer(), rgb.size(),
     308           0 :                                                         stride, rgb.format(), true);
     309             :   }
     310             : 
     311           0 :   if (!mDrawTarget) {
     312           0 :     gfxCriticalNote << "BorrowDrawTarget failure, original backend " << (int)mMoz2DBackend;
     313             :   }
     314             : 
     315           0 :   RefPtr<gfx::DrawTarget> dt = mDrawTarget;
     316           0 :   return dt.forget();
     317             : }
     318             : 
     319             : bool
     320           0 : BufferTextureData::BorrowMappedData(MappedTextureData& aData)
     321             : {
     322           0 :   if (GetFormat() == gfx::SurfaceFormat::YUV) {
     323           0 :     return false;
     324             :   }
     325             : 
     326           0 :   gfx::IntSize size = GetSize();
     327             : 
     328           0 :   aData.data = GetBuffer();
     329           0 :   aData.size = size;
     330           0 :   aData.format = GetFormat();
     331           0 :   aData.stride = ImageDataSerializer::ComputeRGBStride(aData.format, size.width);
     332             : 
     333           0 :   return true;
     334             : }
     335             : 
     336             : bool
     337           0 : BufferTextureData::BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap)
     338             : {
     339           0 :   if (mDescriptor.type() != BufferDescriptor::TYCbCrDescriptor) {
     340           0 :     return false;
     341             :   }
     342             : 
     343           0 :   const YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
     344             : 
     345           0 :   uint8_t* data = GetBuffer();
     346           0 :   auto ySize = desc.ySize();
     347           0 :   auto cbCrSize = desc.cbCrSize();
     348             : 
     349           0 :   aMap.stereoMode = desc.stereoMode();
     350           0 :   aMap.metadata = nullptr;
     351             : 
     352           0 :   aMap.y.data = data + desc.yOffset();
     353           0 :   aMap.y.size = ySize;
     354           0 :   aMap.y.stride = ySize.width;
     355           0 :   aMap.y.skip = 0;
     356             : 
     357           0 :   aMap.cb.data = data + desc.cbOffset();
     358           0 :   aMap.cb.size = cbCrSize;
     359           0 :   aMap.cb.stride = cbCrSize.width;
     360           0 :   aMap.cb.skip = 0;
     361             : 
     362           0 :   aMap.cr.data = data + desc.crOffset();
     363           0 :   aMap.cr.size = cbCrSize;
     364           0 :   aMap.cr.stride = cbCrSize.width;
     365           0 :   aMap.cr.skip = 0;
     366             : 
     367           0 :   return true;
     368             : }
     369             : 
     370             : bool
     371           0 : BufferTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
     372             : {
     373           0 :   if (mDescriptor.type() != BufferDescriptor::TRGBDescriptor) {
     374           0 :     return false;
     375             :   }
     376           0 :   const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
     377             : 
     378           0 :   uint32_t stride = ImageDataSerializer::GetRGBStride(rgb);
     379             :   RefPtr<gfx::DataSourceSurface> surface =
     380           0 :     gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(), stride,
     381           0 :                                                   rgb.size(), rgb.format());
     382             : 
     383           0 :   if (!surface) {
     384           0 :     gfxCriticalError() << "Failed to get serializer as surface!";
     385           0 :     return false;
     386             :   }
     387             : 
     388           0 :   RefPtr<gfx::DataSourceSurface> srcSurf = aSurface->GetDataSurface();
     389             : 
     390           0 :   if (!srcSurf) {
     391           0 :     gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface (BT).";
     392           0 :     return false;
     393             :   }
     394             : 
     395           0 :   if (surface->GetSize() != srcSurf->GetSize() || surface->GetFormat() != srcSurf->GetFormat()) {
     396           0 :     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();
     397           0 :     return false;
     398             :   }
     399             : 
     400             :   gfx::DataSourceSurface::MappedSurface sourceMap;
     401             :   gfx::DataSourceSurface::MappedSurface destMap;
     402           0 :   if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) {
     403           0 :     gfxCriticalError() << "Failed to map source surface for UpdateFromSurface (BT).";
     404           0 :     return false;
     405             :   }
     406             : 
     407           0 :   if (!surface->Map(gfx::DataSourceSurface::WRITE, &destMap)) {
     408           0 :     srcSurf->Unmap();
     409           0 :     gfxCriticalError() << "Failed to map destination surface for UpdateFromSurface.";
     410           0 :     return false;
     411             :   }
     412             : 
     413             : 
     414           0 :   for (int y = 0; y < srcSurf->GetSize().height; y++) {
     415           0 :     memcpy(destMap.mData + destMap.mStride * y,
     416           0 :            sourceMap.mData + sourceMap.mStride * y,
     417           0 :            srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
     418             :   }
     419             : 
     420           0 :   srcSurf->Unmap();
     421           0 :   surface->Unmap();
     422             : 
     423           0 :   return true;
     424             : }
     425             : 
     426             : void
     427           0 : BufferTextureData::SetDesciptor(const BufferDescriptor& aDescriptor)
     428             : {
     429           0 :   MOZ_ASSERT(mDescriptor.type() == BufferDescriptor::TYCbCrDescriptor);
     430           0 :   MOZ_ASSERT(mDescriptor.get_YCbCrDescriptor().ySize() == gfx::IntSize());
     431           0 :   mDescriptor = aDescriptor;
     432           0 : }
     433             : 
     434             : bool
     435           8 : MemoryTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
     436             : {
     437           8 :   MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
     438           8 :   if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
     439           0 :     return false;
     440             :   }
     441             : 
     442           8 :   uintptr_t ptr = reinterpret_cast<uintptr_t>(mBuffer);
     443           8 :   aOutDescriptor = SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(ptr));
     444             : 
     445           8 :   return true;
     446             : }
     447             : 
     448             : static bool
     449           9 : InitBuffer(uint8_t* buf, size_t bufSize,
     450             :            gfx::SurfaceFormat aFormat, TextureAllocationFlags aAllocFlags,
     451             :            bool aAlreadyZero)
     452             : {
     453           9 :   if (!buf) {
     454           0 :     gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize << " bytes";
     455           0 :     return false;
     456             :   }
     457             : 
     458           9 :   if ((aAllocFlags & ALLOC_CLEAR_BUFFER) ||
     459           0 :       (aAllocFlags & ALLOC_CLEAR_BUFFER_BLACK)) {
     460           9 :     if (aFormat == gfx::SurfaceFormat::B8G8R8X8) {
     461             :       // Even though BGRX was requested, XRGB_UINT32 is what is meant,
     462             :       // so use 0xFF000000 to put alpha in the right place.
     463           5 :       libyuv::ARGBRect(buf, bufSize, 0, 0, bufSize / sizeof(uint32_t), 1, 0xFF000000);
     464           4 :     } else if (!aAlreadyZero) {
     465           4 :       memset(buf, 0, bufSize);
     466             :     }
     467             :   }
     468             : 
     469           9 :   if (aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE) {
     470           0 :     memset(buf, 0xFF, bufSize);
     471             :   }
     472             : 
     473           9 :   return true;
     474             : }
     475             : 
     476             : MemoryTextureData*
     477           8 : MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
     478             :                           gfx::BackendType aMoz2DBackend,
     479             :                           LayersBackend aLayersBackend, TextureFlags aFlags,
     480             :                           TextureAllocationFlags aAllocFlags,
     481             :                           LayersIPCChannel* aAllocator)
     482             : {
     483             :   // Should have used CreateForYCbCr.
     484           8 :   MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
     485             : 
     486           8 :   if (aSize.width <= 0 || aSize.height <= 0) {
     487           0 :     gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
     488           0 :     return nullptr;
     489             :   }
     490             : 
     491           8 :   uint32_t bufSize = ImageDataSerializer::ComputeRGBBufferSize(aSize, aFormat);
     492           8 :   if (!bufSize) {
     493           0 :     return nullptr;
     494             :   }
     495             : 
     496          16 :   uint8_t* buf = new (fallible) uint8_t[bufSize];
     497           8 :   if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags, false)) {
     498           0 :     return nullptr;
     499             :   }
     500             : 
     501           8 :   bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat, aLayersBackend);
     502             : 
     503           8 :   GfxMemoryImageReporter::DidAlloc(buf);
     504             : 
     505          16 :   BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
     506             : 
     507           8 :   return new MemoryTextureData(descriptor, aMoz2DBackend, buf, bufSize);
     508             : }
     509             : 
     510             : void
     511           0 : MemoryTextureData::Deallocate(LayersIPCChannel*)
     512             : {
     513           0 :   MOZ_ASSERT(mBuffer);
     514           0 :   GfxMemoryImageReporter::WillFree(mBuffer);
     515           0 :   delete [] mBuffer;
     516           0 :   mBuffer = nullptr;
     517           0 : }
     518             : 
     519             : TextureData*
     520           0 : MemoryTextureData::CreateSimilar(LayersIPCChannel* aAllocator,
     521             :                                  LayersBackend aLayersBackend,
     522             :                                  TextureFlags aFlags,
     523             :                                  TextureAllocationFlags aAllocFlags) const
     524             : {
     525           0 :   return MemoryTextureData::Create(GetSize(), GetFormat(), mMoz2DBackend,
     526           0 :                                    aLayersBackend, aFlags, aAllocFlags, aAllocator);
     527             : }
     528             : 
     529             : bool
     530           1 : ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
     531             : {
     532           1 :   MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
     533           1 :   if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
     534           0 :     return false;
     535             :   }
     536             : 
     537           1 :   aOutDescriptor = SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(mShmem));
     538             : 
     539           1 :   return true;
     540             : }
     541             : 
     542             : ShmemTextureData*
     543           1 : ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
     544             :                          gfx::BackendType aMoz2DBackend,
     545             :                          LayersBackend aLayersBackend, TextureFlags aFlags,
     546             :                          TextureAllocationFlags aAllocFlags,
     547             :                          LayersIPCChannel* aAllocator)
     548             : {
     549           1 :   MOZ_ASSERT(aAllocator);
     550             :   // Should have used CreateForYCbCr.
     551           1 :   MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
     552             : 
     553           1 :   if (!aAllocator) {
     554           0 :     return nullptr;
     555             :   }
     556             : 
     557           1 :   if (aSize.width <= 0 || aSize.height <= 0) {
     558           0 :     gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
     559           0 :     return nullptr;
     560             :   }
     561             : 
     562           1 :   uint32_t bufSize = ImageDataSerializer::ComputeRGBBufferSize(aSize, aFormat);
     563           1 :   if (!bufSize) {
     564           0 :     return nullptr;
     565             :   }
     566             : 
     567           2 :   mozilla::ipc::Shmem shm;
     568           1 :   if (!aAllocator->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
     569           0 :     return nullptr;
     570             :   }
     571             : 
     572           1 :   uint8_t* buf = shm.get<uint8_t>();
     573           1 :   if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags, true)) {
     574           0 :     return nullptr;
     575             :   }
     576             : 
     577           1 :   bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat, aLayersBackend);
     578             : 
     579           2 :   BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
     580             : 
     581           2 :   return new ShmemTextureData(descriptor, aMoz2DBackend, shm);
     582             : 
     583             :   return nullptr;
     584             : }
     585             : 
     586             : TextureData*
     587           0 : ShmemTextureData::CreateSimilar(LayersIPCChannel* aAllocator,
     588             :                                 LayersBackend aLayersBackend,
     589             :                                 TextureFlags aFlags,
     590             :                                 TextureAllocationFlags aAllocFlags) const
     591             : {
     592           0 :   return ShmemTextureData::Create(GetSize(), GetFormat(), mMoz2DBackend,
     593           0 :                                   aLayersBackend, aFlags, aAllocFlags, aAllocator);
     594             : }
     595             : 
     596             : void
     597           0 : ShmemTextureData::Deallocate(LayersIPCChannel* aAllocator)
     598             : {
     599           0 :   aAllocator->DeallocShmem(mShmem);
     600           0 : }
     601             : 
     602             : } // namespace
     603             : } // namespace

Generated by: LCOV version 1.13