Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  BufferTexture.cpp

  Sprache: C
 

/* 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 <utility>

#include "libyuv.h"
#include "mozilla/fallible.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/TextureForwarder.h"

#include "gfxPlatform.h"

#ifdef MOZ_WIDGET_GTK
#  include "gfxPlatformGtk.h"
#endif

using mozilla::ipc::IShmemAllocator;

namespace mozilla {
namespace layers {

class MemoryTextureData : public BufferTextureData {
 public:
  static MemoryTextureData* Create(
      gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
      gfx::ColorSpace2 aColorSpace, gfx::TransferFunction aTransferFunction,
      gfx::BackendType aMoz2DBackend, LayersBackend aLayersBackend,
      TextureFlags aFlags, TextureAllocationFlags aAllocFlags,
      IShmemAllocator* aAllocator);

  virtual TextureData* CreateSimilar(
      LayersIPCChannel* aAllocator, LayersBackend aLayersBackend,
      TextureFlags aFlags = TextureFlags::DEFAULT,
      TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;

  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;

  virtual void Deallocate(LayersIPCChannel*) override;

  MemoryTextureData(const BufferDescriptor& aDesc,
                    gfx::BackendType aMoz2DBackend, uint8_t* aBuffer,
                    size_t aBufferSize, bool aAutoDeallocate = false,
                    bool aIsClear = false)
      : BufferTextureData(aDesc, aMoz2DBackend, aIsClear),
        mBuffer(aBuffer),
        mBufferSize(aBufferSize),
        mAutoDeallocate(aAutoDeallocate) {
    MOZ_ASSERT(aBuffer);
    MOZ_ASSERT(aBufferSize);
  }

  virtual ~MemoryTextureData() override {
    if (mAutoDeallocate) {
      Deallocate(nullptr);
    }
  }

  virtual uint8_t* GetBuffer() override { return mBuffer; }

  virtual size_t GetBufferSize() override { return mBufferSize; }

  TextureType GetTextureType() const override { return TextureType::Unknown; }

 protected:
  uint8_t* mBuffer;
  size_t mBufferSize;
  bool mAutoDeallocate;
};

class ShmemTextureData : public BufferTextureData {
 public:
  static ShmemTextureData* Create(
      gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
      gfx::ColorSpace2 aColorSpace, gfx::TransferFunction aTransferFunction,
      gfx::BackendType aMoz2DBackend, LayersBackend aLayersBackend,
      TextureFlags aFlags, TextureAllocationFlags aAllocFlags,
      LayersIPCChannel* aAllocator);

  virtual TextureData* CreateSimilar(
      LayersIPCChannel* aAllocator, LayersBackend aLayersBackend,
      TextureFlags aFlags = TextureFlags::DEFAULT,
      TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;

  virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;

  virtual void Deallocate(LayersIPCChannel* aAllocator) override;

  class ShmemHolder final {
   public:
    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ShmemHolder)

    ShmemHolder(LayersIPCChannel* aAllocator, mozilla::ipc::Shmem aShmem)
        : mAllocator(aAllocator), mShmem(std::move(aShmem)) {}
    mozilla::ipc::Shmem& GetShmem() { return mShmem; }
    void SetDeallocShmem() { mDeallocShmem = true; }

    const RefPtr<LayersIPCChannel> mAllocator;

   protected:
    ~ShmemHolder() {
      if (mDeallocShmem) {
        mAllocator->DeallocShmem(mShmem);
      }
    }

    mozilla::ipc::Shmem mShmem;
    mozilla::Atomic<bool> mDeallocShmem{false};
  };

  ShmemTextureData(const BufferDescriptor& aDesc,
                   gfx::BackendType aMoz2DBackend,
                   RefPtr<ShmemHolder>& aShmemHolder, bool aIsClear = false)
      : BufferTextureData(aDesc, aMoz2DBackend, aIsClear),
        mShmemHolder(aShmemHolder) {
    MOZ_ASSERT(mShmemHolder);
    MOZ_ASSERT(mShmemHolder->GetShmem().Size<uint8_t>());
  }

  virtual uint8_t* GetBuffer() override {
    return mShmemHolder->GetShmem().get<uint8_t>();
  }

  virtual size_t GetBufferSize() override {
    return mShmemHolder->GetShmem().Size<uint8_t>();
  }

  virtual void OnBorrowDrawTarget(gfx::DrawTarget* aDrawTarget) override;

 protected:
  const RefPtr<ShmemHolder> mShmemHolder;
  gfx::UserDataKey mShmemHolderKey = {0};
};

BufferTextureData* BufferTextureData::Create(
    gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    gfx::ColorSpace2 aColorSpace, gfx::TransferFunction aTransferFunction,
    gfx::BackendType aMoz2DBackend, LayersBackend aLayersBackend,
    TextureFlags aFlags, TextureAllocationFlags aAllocFlags,
    LayersIPCChannel* aAllocator, bool aIsSameProcess) {
  if (!aAllocator || aIsSameProcess) {
    return MemoryTextureData::Create(
        aSize, aFormat, aColorSpace, aTransferFunction, aMoz2DBackend,
        aLayersBackend, aFlags, aAllocFlags, aAllocator);
  } else {
    return ShmemTextureData::Create(
        aSize, aFormat, aColorSpace, aTransferFunction, aMoz2DBackend,
        aLayersBackend, aFlags, aAllocFlags, aAllocator);
  }
}

BufferTextureData* BufferTextureData::CreateInternal(
    LayersIPCChannel* aAllocator, const BufferDescriptor& aDesc,
    gfx::BackendType aMoz2DBackend, int32_t aBufferSize,
    TextureFlags aTextureFlags) {
  if (!aAllocator || aAllocator->IsSameProcess()) {
    uint8_t* buffer = new (fallible) uint8_t[aBufferSize];
    if (!buffer) {
      return nullptr;
    }

    GfxMemoryImageReporter::DidAlloc(buffer);

    return new MemoryTextureData(aDesc, aMoz2DBackend, buffer, aBufferSize);
  } else {
    ipc::Shmem shm;
    if (!aAllocator->AllocUnsafeShmem(aBufferSize, &shm)) {
      return nullptr;
    }

    bool isClear = aDesc.type() == BufferDescriptor::TRGBDescriptor &&
                   !IsOpaque(aDesc.get_RGBDescriptor().format());
    RefPtr shmemHolder =
        MakeRefPtr<ShmemTextureData::ShmemHolder>(aAllocator, shm);
    return new ShmemTextureData(aDesc, aMoz2DBackend, shmemHolder, isClear);
  }
}

BufferTextureData* BufferTextureData::CreateForYCbCr(
    KnowsCompositor* aAllocator, const gfx::IntRect& aDisplay,
    const gfx::IntSize& aYSize, uint32_t aYStride,
    const gfx::IntSize& aCbCrSize, uint32_t aCbCrStride, StereoMode aStereoMode,
    gfx::ColorDepth aColorDepth, gfx::YUVColorSpace aYUVColorSpace,
    gfx::ColorRange aColorRange, gfx::TransferFunction aTransferFunction,
    gfx::ChromaSubsampling aSubsampling, TextureFlags aTextureFlags,
    const Maybe<gfx::HDRMetadata>& aHDRMetadata) {
  Maybe<uint32_t> bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(
      aDisplay, aYSize, aYStride, aCbCrSize, aCbCrStride, aColorDepth,
      aSubsampling);
  if (bufSize.isNothing()) {
    return nullptr;
  }

  uint32_t yOffset;
  uint32_t cbOffset;
  uint32_t crOffset;
  ImageDataSerializer::ComputeYCbCrOffsets(aYStride, aYSize.height, aCbCrStride,
                                           aCbCrSize.height, yOffset, cbOffset,
                                           crOffset);

  YCbCrDescriptor descriptor = YCbCrDescriptor(
      aDisplay, aYSize, aYStride, aCbCrSize, aCbCrStride, yOffset, cbOffset,
      crOffset, aStereoMode, aColorDepth, aYUVColorSpace, aColorRange,
      aTransferFunction, aSubsampling, aHDRMetadata);

  return CreateInternal(
      aAllocator ? aAllocator->GetTextureForwarder().get() : nullptr,
      descriptor, gfx::BackendType::NONE, bufSize.value(), aTextureFlags);
}

void BufferTextureData::FillInfo(TextureData::Info& aInfo) const {
  aInfo.size = GetSize();
  aInfo.format = GetFormat();
  aInfo.hasSynchronization = false;
  aInfo.canExposeMappedData = true;

  switch (aInfo.format) {
    case gfx::SurfaceFormat::YUV420:
    case gfx::SurfaceFormat::UNKNOWN:
      aInfo.supportsMoz2D = false;
      break;
    default:
      aInfo.supportsMoz2D = true;
  }
}

gfx::IntSize BufferTextureData::GetSize() const {
  return ImageDataSerializer::SizeFromBufferDescriptor(mDescriptor);
}

gfx::IntRect BufferTextureData::GetPictureRect() const {
  return ImageDataSerializer::RectFromBufferDescriptor(mDescriptor);
}

Maybe<gfx::IntSize> BufferTextureData::GetYSize() const {
  return ImageDataSerializer::YSizeFromBufferDescriptor(mDescriptor);
}

Maybe<gfx::IntSize> BufferTextureData::GetCbCrSize() const {
  return ImageDataSerializer::CbCrSizeFromBufferDescriptor(mDescriptor);
}

Maybe<int32_t> BufferTextureData::GetYStride() const {
  return ImageDataSerializer::YStrideFromBufferDescriptor(mDescriptor);
}

Maybe<int32_t> BufferTextureData::GetCbCrStride() const {
  return ImageDataSerializer::CbCrStrideFromBufferDescriptor(mDescriptor);
}

Maybe<gfx::ColorSpace2> BufferTextureData::GetColorSpace2() const {
  return ImageDataSerializer::ColorSpace2FromBufferDescriptor(mDescriptor);
}

Maybe<gfx::YUVColorSpace> BufferTextureData::GetYUVColorSpace() const {
  return ImageDataSerializer::YUVColorSpaceFromBufferDescriptor(mDescriptor);
}

Maybe<gfx::ColorDepth> BufferTextureData::GetColorDepth() const {
  return ImageDataSerializer::ColorDepthFromBufferDescriptor(mDescriptor);
}

Maybe<StereoMode> BufferTextureData::GetStereoMode() const {
  return ImageDataSerializer::StereoModeFromBufferDescriptor(mDescriptor);
}

Maybe<gfx::ChromaSubsampling> BufferTextureData::GetChromaSubsampling() const {
  return ImageDataSerializer::ChromaSubsamplingFromBufferDescriptor(
      mDescriptor);
}

Maybe<gfx::TransferFunction> BufferTextureData::GetTransferFunction() const {
  return ImageDataSerializer::TransferFunctionFromBufferDescriptor(mDescriptor);
}

gfx::SurfaceFormat BufferTextureData::GetFormat() const {
  return ImageDataSerializer::FormatFromBufferDescriptor(mDescriptor);
}

struct ShmemHolderUserData {
  explicit ShmemHolderUserData(ShmemTextureData::ShmemHolder* aShmemHolder)
      : mShmemHolder(aShmemHolder) {}
  ~ShmemHolderUserData() = default;
  RefPtr<ShmemTextureData::ShmemHolder> mShmemHolder;
};

void DeleteShmemHolderUserData(void* aClosure) {
  ShmemHolderUserData* data = reinterpret_cast<ShmemHolderUserData*>(aClosure);
  auto* eventTarget = data->mShmemHolder->mAllocator->GetThread();

  if (!eventTarget->IsOnCurrentThread()) {
    RefPtr<Runnable> runnable =
        NS_NewRunnableFunction("DeleteShmemHolderUserData::Runnable",
                               [wrapper = std::move(data->mShmemHolder)]() {});
    eventTarget->Dispatch(runnable.forget());
  }

  delete data;
}

void ShmemTextureData::OnBorrowDrawTarget(gfx::DrawTarget* aDrawTarget) {
  if (!aDrawTarget) {
    return;
  }
  auto* data = new ShmemHolderUserData(mShmemHolder);
  aDrawTarget->AddUserData(&mShmemHolderKey, data, DeleteShmemHolderUserData);
}

already_AddRefed<gfx::DrawTarget> BufferTextureData::BorrowDrawTarget() {
  if (mDescriptor.type() != BufferDescriptor::TRGBDescriptor) {
    return nullptr;
  }

  const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();

  auto stride = ImageDataSerializer::GetRGBStride(rgb);
  if (stride.isNothing()) {
    return nullptr;
  }

  RefPtr<gfx::DrawTarget> dt;
  if (gfx::Factory::DoesBackendSupportDataDrawtarget(mMoz2DBackend)) {
    dt = gfx::Factory::CreateDrawTargetForData(mMoz2DBackend, GetBuffer(),
                                               rgb.size(), stride.value(),
                                               rgb.format(), true, mIsClear);
  }
  if (!dt) {
    // Fall back to supported platform backend.  Note that mMoz2DBackend
    // does not match the draw target type.
    dt = gfxPlatform::CreateDrawTargetForData(
        GetBuffer(), rgb.size(), stride.value(), rgb.format(), true, mIsClear);
  }

  if (!dt) {
    gfxCriticalNote << "BorrowDrawTarget failure, original backend "
                    << (int)mMoz2DBackend;
  }

  return dt.forget();
}

bool BufferTextureData::BorrowMappedData(MappedTextureData& aData) {
  if (GetFormat() == gfx::SurfaceFormat::YUV420) {
    return false;
  }

  gfx::IntSize size = GetSize();

  auto stride = ImageDataSerializer::ComputeRGBStride(GetFormat(), size.width);
  if (stride.isNothing()) {
    return false;
  }

  aData.data = GetBuffer();
  aData.size = size;
  aData.format = GetFormat();
  aData.stride = stride.value();
  mIsClear = false;

  return true;
}

bool BufferTextureData::BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap) {
  if (mDescriptor.type() != BufferDescriptor::TYCbCrDescriptor) {
    return false;
  }

  const YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();

  uint8_t* data = GetBuffer();
  auto ySize = desc.ySize();
  auto cbCrSize = desc.cbCrSize();

  aMap.stereoMode = desc.stereoMode();
  aMap.metadata = nullptr;
  uint32_t bytesPerPixel =
      BytesPerPixel(SurfaceFormatForColorDepth(desc.colorDepth()));

  aMap.y.data = data + desc.yOffset();
  aMap.y.size = ySize;
  aMap.y.stride = desc.yStride();
  aMap.y.skip = 0;
  aMap.y.bytesPerPixel = bytesPerPixel;

  aMap.cb.data = data + desc.cbOffset();
  aMap.cb.size = cbCrSize;
  aMap.cb.stride = desc.cbCrStride();
  aMap.cb.skip = 0;
  aMap.cb.bytesPerPixel = bytesPerPixel;

  aMap.cr.data = data + desc.crOffset();
  aMap.cr.size = cbCrSize;
  aMap.cr.stride = desc.cbCrStride();
  aMap.cr.skip = 0;
  aMap.cr.bytesPerPixel = bytesPerPixel;

  return true;
}

bool BufferTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface) {
  if (mDescriptor.type() != BufferDescriptor::TRGBDescriptor) {
    return false;
  }
  const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();

  auto stride = ImageDataSerializer::GetRGBStride(rgb);
  if (stride.isNothing()) {
    gfxCriticalError() << "Invalid stride!";
    return false;
  }

  RefPtr<gfx::DataSourceSurface> surface =
      gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(), stride.value(),
                                                    rgb.size(), rgb.format());

  if (!surface) {
    gfxCriticalError() << "Failed to get serializer as surface!";
    return false;
  }

  RefPtr<gfx::DataSourceSurface> srcSurf = aSurface->GetDataSurface();

  if (!srcSurf) {
    gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface (BT).";
    return false;
  }

  if (surface->GetSize() != srcSurf->GetSize() ||
      surface->GetFormat() != srcSurf->GetFormat()) {
    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();
    return false;
  }

  gfx::DataSourceSurface::MappedSurface sourceMap;
  gfx::DataSourceSurface::MappedSurface destMap;
  if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) {
    gfxCriticalError()
        << "Failed to map source surface for UpdateFromSurface (BT).";
    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();

  mIsClear = false;

  return true;
}

bool MemoryTextureData::Serialize(SurfaceDescriptor& aOutDescriptor) {
  MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
  if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
    return false;
  }

  uintptr_t ptr = reinterpret_cast<uintptr_t>(mBuffer);
  aOutDescriptor = SurfaceDescriptorBuffer(mDescriptor, MemoryOrShmem(ptr));

  return true;
}

static bool InitBuffer(uint8_t* buf, size_t bufSize, gfx::SurfaceFormat aFormat,
                       TextureAllocationFlags aAllocFlags, bool aAlreadyZero) {
  if (!buf) {
    gfxDebug() << "BufferTextureData: Failed to allocate " << bufSize
               << " bytes";
    return false;
  }

  if (aAllocFlags & ALLOC_CLEAR_BUFFER) {
    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.
      libyuv::ARGBRect(buf, bufSize, 00, bufSize / sizeof(uint32_t), 1,
                       0xFF000000);
    } else if (!aAlreadyZero) {
      memset(buf, 0, bufSize);
    }
  }

  return true;
}

MemoryTextureData* MemoryTextureData::Create(
    gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    gfx::ColorSpace2 aColorSpace, gfx::TransferFunction aTransferFunction,
    gfx::BackendType aMoz2DBackend, LayersBackend aLayersBackend,
    TextureFlags aFlags, TextureAllocationFlags aAllocFlags,
    IShmemAllocator* aAllocator) {
  // Should have used CreateForYCbCr.
  MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV420);

  if (aSize.width <= 0 || aSize.height <= 0) {
    gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x"
               << aSize.height;
    return nullptr;
  }

  Maybe<uint32_t> bufSize =
      ImageDataSerializer::ComputeRGBBufferSize(aSize, aFormat);
  if (bufSize.isNothing()) {
    return nullptr;
  }

  uint8_t* buf = new (fallible) uint8_t[bufSize.value()];
  if (!InitBuffer(buf, bufSize.value(), aFormat, aAllocFlags, false)) {
    return nullptr;
  }

  GfxMemoryImageReporter::DidAlloc(buf);

  BufferDescriptor descriptor =
      RGBDescriptor(aSize, aFormat, aColorSpace, aTransferFunction);

  // Remote textures are not managed by a texture client, so we need to ensure
  // that memory is freed when the owning MemoryTextureData goes away.
  bool autoDeallocate = !!(aFlags & TextureFlags::REMOTE_TEXTURE);
  bool isClear = (aAllocFlags & ALLOC_CLEAR_BUFFER) != 0;
  return new MemoryTextureData(descriptor, aMoz2DBackend, buf, bufSize.value(),
                               autoDeallocate, isClear);
}

void MemoryTextureData::Deallocate(LayersIPCChannel*) {
  MOZ_ASSERT(mBuffer);
  GfxMemoryImageReporter::WillFree(mBuffer);
  delete[] mBuffer;
  mBuffer = nullptr;
}

TextureData* MemoryTextureData::CreateSimilar(
    LayersIPCChannel* aAllocator, LayersBackend aLayersBackend,
    TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const {
  const auto colorSpace = GetColorSpace2().valueOr(gfx::ColorSpace2::SRGB);
  const auto transferFunction =
      GetTransferFunction().valueOr(gfx::TransferFunction::SRGB);
  return MemoryTextureData::Create(
      GetSize(), GetFormat(), colorSpace, transferFunction, mMoz2DBackend,
      aLayersBackend, aFlags, aAllocFlags, aAllocator);
}

bool ShmemTextureData::Serialize(SurfaceDescriptor& aOutDescriptor) {
  MOZ_ASSERT(GetFormat() != gfx::SurfaceFormat::UNKNOWN);
  if (GetFormat() == gfx::SurfaceFormat::UNKNOWN) {
    return false;
  }

  aOutDescriptor = SurfaceDescriptorBuffer(
      mDescriptor, MemoryOrShmem(mShmemHolder->GetShmem()));

  return true;
}

ShmemTextureData* ShmemTextureData::Create(
    gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
    gfx::ColorSpace2 aColorSpace, gfx::TransferFunction aTransferFunction,
    gfx::BackendType aMoz2DBackend, LayersBackend aLayersBackend,
    TextureFlags aFlags, TextureAllocationFlags aAllocFlags,
    LayersIPCChannel* aAllocator) {
  MOZ_ASSERT(aAllocator);
  // Should have used CreateForYCbCr.
  MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV420);
  MOZ_ASSERT(!(aFlags & TextureFlags::DEALLOCATE_CLIENT));

  if (!aAllocator) {
    return nullptr;
  }

  if (aSize.width <= 0 || aSize.height <= 0) {
    gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x"
               << aSize.height;
    return nullptr;
  }

  Maybe<uint32_t> bufSize =
      ImageDataSerializer::ComputeRGBBufferSize(aSize, aFormat);
  if (bufSize.isNothing()) {
    return nullptr;
  }

  mozilla::ipc::Shmem shm;
  if (!aAllocator->AllocUnsafeShmem(bufSize.value(), &shm)) {
    return nullptr;
  }

  uint8_t* buf = shm.get<uint8_t>();
  if (!InitBuffer(buf, bufSize.value(), aFormat, aAllocFlags, true)) {
    return nullptr;
  }

  BufferDescriptor descriptor =
      RGBDescriptor(aSize, aFormat, aColorSpace, aTransferFunction);
  bool isClear = (aAllocFlags & ALLOC_CLEAR_BUFFER) || !IsOpaque(aFormat);
  RefPtr shmemHolder =
      MakeRefPtr<ShmemTextureData::ShmemHolder>(aAllocator, shm);
  return new ShmemTextureData(descriptor, aMoz2DBackend, shmemHolder, isClear);
}

TextureData* ShmemTextureData::CreateSimilar(
    LayersIPCChannel* aAllocator, LayersBackend aLayersBackend,
    TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const {
  const auto colorSpace = GetColorSpace2().valueOr(gfx::ColorSpace2::SRGB);
  const auto transferFunction =
      GetTransferFunction().valueOr(gfx::TransferFunction::SRGB);
  return ShmemTextureData::Create(
      GetSize(), GetFormat(), colorSpace, transferFunction, mMoz2DBackend,
      aLayersBackend, aFlags, aAllocFlags, aAllocator);
}

void ShmemTextureData::Deallocate(LayersIPCChannel* aAllocator) {
  if (!aAllocator) {
    gfxCriticalNote << "No allocator in ShmemTextureData::Deallocate";
    return;
  }
  MOZ_ASSERT(aAllocator == mShmemHolder->mAllocator);
  mShmemHolder->SetDeallocShmem();
}

}  // namespace layers
}  // namespace mozilla

Messung V0.5 in Prozent
C=90 H=96 G=93

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142