BufferTextureData*
BufferTextureData::CreateInternal(ClientIPCAllocator* 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 if (aAllocator->AsShmemAllocator()) {
    ipc::Shmem shm;
    if (!aAllocator->AsShmemAllocator()->AllocUnsafeShmem(aBufferSize, OptimalShmemType(), &shm)) {
      return nullptr;
    }

    return new ShmemTextureData(aDesc, aMoz2DBackend, shm);
  }
  return nullptr;
}
bool
ShmemTextureClient::Allocate(uint32_t aSize)
{
  MOZ_ASSERT(IsValid());
  ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType();
  mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
  return mAllocated;
}
bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage)
{
  MOZ_ASSERT(aImage);
  if (!aImage) {
    return false;
  }

  const PlanarYCbCrData *data = aImage->GetData();
  NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
  if (!data) {
    return false;
  }

  bool needsAllocation = false;
  if (mDescriptor->type() != SurfaceDescriptor::TYCbCrImage) {
    needsAllocation = true;
  } else {
    ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
    YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
    if (serializer.GetYSize() != data->mYSize ||
        serializer.GetCbCrSize() != data->mCbCrSize) {
      needsAllocation = true;
    }
  }

  if (!needsAllocation) {
    return true;
  }

  mDeprecatedTextureClient->ReleaseResources();

  ipc::SharedMemory::SharedMemoryType shmType = OptimalShmemType();
  size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(data->mYSize,
                                                               data->mCbCrSize);
  ipc::Shmem shmem;
  if (!mDeprecatedTextureClient->GetForwarder()->AllocUnsafeShmem(size, shmType, &shmem)) {
    return false;
  }

  YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
  serializer.InitializeBufferInfo(data->mYSize,
                                  data->mCbCrSize,
                                  data->mStereoMode);

  *mDescriptor = YCbCrImage(shmem, 0);

  return true;
}
ShmemTextureData*
ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                         gfx::BackendType aMoz2DBackend,
                         LayersBackend aLayersBackend, TextureFlags aFlags,
                         TextureAllocationFlags aAllocFlags,
                         ClientIPCAllocator* aAllocator)
{
  MOZ_ASSERT(aAllocator);
  // Should have used CreateForYCbCr.
  MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);

  if (!aAllocator || !aAllocator->AsShmemAllocator()) {
    return nullptr;
  }

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

  uint32_t bufSize = ImageDataSerializer::ComputeRGBBufferSize(aSize, aFormat);
  if (!bufSize) {
    return nullptr;
  }

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

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

  // LAYERS_NONE must imply that we have no compositable forwarder
  MOZ_ASSERT_IF(aLayersBackend == LayersBackend::LAYERS_NONE,
                !aAllocator || !aAllocator->AsCompositableForwarder());

  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(aFormat, aLayersBackend);

  BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);

  return new ShmemTextureData(descriptor, aMoz2DBackend, shm);

  return nullptr;
}
Exemple #5
0
bool
ISurfaceAllocator::AllocSharedImageSurface(const gfxIntSize& aSize,
                               gfxASurface::gfxContentType aContent,
                               gfxSharedImageSurface** aBuffer)
{
  SharedMemory::SharedMemoryType shmemType = OptimalShmemType();
  gfxASurface::gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent);

  nsRefPtr<gfxSharedImageSurface> back =
    gfxSharedImageSurface::CreateUnsafe(this, aSize, format, shmemType);
  if (!back)
    return false;

  *aBuffer = nullptr;
  back.swap(*aBuffer);
  return true;
}
Exemple #6
0
bool
DeprecatedSharedRGBImage::AllocateBuffer(nsIntSize aSize, gfxImageFormat aImageFormat)
{
  if (mAllocated) {
    NS_WARNING("Already allocated shmem");
    return false;
  }

  size_t size = GetBufferSize();

  if (size == 0 || size > MAX_FRAME_SIZE) {
    NS_WARNING("Invalid frame size");
  }
  if (mSurfaceAllocator->AllocUnsafeShmem(size, OptimalShmemType(), mShmem)) {
    mAllocated = true;
  }

  return mAllocated;
}
Exemple #7
0
bool
ShadowLayerForwarder::AllocBuffer(const gfxIntSize& aSize,
                                  gfxASurface::gfxContentType aContent,
                                  gfxSharedImageSurface** aBuffer)
{
  NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");

  gfxASurface::gfxImageFormat format = OptimalFormatFor(aContent);
  SharedMemory::SharedMemoryType shmemType = OptimalShmemType();

  nsRefPtr<gfxSharedImageSurface> back =
    gfxSharedImageSurface::CreateUnsafe(mShadowManager, aSize, format, shmemType);
  if (!back)
    return false;

  *aBuffer = nsnull;
  back.swap(*aBuffer);
  return true;
}
SharedImage* ImageContainerChild::AllocateSharedImageFor(Image* image)
{
  NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                  "Should be in ImageBridgeChild thread.");
  if (!image) {
    return nullptr;
  }

  if (image->GetFormat() == PLANAR_YCBCR ) {
    PlanarYCbCrImage *planarYCbCrImage = static_cast<PlanarYCbCrImage*>(image);
    const PlanarYCbCrImage::Data *data = planarYCbCrImage->GetData();
    NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
    if (!data) {
      return nullptr;
    }

    SharedMemory::SharedMemoryType shmType = OptimalShmemType();
    size_t size = ShmemYCbCrImage::ComputeMinBufferSize(data->mYSize,
                                                        data->mCbCrSize);
    Shmem shmem;
    if (!AllocUnsafeShmem(size, shmType, &shmem)) {
      return nullptr;
    }

    ShmemYCbCrImage::InitializeBufferInfo(shmem.get<uint8_t>(),
                                          data->mYSize,
                                          data->mCbCrSize);
    ShmemYCbCrImage shmemImage(shmem);

    if (!shmemImage.IsValid()) {
      NS_WARNING("Failed to properly allocate image data!");
      DeallocShmem(shmem);
      return nullptr;
    }

    ++mActiveImageCount;
    return new SharedImage(YCbCrImage(shmem, 0, data->GetPictureRect()));
  } else {
    NS_RUNTIMEABORT("TODO: Only YCbCrImage is supported here right now.");
  }
  return nullptr;
}
Exemple #9
0
bool
FixedSizeSmallShmemSectionAllocator::AllocShmemSection(uint32_t aSize, ShmemSection* aShmemSection)
{
  // For now we only support sizes of 4. If we want to support different sizes
  // some more complicated bookkeeping should be added.
  MOZ_ASSERT(aSize == sSupportedBlockSize);
  MOZ_ASSERT(aShmemSection);

  if (!IPCOpen()) {
    gfxCriticalError() << "Attempt to allocate a ShmemSection after shutdown.";
    return false;
  }

  uint32_t allocationSize = (aSize + sizeof(ShmemSectionHeapAllocation));

  for (size_t i = 0; i < mUsedShmems.size(); i++) {
    ShmemSectionHeapHeader* header = mUsedShmems[i].get<ShmemSectionHeapHeader>();
    if ((header->mAllocatedBlocks + 1) * allocationSize + sizeof(ShmemSectionHeapHeader) < sShmemPageSize) {
      aShmemSection->shmem() = mUsedShmems[i];
      MOZ_ASSERT(mUsedShmems[i].IsWritable());
      break;
    }
  }

  if (!aShmemSection->shmem().IsWritable()) {
    ipc::Shmem tmp;
    if (!GetShmAllocator()->AllocUnsafeShmem(sShmemPageSize, OptimalShmemType(), &tmp)) {
      return false;
    }

    ShmemSectionHeapHeader* header = tmp.get<ShmemSectionHeapHeader>();
    header->mTotalBlocks = 0;
    header->mAllocatedBlocks = 0;

    mUsedShmems.push_back(tmp);
    aShmemSection->shmem() = tmp;
  }

  MOZ_ASSERT(aShmemSection->shmem().IsWritable());

  ShmemSectionHeapHeader* header = aShmemSection->shmem().get<ShmemSectionHeapHeader>();
  uint8_t* heap = aShmemSection->shmem().get<uint8_t>() + sizeof(ShmemSectionHeapHeader);

  ShmemSectionHeapAllocation* allocHeader = nullptr;

  if (header->mTotalBlocks > header->mAllocatedBlocks) {
    // Search for the first available block.
    for (size_t i = 0; i < header->mTotalBlocks; i++) {
      allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);

      if (allocHeader->mStatus == STATUS_FREED) {
        break;
      }
      heap += allocationSize;
    }
    MOZ_ASSERT(allocHeader && allocHeader->mStatus == STATUS_FREED);
    MOZ_ASSERT(allocHeader->mSize == sSupportedBlockSize);
  } else {
    heap += header->mTotalBlocks * allocationSize;

    header->mTotalBlocks++;
    allocHeader = reinterpret_cast<ShmemSectionHeapAllocation*>(heap);
    allocHeader->mSize = aSize;
  }

  MOZ_ASSERT(allocHeader);
  header->mAllocatedBlocks++;
  allocHeader->mStatus = STATUS_ALLOCATED;

  aShmemSection->size() = aSize;
  aShmemSection->offset() = (heap + sizeof(ShmemSectionHeapAllocation)) - aShmemSection->shmem().get<uint8_t>();
  ShrinkShmemSectionHeap();
  return true;
}
SharedImage* ImageContainerChild::CreateSharedImageFromData(Image* image)
{
    NS_ABORT_IF_FALSE(InImageBridgeChildThread(),
                      "Should be in ImageBridgeChild thread.");

    if (!image) {
        return nullptr;
    }
    if (image->GetFormat() == PLANAR_YCBCR ) {
        PlanarYCbCrImage *planarYCbCrImage = static_cast<PlanarYCbCrImage*>(image);
        const PlanarYCbCrImage::Data *data = planarYCbCrImage->GetData();
        NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
        if (!data) {
            return nullptr;
        }

        SharedMemory::SharedMemoryType shmType = OptimalShmemType();
        size_t size = ShmemYCbCrImage::ComputeMinBufferSize(data->mYSize,
                      data->mCbCrSize);
        Shmem shmem;
        if (!AllocUnsafeShmem(size, shmType, &shmem)) {
            return nullptr;
        }

        ShmemYCbCrImage::InitializeBufferInfo(shmem.get<uint8_t>(),
                                              data->mYSize,
                                              data->mCbCrSize);
        ShmemYCbCrImage shmemImage(shmem);

        if (!shmemImage.IsValid() || shmem.Size<uint8_t>() < size) {
            DeallocShmem(shmem);
            return nullptr;
        }

        for (int i = 0; i < data->mYSize.height; i++) {
            memcpy(shmemImage.GetYData() + i * shmemImage.GetYStride(),
                   data->mYChannel + i * data->mYStride,
                   data->mYSize.width);
        }
        for (int i = 0; i < data->mCbCrSize.height; i++) {
            memcpy(shmemImage.GetCbData() + i * shmemImage.GetCbCrStride(),
                   data->mCbChannel + i * data->mCbCrStride,
                   data->mCbCrSize.width);
            memcpy(shmemImage.GetCrData() + i * shmemImage.GetCbCrStride(),
                   data->mCrChannel + i * data->mCbCrStride,
                   data->mCbCrSize.width);
        }

        ++mActiveImageCount;
        SharedImage* result = new SharedImage(YCbCrImage(shmem, 0, data->GetPictureRect()));
        return result;
#ifdef MOZ_WIDGET_GONK
    } else if (image->GetFormat() == GONK_IO_SURFACE) {
        GonkIOSurfaceImage* gonkImage = static_cast<GonkIOSurfaceImage*>(image);
        SharedImage* result = new SharedImage(gonkImage->GetSurfaceDescriptor());
        return result;
    } else if (image->GetFormat() == GRALLOC_PLANAR_YCBCR) {
        GrallocPlanarYCbCrImage* GrallocImage = static_cast<GrallocPlanarYCbCrImage*>(image);
        SharedImage* result = new SharedImage(GrallocImage->GetSurfaceDescriptor());
        return result;
#endif
    } else {
        NS_RUNTIMEABORT("TODO: Only YCbCrImage is supported here right now.");
    }
    return nullptr;
}