gfx/layers/ipc/SharedPlanarYCbCrImage.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,224 @@
     1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "SharedPlanarYCbCrImage.h"
    1.10 +#include <stddef.h>                     // for size_t
    1.11 +#include <stdio.h>                      // for printf
    1.12 +#include "gfx2DGlue.h"                  // for Moz2D transition helpers
    1.13 +#include "ISurfaceAllocator.h"          // for ISurfaceAllocator, etc
    1.14 +#include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    1.15 +#include "mozilla/gfx/Types.h"          // for SurfaceFormat::SurfaceFormat::YUV
    1.16 +#include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
    1.17 +#include "mozilla/layers/ImageClient.h"  // for ImageClient
    1.18 +#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
    1.19 +#include "mozilla/layers/TextureClient.h"  // for BufferTextureClient, etc
    1.20 +#include "mozilla/layers/YCbCrImageDataSerializer.h"
    1.21 +#include "mozilla/layers/ImageBridgeChild.h"  // for ImageBridgeChild
    1.22 +#include "mozilla/mozalloc.h"           // for operator delete
    1.23 +#include "nsISupportsImpl.h"            // for Image::AddRef
    1.24 +#include "mozilla/ipc/Shmem.h"
    1.25 +
    1.26 +namespace mozilla {
    1.27 +namespace layers {
    1.28 +
    1.29 +using namespace mozilla::ipc;
    1.30 +
    1.31 +SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable)
    1.32 +: PlanarYCbCrImage(nullptr)
    1.33 +, mCompositable(aCompositable)
    1.34 +{
    1.35 +  mTextureClient = aCompositable->CreateBufferTextureClient(gfx::SurfaceFormat::YUV);
    1.36 +  MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
    1.37 +}
    1.38 +
    1.39 +SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
    1.40 +  MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
    1.41 +
    1.42 +  if (mCompositable->GetAsyncID() != 0 &&
    1.43 +      !InImageBridgeChildThread()) {
    1.44 +    ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().drop());
    1.45 +    ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().drop());
    1.46 +  }
    1.47 +}
    1.48 +
    1.49 +size_t
    1.50 +SharedPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
    1.51 +{
    1.52 +  // NB: Explicitly skipping mTextureClient, the memory is already reported
    1.53 +  //     at time of allocation in GfxMemoryImageReporter.
    1.54 +  // Not owned:
    1.55 +  // - mCompositable
    1.56 +  size_t size = PlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf);
    1.57 +  return size;
    1.58 +}
    1.59 +
    1.60 +TextureClient*
    1.61 +SharedPlanarYCbCrImage::GetTextureClient(CompositableClient* aClient)
    1.62 +{
    1.63 +  return mTextureClient.get();
    1.64 +}
    1.65 +
    1.66 +uint8_t*
    1.67 +SharedPlanarYCbCrImage::GetBuffer()
    1.68 +{
    1.69 +  return mTextureClient->GetBuffer();
    1.70 +}
    1.71 +
    1.72 +TemporaryRef<gfx::SourceSurface>
    1.73 +SharedPlanarYCbCrImage::GetAsSourceSurface()
    1.74 +{
    1.75 +  if (!mTextureClient->IsAllocated()) {
    1.76 +    NS_WARNING("Can't get as surface");
    1.77 +    return nullptr;
    1.78 +  }
    1.79 +  return PlanarYCbCrImage::GetAsSourceSurface();
    1.80 +}
    1.81 +
    1.82 +void
    1.83 +SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
    1.84 +{
    1.85 +  // If mShmem has not been allocated (through Allocate(aData)), allocate it.
    1.86 +  // This code path is slower than the one used when Allocate has been called
    1.87 +  // since it will trigger a full copy.
    1.88 +  if (!mTextureClient->IsAllocated()) {
    1.89 +    Data data = aData;
    1.90 +    if (!Allocate(data)) {
    1.91 +      NS_WARNING("SharedPlanarYCbCrImage::SetData failed to allocate");
    1.92 +      return;
    1.93 +    }
    1.94 +  }
    1.95 +
    1.96 +  MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
    1.97 +  if (!mTextureClient->Lock(OPEN_WRITE_ONLY)) {
    1.98 +    MOZ_ASSERT(false, "Failed to lock the texture.");
    1.99 +    return;
   1.100 +  }
   1.101 +  TextureClientAutoUnlock unlock(mTextureClient);
   1.102 +  if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
   1.103 +    MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
   1.104 +    return;
   1.105 +  }
   1.106 +  // do not set mBuffer like in PlanarYCbCrImage because the later
   1.107 +  // will try to manage this memory without knowing it belongs to a
   1.108 +  // shmem.
   1.109 +  mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
   1.110 +                                                               mData.mCbCrSize);
   1.111 +  mSize = mData.mPicSize;
   1.112 +
   1.113 +  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   1.114 +  mData.mYChannel = serializer.GetYData();
   1.115 +  mData.mCbChannel = serializer.GetCbData();
   1.116 +  mData.mCrChannel = serializer.GetCrData();
   1.117 +  mTextureClient->MarkImmutable();
   1.118 +}
   1.119 +
   1.120 +// needs to be overriden because the parent class sets mBuffer which we
   1.121 +// do not want to happen.
   1.122 +uint8_t*
   1.123 +SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
   1.124 +{
   1.125 +  NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), "This image already has allocated data");
   1.126 +  size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aSize);
   1.127 +
   1.128 +  // get new buffer _without_ setting mBuffer.
   1.129 +  if (!mTextureClient->Allocate(size)) {
   1.130 +    return nullptr;
   1.131 +  }
   1.132 +
   1.133 +  // update buffer size
   1.134 +  mBufferSize = size;
   1.135 +
   1.136 +  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   1.137 +  return serializer.GetData();
   1.138 +}
   1.139 +
   1.140 +void
   1.141 +SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
   1.142 +{
   1.143 +  mData = aData;
   1.144 +  mSize = aData.mPicSize;
   1.145 +  /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating
   1.146 +   * memory previously allocated with AllocateAndGetNewBuffer().
   1.147 +   * serializer.GetData() returns the address of the memory previously allocated
   1.148 +   * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
   1.149 +   * channels to compute 0-based offsets to pass to InitializeBufferInfo.
   1.150 +   */
   1.151 +  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   1.152 +  uint8_t *base = serializer.GetData();
   1.153 +  uint32_t yOffset = aData.mYChannel - base;
   1.154 +  uint32_t cbOffset = aData.mCbChannel - base;
   1.155 +  uint32_t crOffset = aData.mCrChannel - base;
   1.156 +  serializer.InitializeBufferInfo(yOffset,
   1.157 +                                  cbOffset,
   1.158 +                                  crOffset,
   1.159 +                                  aData.mYStride,
   1.160 +                                  aData.mCbCrStride,
   1.161 +                                  aData.mYSize,
   1.162 +                                  aData.mCbCrSize,
   1.163 +                                  aData.mStereoMode);
   1.164 +}
   1.165 +
   1.166 +uint8_t*
   1.167 +SharedPlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
   1.168 +{
   1.169 +  NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
   1.170 +                    "This image already has allocated data");
   1.171 +  if (!mTextureClient->Allocate(aSize)) {
   1.172 +    return nullptr;
   1.173 +  }
   1.174 +  return mTextureClient->GetBuffer();
   1.175 +}
   1.176 +
   1.177 +bool
   1.178 +SharedPlanarYCbCrImage::IsValid() {
   1.179 +  return mTextureClient->IsAllocated();
   1.180 +}
   1.181 +
   1.182 +bool
   1.183 +SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
   1.184 +{
   1.185 +  NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
   1.186 +                    "This image already has allocated data");
   1.187 +
   1.188 +  size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize,
   1.189 +                                                               aData.mCbCrSize);
   1.190 +
   1.191 +  if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) {
   1.192 +    return false;
   1.193 +  }
   1.194 +
   1.195 +  YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
   1.196 +  serializer.InitializeBufferInfo(aData.mYSize,
   1.197 +                                  aData.mCbCrSize,
   1.198 +                                  aData.mStereoMode);
   1.199 +  MOZ_ASSERT(serializer.IsValid());
   1.200 +
   1.201 +  aData.mYChannel = serializer.GetYData();
   1.202 +  aData.mCbChannel = serializer.GetCbData();
   1.203 +  aData.mCrChannel = serializer.GetCrData();
   1.204 +
   1.205 +  // copy some of aData's values in mData (most of them)
   1.206 +  mData.mYChannel = aData.mYChannel;
   1.207 +  mData.mCbChannel = aData.mCbChannel;
   1.208 +  mData.mCrChannel = aData.mCrChannel;
   1.209 +  mData.mYSize = aData.mYSize;
   1.210 +  mData.mCbCrSize = aData.mCbCrSize;
   1.211 +  mData.mPicX = aData.mPicX;
   1.212 +  mData.mPicY = aData.mPicY;
   1.213 +  mData.mPicSize = aData.mPicSize;
   1.214 +  mData.mStereoMode = aData.mStereoMode;
   1.215 +  // those members are not always equal to aData's, due to potentially different
   1.216 +  // packing.
   1.217 +  mData.mYSkip = 0;
   1.218 +  mData.mCbSkip = 0;
   1.219 +  mData.mCrSkip = 0;
   1.220 +  mData.mYStride = mData.mYSize.width;
   1.221 +  mData.mCbCrStride = mData.mCbCrSize.width;
   1.222 +
   1.223 +  return true;
   1.224 +}
   1.225 +
   1.226 +} // namespace
   1.227 +} // namespace

mercurial