diff --git a/gfx/layers/YCbCrImageDataSerializer.cpp b/gfx/layers/YCbCrImageDataSerializer.cpp index ed171224f016..99fb2e7f852d 100644 --- a/gfx/layers/YCbCrImageDataSerializer.cpp +++ b/gfx/layers/YCbCrImageDataSerializer.cpp @@ -153,17 +153,18 @@ YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize) } void -YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize, +YCbCrImageDataSerializer::InitializeBufferInfo(uint32_t aYOffset, + uint32_t aCbOffset, + uint32_t aCrOffset, + const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize, StereoMode aStereoMode) { YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData); - info->mYOffset = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo)); - info->mCbOffset = info->mYOffset - + MOZ_ALIGN_WORD(aYSize.width * aYSize.height); - info->mCrOffset = info->mCbOffset - + MOZ_ALIGN_WORD(aCbCrSize.width * aCbCrSize.height); - + uint32_t info_size = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo)); + info->mYOffset = info_size + aYOffset; + info->mCbOffset = info_size + aCbOffset; + info->mCrOffset = info_size + aCrOffset; info->mYWidth = aYSize.width; info->mYHeight = aYSize.height; info->mCbCrWidth = aCbCrSize.width; @@ -171,6 +172,17 @@ YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize, info->mStereoMode = aStereoMode; } +void +YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize, + const gfx::IntSize& aCbCrSize, + StereoMode aStereoMode) +{ + uint32_t yOffset = 0; + uint32_t cbOffset = yOffset + MOZ_ALIGN_WORD(aYSize.width * aYSize.height); + uint32_t crOffset = cbOffset + MOZ_ALIGN_WORD(aCbCrSize.width * aCbCrSize.height); + return InitializeBufferInfo(yOffset, cbOffset, crOffset, aYSize, aCbCrSize, aStereoMode); +} + void YCbCrImageDataSerializer::InitializeBufferInfo(const gfxIntSize& aYSize, const gfxIntSize& aCbCrSize, diff --git a/gfx/layers/YCbCrImageDataSerializer.h b/gfx/layers/YCbCrImageDataSerializer.h index 1ec52ed00ee7..e6b14cdeebf6 100644 --- a/gfx/layers/YCbCrImageDataSerializer.h +++ b/gfx/layers/YCbCrImageDataSerializer.h @@ -114,6 +114,12 @@ public: * The provided pointer should point to the beginning of the (chunk of) * buffer on which we want to store the image. */ + void InitializeBufferInfo(uint32_t aYOffset, + uint32_t aCbOffset, + uint32_t aCrOffset, + const gfx::IntSize& aYSize, + const gfx::IntSize& aCbCrSize, + StereoMode aStereoMode); void InitializeBufferInfo(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize, StereoMode aStereoMode); diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp index f90226221072..a4b7ebe1c5e6 100644 --- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp +++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp @@ -143,8 +143,21 @@ SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData) { mData = aData; mSize = aData.mPicSize; + /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating + * memory previously allocated with AllocateAndGetNewBuffer(). + * serializer.GetData() returns the address of the memory previously allocated + * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr + * channels to compute 0-based offsets to pass to InitializeBufferInfo. + */ YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer()); - serializer.InitializeBufferInfo(aData.mYSize, + uint8_t *base = serializer.GetData(); + uint32_t yOffset = aData.mYChannel - base; + uint32_t cbOffset = aData.mCbChannel - base; + uint32_t crOffset = aData.mCrChannel - base; + serializer.InitializeBufferInfo(yOffset, + cbOffset, + crOffset, + aData.mYSize, aData.mCbCrSize, aData.mStereoMode); }