Bug 1215089 - P6: Add support for 10/12 bits YUV surface with basic compositor. r=mattwoodrow

MozReview-Commit-ID: Ej4MbvHnSk9

--HG--
extra : rebase_source : 69b342e18829816ca3cdd91a3f01252ae2a1ac94
This commit is contained in:
Jean-Yves Avenard 2017-09-29 16:37:56 +02:00
parent 6e1769b5cd
commit 9a3a9f486e
17 changed files with 202 additions and 94 deletions

View File

@ -92,6 +92,7 @@ BytesPerPixel(SurfaceFormat aFormat)
case SurfaceFormat::A8:
return 1;
case SurfaceFormat::R5G6B5_UINT16:
case SurfaceFormat::A16:
return 2;
case SurfaceFormat::R8G8B8:
case SurfaceFormat::B8G8R8:
@ -106,6 +107,19 @@ BytesPerPixel(SurfaceFormat aFormat)
}
}
static inline SurfaceFormat
SurfaceFormatForAlphaDepth(uint32_t aDepth)
{
if (aDepth == 8) {
return SurfaceFormat::A8;
} else if (aDepth == 10 ||
aDepth == 12) {
return SurfaceFormat::A16;
}
MOZ_ASSERT_UNREACHABLE("Unsupported alpha depth");
return SurfaceFormat::UNKNOWN;
}
static inline bool
IsOpaqueFormat(SurfaceFormat aFormat) {
switch (aFormat) {

View File

@ -56,6 +56,7 @@ enum class SurfaceFormat : int8_t {
// This one is a single-byte, so endianness isn't an issue.
A8,
A16,
R8G8,

View File

@ -159,6 +159,7 @@ BufferTextureData*
BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
int32_t aBufferSize,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags)
{
if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
@ -171,9 +172,10 @@ BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
// Initialize the metadata with something, even if it will have to be rewritten
// afterwards since we don't know the dimensions of the texture at this point.
BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), gfx::IntSize(),
BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), 0, gfx::IntSize(), 0,
0, 0, 0, StereoMode::MONO,
aYUVColorSpace,
aDepth,
hasIntermediateBuffer);
return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr,
@ -183,12 +185,16 @@ BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
BufferTextureData*
BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
gfx::IntSize aYSize,
uint32_t aYStride,
gfx::IntSize aCbCrSize,
uint32_t aCbCrStride,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags)
{
uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(
aYSize, aYStride, aCbCrSize, aCbCrStride);
if (bufSize == 0) {
return nullptr;
}
@ -196,20 +202,30 @@ BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
uint32_t yOffset;
uint32_t cbOffset;
uint32_t crOffset;
ImageDataSerializer::ComputeYCbCrOffsets(aYSize.width, aYSize.height,
aCbCrSize.width, aCbCrSize.height,
yOffset, cbOffset, crOffset);
ImageDataSerializer::ComputeYCbCrOffsets(aYStride, aYSize.height,
aCbCrStride, aCbCrSize.height,
yOffset, cbOffset, crOffset);
bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
aAllocator->GetCompositorBackendType())
: true;
bool hasIntermediateBuffer =
aAllocator
? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
aAllocator->GetCompositorBackendType())
: true;
YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aCbCrSize, yOffset, cbOffset,
crOffset, aStereoMode, aYUVColorSpace,
YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aYStride,
aCbCrSize, aCbCrStride,
yOffset, cbOffset, crOffset,
aStereoMode,
aYUVColorSpace,
aDepth,
hasIntermediateBuffer);
return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr, descriptor,
gfx::BackendType::NONE, bufSize, aTextureFlags);
return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder()
: nullptr,
descriptor,
gfx::BackendType::NONE,
bufSize,
aTextureFlags);
}
void
@ -254,6 +270,12 @@ BufferTextureData::GetYUVColorSpace() const
return ImageDataSerializer::YUVColorSpaceFromBufferDescriptor(mDescriptor);
}
Maybe<uint32_t>
BufferTextureData::GetDepth() const
{
return ImageDataSerializer::DepthFromBufferDescriptor(mDescriptor);
}
Maybe<StereoMode>
BufferTextureData::GetStereoMode() const
{
@ -351,17 +373,17 @@ BufferTextureData::BorrowMappedYCbCrData(MappedYCbCrTextureData& aMap)
aMap.y.data = data + desc.yOffset();
aMap.y.size = ySize;
aMap.y.stride = ySize.width;
aMap.y.stride = desc.yStride();
aMap.y.skip = 0;
aMap.cb.data = data + desc.cbOffset();
aMap.cb.size = cbCrSize;
aMap.cb.stride = cbCrSize.width;
aMap.cb.stride = desc.cbCrStride();
aMap.cb.skip = 0;
aMap.cr.data = data + desc.crOffset();
aMap.cr.size = cbCrSize;
aMap.cr.stride = cbCrSize.width;
aMap.cr.stride = desc.cbCrStride();
aMap.cr.skip = 0;
return true;

View File

@ -30,9 +30,12 @@ public:
static BufferTextureData* CreateForYCbCr(KnowsCompositor* aAllocator,
gfx::IntSize aYSize,
uint32_t aYStride,
gfx::IntSize aCbCrSize,
uint32_t aCbCrStride,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags);
// It is generally better to use CreateForYCbCr instead.
@ -41,6 +44,7 @@ public:
static BufferTextureData* CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
int32_t aSize,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags);
virtual bool Lock(OpenMode aMode) override { return true; }
@ -67,6 +71,8 @@ public:
Maybe<YUVColorSpace> GetYUVColorSpace() const;
Maybe<uint32_t> GetDepth() const;
Maybe<StereoMode> GetStereoMode() const;
protected:

View File

@ -161,14 +161,16 @@ struct EffectRGB : public TexturedEffect
struct EffectYCbCr : public TexturedEffect
{
EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, gfx::SamplingFilter aSamplingFilter)
EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, uint32_t aDepth, gfx::SamplingFilter aSamplingFilter)
: TexturedEffect(EffectTypes::YCBCR, aSource, false, aSamplingFilter)
, mYUVColorSpace(aYUVColorSpace)
, mDepth(aDepth)
{}
virtual const char* Name() { return "EffectYCbCr"; }
YUVColorSpace mYUVColorSpace;
uint32_t mDepth;
};
struct EffectNV12 : public TexturedEffect
@ -270,7 +272,8 @@ CreateTexturedEffect(TextureHost* aHost,
RefPtr<TexturedEffect> result;
if (aHost->GetReadFormat() == gfx::SurfaceFormat::YUV) {
MOZ_ASSERT(aHost->GetYUVColorSpace() != YUVColorSpace::UNKNOWN);
result = new EffectYCbCr(aSource, aHost->GetYUVColorSpace(), aSamplingFilter);
result = new EffectYCbCr(
aSource, aHost->GetYUVColorSpace(), aHost->GetDepth(), aSamplingFilter);
} else {
result = CreateTexturedEffect(aHost->GetReadFormat(),
aSource,

View File

@ -71,18 +71,12 @@ ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, int32_t aYStride,
!gfx::Factory::AllowedSurfaceSize(IntSize(aCbCrStride, aCbCrSize.height))) {
return 0;
}
// Overflow checks are performed in AllowedSurfaceSize
return GetAlignedStride<4>(aYSize.height, aYStride) +
2 * GetAlignedStride<4>(aCbCrSize.height, aCbCrStride);
}
// Minimum required shmem size in bytes
uint32_t
ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize)
{
return ComputeYCbCrBufferSize(aYSize, aYSize.width, aCbCrSize, aCbCrSize.width);
}
uint32_t
ComputeYCbCrBufferSize(uint32_t aBufferSize)
{
@ -136,7 +130,6 @@ Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescri
}
Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor)
{
{
switch (aDescriptor.type()) {
case BufferDescriptor::TRGBDescriptor:
@ -144,9 +137,20 @@ Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& a
case BufferDescriptor::TYCbCrDescriptor:
return Some(aDescriptor.get_YCbCrDescriptor().yUVColorSpace());
default:
MOZ_CRASH("GFX: CbCrSizeFromBufferDescriptor");
MOZ_CRASH("GFX: YUVColorSpaceFromBufferDescriptor");
}
}
Maybe<uint32_t> DepthFromBufferDescriptor(const BufferDescriptor& aDescriptor)
{
switch (aDescriptor.type()) {
case BufferDescriptor::TRGBDescriptor:
return Nothing();
case BufferDescriptor::TYCbCrDescriptor:
return Some(aDescriptor.get_YCbCrDescriptor().depth());
default:
MOZ_CRASH("GFX: DepthFromBufferDescriptor");
}
}
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
@ -157,7 +161,7 @@ Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescri
case BufferDescriptor::TYCbCrDescriptor:
return Some(aDescriptor.get_YCbCrDescriptor().stereoMode());
default:
MOZ_CRASH("GFX: CbCrSizeFromBufferDescriptor");
MOZ_CRASH("GFX: StereoModeFromBufferDescriptor");
}
}
@ -180,9 +184,6 @@ already_AddRefed<DataSourceSurface>
DataSourceSurfaceFromYCbCrDescriptor(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor, gfx::DataSourceSurface* aSurface)
{
gfx::IntSize ySize = aDescriptor.ySize();
gfx::IntSize cbCrSize = aDescriptor.cbCrSize();
int32_t yStride = ySize.width;
int32_t cbCrStride = cbCrSize.width;
RefPtr<DataSourceSurface> result;
if (aSurface) {
@ -209,14 +210,15 @@ DataSourceSurfaceFromYCbCrDescriptor(uint8_t* aBuffer, const YCbCrDescriptor& aD
layers::PlanarYCbCrData ycbcrData;
ycbcrData.mYChannel = GetYChannel(aBuffer, aDescriptor);
ycbcrData.mYStride = yStride;
ycbcrData.mYStride = aDescriptor.yStride();
ycbcrData.mYSize = ySize;
ycbcrData.mCbChannel = GetCbChannel(aBuffer, aDescriptor);
ycbcrData.mCrChannel = GetCrChannel(aBuffer, aDescriptor);
ycbcrData.mCbCrStride = cbCrStride;
ycbcrData.mCbCrSize = cbCrSize;
ycbcrData.mCbCrStride = aDescriptor.cbCrStride();
ycbcrData.mCbCrSize = aDescriptor.cbCrSize();
ycbcrData.mPicSize = ySize;
ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
ycbcrData.mDepth = aDescriptor.depth();
gfx::ConvertYCbCrToRGB(ycbcrData,
gfx::SurfaceFormat::B8G8R8X8,
@ -237,21 +239,18 @@ ConvertAndScaleFromYCbCrDescriptor(uint8_t* aBuffer,
int32_t aStride)
{
MOZ_ASSERT(aBuffer);
gfx::IntSize ySize = aDescriptor.ySize();
gfx::IntSize cbCrSize = aDescriptor.cbCrSize();
int32_t yStride = ySize.width;
int32_t cbCrStride = cbCrSize.width;
layers::PlanarYCbCrData ycbcrData;
ycbcrData.mYChannel = GetYChannel(aBuffer, aDescriptor);
ycbcrData.mYStride = yStride;
ycbcrData.mYSize = ySize;
ycbcrData.mYStride = aDescriptor.yStride();;
ycbcrData.mYSize = aDescriptor.ySize();
ycbcrData.mCbChannel = GetCbChannel(aBuffer, aDescriptor);
ycbcrData.mCrChannel = GetCrChannel(aBuffer, aDescriptor);
ycbcrData.mCbCrStride = cbCrStride;
ycbcrData.mCbCrSize = cbCrSize;
ycbcrData.mPicSize = ySize;
ycbcrData.mCbCrStride = aDescriptor.cbCrStride();
ycbcrData.mCbCrSize = aDescriptor.cbCrSize();
ycbcrData.mPicSize = aDescriptor.ySize();
ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
ycbcrData.mDepth = aDescriptor.depth();
gfx::ConvertYCbCrToRGB(ycbcrData, aDestFormat, aDestSize, aDestBuffer, aStride);
}

View File

@ -45,9 +45,6 @@ uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize,
int32_t aYStride,
const gfx::IntSize& aCbCrSize,
int32_t aCbCrStride);
uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize,
const gfx::IntSize& aCbCrSize);
uint32_t ComputeYCbCrBufferSize(uint32_t aBufferSize);
void ComputeYCbCrOffsets(int32_t yStride, int32_t yHeight,
@ -62,6 +59,8 @@ Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescri
Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor);
Maybe<uint32_t> DepthFromBufferDescriptor(const BufferDescriptor& aDescriptor);
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);

View File

@ -101,8 +101,11 @@ ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwar
return nullptr;
}
texture = TextureClient::CreateForYCbCr(aForwarder,
data->mYSize, data->mCbCrSize, data->mStereoMode,
data->mYSize, data->mYStride,
data->mCbCrSize, data->mCbCrStride,
data->mStereoMode,
data->mYUVColorSpace,
data->mDepth,
TextureFlags::DEFAULT);
if (!texture) {
return nullptr;

View File

@ -1256,9 +1256,12 @@ TextureClient::CreateForRawBufferAccess(LayersIPCChannel* aAllocator,
already_AddRefed<TextureClient>
TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
gfx::IntSize aYSize,
uint32_t aYStride,
gfx::IntSize aCbCrSize,
uint32_t aCbCrStride,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags)
{
if (!aAllocator || !aAllocator->GetLayersIPCActor()->IPCOpen()) {
@ -1269,9 +1272,12 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
return nullptr;
}
TextureData* data = BufferTextureData::CreateForYCbCr(aAllocator, aYSize, aCbCrSize,
aStereoMode, aYUVColorSpace,
aTextureFlags);
TextureData* data =
BufferTextureData::CreateForYCbCr(aAllocator,
aYSize, aYStride,
aCbCrSize, aCbCrStride,
aStereoMode, aYUVColorSpace,
aDepth, aTextureFlags);
if (!data) {
return nullptr;
}
@ -1285,15 +1291,15 @@ already_AddRefed<TextureClient>
TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
size_t aSize,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags)
{
if (!aAllocator || !aAllocator->GetLayersIPCActor()->IPCOpen()) {
return nullptr;
}
TextureData* data =
BufferTextureData::CreateForYCbCrWithBufferSize(aAllocator, aSize, aYUVColorSpace,
aTextureFlags);
TextureData* data = BufferTextureData::CreateForYCbCrWithBufferSize(
aAllocator, aSize, aYUVColorSpace, aDepth, aTextureFlags);
if (!data) {
return nullptr;
}
@ -1302,26 +1308,28 @@ TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
aAllocator->GetTextureForwarder());
}
TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, LayersIPCChannel* aAllocator)
: AtomicRefCountedWithFinalize("TextureClient")
, mAllocator(aAllocator)
, mActor(nullptr)
, mData(aData)
, mFlags(aFlags)
, mOpenMode(OpenMode::OPEN_NONE)
TextureClient::TextureClient(TextureData* aData,
TextureFlags aFlags,
LayersIPCChannel* aAllocator)
: AtomicRefCountedWithFinalize("TextureClient")
, mAllocator(aAllocator)
, mActor(nullptr)
, mData(aData)
, mFlags(aFlags)
, mOpenMode(OpenMode::OPEN_NONE)
#ifdef DEBUG
, mExpectedDtRefs(0)
, mExpectedDtRefs(0)
#endif
, mIsLocked(false)
, mIsReadLocked(false)
, mUpdated(false)
, mAddedToCompositableClient(false)
, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
, mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false)
, mFwdTransactionId(0)
, mSerial(++sSerialCounter)
, mIsLocked(false)
, mIsReadLocked(false)
, mUpdated(false)
, mAddedToCompositableClient(false)
, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
, mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false)
, mFwdTransactionId(0)
, mSerial(++sSerialCounter)
#ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
, mPoolTracker(nullptr)
, mPoolTracker(nullptr)
#endif
{
mData->FillInfo(mInfo);
@ -1757,14 +1765,18 @@ UpdateYCbCrTextureClient(TextureClient* aTexture, const PlanarYCbCrData& aData)
srcData.y.size = aData.mYSize;
srcData.y.stride = aData.mYStride;
srcData.y.skip = aData.mYSkip;
MOZ_ASSERT(aData.mDepth == 8 || (aData.mDepth > 8 && aData.mDepth <= 16));
srcData.y.bytesPerPixel = (aData.mDepth > 8) ? 2 : 1;
srcData.cb.data = aData.mCbChannel;
srcData.cb.size = aData.mCbCrSize;
srcData.cb.stride = aData.mCbCrStride;
srcData.cb.skip = aData.mCbSkip;
srcData.cb.bytesPerPixel = (aData.mDepth > 8) ? 2 : 1;
srcData.cr.data = aData.mCrChannel;
srcData.cr.size = aData.mCbCrSize;
srcData.cr.stride = aData.mCbCrStride;
srcData.cr.skip = aData.mCrSkip;
srcData.cr.bytesPerPixel = (aData.mDepth > 8) ? 2 : 1;
srcData.metadata = nullptr;
if (!srcData.CopyInto(mapped)) {
@ -1809,15 +1821,19 @@ MappedYCbCrChannelData::CopyInto(MappedYCbCrChannelData& aDst)
// fast-ish path
memcpy(aDst.data + i * aDst.stride,
data + i * stride,
size.width);
size.width * bytesPerPixel);
} else {
// slow path
uint8_t* src = data + i * stride;
uint8_t* dst = aDst.data + i * aDst.stride;
for (int32_t j = 0; j < size.width; ++j) {
*dst = *src;
src += 1 + skip;
dst += 1 + aDst.skip;
for (uint32_t k = 0; k < bytesPerPixel; ++k) {
*dst = *src;
src += 1;
dst += 1;
}
src += skip;
dst += aDst.skip;
}
}
}

View File

@ -139,6 +139,7 @@ struct MappedYCbCrChannelData
gfx::IntSize size;
int32_t stride;
int32_t skip;
uint32_t bytesPerPixel;
bool CopyInto(MappedYCbCrChannelData& aDst);
};
@ -347,9 +348,12 @@ public:
static already_AddRefed<TextureClient>
CreateForYCbCr(KnowsCompositor* aAllocator,
gfx::IntSize aYSize,
uint32_t aYStride,
gfx::IntSize aCbCrSize,
uint32_t aCbCrStride,
StereoMode aStereoMode,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags);
// Creates and allocates a TextureClient (can be accessed through raw
@ -369,6 +373,7 @@ public:
CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
size_t aSize,
YUVColorSpace aYUVColorSpace,
uint32_t aDepth,
TextureFlags aTextureFlags);
// Creates and allocates a TextureClient of the same type.

View File

@ -108,6 +108,8 @@ YCbCrTextureClientAllocationHelper::IsCompatible(TextureClient* aTextureClient)
bufferData->GetCbCrSize().ref() != mData.mCbCrSize ||
bufferData->GetYUVColorSpace().isNothing() ||
bufferData->GetYUVColorSpace().ref() != mData.mYUVColorSpace ||
bufferData->GetDepth().isNothing() ||
bufferData->GetDepth().ref() != mData.mDepth ||
bufferData->GetStereoMode().isNothing() ||
bufferData->GetStereoMode().ref() != mData.mStereoMode) {
return false;
@ -119,9 +121,11 @@ already_AddRefed<TextureClient>
YCbCrTextureClientAllocationHelper::Allocate(KnowsCompositor* aAllocator)
{
return TextureClient::CreateForYCbCr(aAllocator,
mData.mYSize, mData.mCbCrSize,
mData.mYSize, mData.mYStride,
mData.mCbCrSize, mData.mCbCrStride,
mData.mStereoMode,
mData.mYUVColorSpace,
mData.mDepth,
mTextureFlags);
}

View File

@ -446,7 +446,7 @@ TextureSource::Name() const
MOZ_CRASH("GFX: TextureSource without class name");
return "TextureSource";
}
BufferTextureHost::BufferTextureHost(const BufferDescriptor& aDesc,
TextureFlags aFlags)
: TextureHost(aFlags)
@ -880,6 +880,16 @@ BufferTextureHost::GetYUVColorSpace() const
return YUVColorSpace::UNKNOWN;
}
uint32_t
BufferTextureHost::GetDepth() const
{
if (mFormat == gfx::SurfaceFormat::YUV) {
const YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
return desc.depth();
}
return 8;
}
bool
BufferTextureHost::UploadIfNeeded()
{
@ -986,19 +996,19 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
RefPtr<gfx::DataSourceSurface> tempY =
gfx::Factory::CreateWrappingDataSourceSurface(ImageDataSerializer::GetYChannel(buf, desc),
desc.ySize().width,
desc.yStride(),
desc.ySize(),
gfx::SurfaceFormat::A8);
SurfaceFormatForAlphaDepth(desc.depth()));
RefPtr<gfx::DataSourceSurface> tempCb =
gfx::Factory::CreateWrappingDataSourceSurface(ImageDataSerializer::GetCbChannel(buf, desc),
desc.cbCrSize().width,
desc.cbCrStride(),
desc.cbCrSize(),
gfx::SurfaceFormat::A8);
SurfaceFormatForAlphaDepth(desc.depth()));
RefPtr<gfx::DataSourceSurface> tempCr =
gfx::Factory::CreateWrappingDataSourceSurface(ImageDataSerializer::GetCrChannel(buf, desc),
desc.cbCrSize().width,
desc.cbCrStride(),
desc.cbCrSize(),
gfx::SurfaceFormat::A8);
SurfaceFormatForAlphaDepth(desc.depth()));
// We don't support partial updates for Y U V textures
NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
if (!tempY ||

View File

@ -438,6 +438,11 @@ public:
virtual YUVColorSpace GetYUVColorSpace() const { return YUVColorSpace::UNKNOWN; }
/**
* Return the bit depth of the image. Used with YUV textures.
*/
virtual uint32_t GetDepth() const { return 8; }
/**
* Called during the transaction. The TextureSource may or may not be composited.
*
@ -732,6 +737,8 @@ public:
virtual YUVColorSpace GetYUVColorSpace() const override;
virtual uint32_t GetDepth() const override;
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;

View File

@ -100,12 +100,15 @@ struct RGBDescriptor {
struct YCbCrDescriptor {
IntSize ySize;
uint32_t yStride;
IntSize cbCrSize;
uint32_t cbCrStride;
uint32_t yOffset;
uint32_t cbOffset;
uint32_t crOffset;
StereoMode stereoMode;
YUVColorSpace yUVColorSpace;
uint32_t depth;
bool hasIntermediateBuffer;
};

View File

@ -113,13 +113,21 @@ SharedPlanarYCbCrImage::AdoptData(const Data& aData)
uint32_t crOffset = aData.mCrChannel - base;
auto fwd = mCompositable->GetForwarder();
bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
fwd->GetCompositorBackendType());
bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(
gfx::SurfaceFormat::YUV, fwd->GetCompositorBackendType());
static_cast<BufferTextureData*>(mTextureClient->GetInternalData())->SetDesciptor(
YCbCrDescriptor(aData.mYSize, aData.mCbCrSize, yOffset, cbOffset, crOffset,
aData.mStereoMode, aData.mYUVColorSpace, hasIntermediateBuffer)
);
static_cast<BufferTextureData*>(mTextureClient->GetInternalData())
->SetDesciptor(YCbCrDescriptor(aData.mYSize,
aData.mYStride,
aData.mCbCrSize,
aData.mCbCrStride,
yOffset,
cbOffset,
crOffset,
aData.mStereoMode,
aData.mYUVColorSpace,
aData.mDepth,
hasIntermediateBuffer));
return true;
}
@ -175,18 +183,20 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
mData.mPicSize = aData.mPicSize;
mData.mStereoMode = aData.mStereoMode;
mData.mYUVColorSpace = aData.mYUVColorSpace;
mData.mDepth = aData.mDepth;
// those members are not always equal to aData's, due to potentially different
// packing.
mData.mYSkip = 0;
mData.mCbSkip = 0;
mData.mCrSkip = 0;
mData.mYStride = mData.mYSize.width;
mData.mCbCrStride = mData.mCbCrSize.width;
mData.mYStride = aData.mYStride;
mData.mCbCrStride = aData.mCbCrStride;
// do not set mBuffer like in PlanarYCbCrImage because the later
// will try to manage this memory without knowing it belongs to a
// shmem.
mBufferSize = ImageDataSerializer::ComputeYCbCrBufferSize(mData.mYSize, mData.mCbCrSize);
mBufferSize = ImageDataSerializer::ComputeYCbCrBufferSize(
mData.mYSize, mData.mYStride, mData.mCbCrSize, mData.mCbCrStride);
mSize = mData.mPicSize;
mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);

View File

@ -262,6 +262,7 @@ TEST(Layers, TextureYCbCrSerialization) {
clientData.mCbCrStride = cbSurface->Stride();
clientData.mStereoMode = StereoMode::MONO;
clientData.mYUVColorSpace = YUVColorSpace::BT601;
clientData.mDepth = 8;
clientData.mYSkip = 0;
clientData.mCbSkip = 0;
clientData.mCrSkip = 0;
@ -290,9 +291,9 @@ TEST(Layers, TextureYCbCrSerialization) {
return;
}
RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(imageBridge, clientData.mYSize, clientData.mCbCrSize,
RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(imageBridge, clientData.mYSize, clientData.mYStride, clientData.mCbCrSize, clientData.mCbCrStride,
StereoMode::MONO, YUVColorSpace::BT601,
TextureFlags::DEALLOCATE_CLIENT);
8, TextureFlags::DEALLOCATE_CLIENT);
TestTextureClientYCbCr(client, clientData);

View File

@ -62,9 +62,14 @@ CreateYCbCrTextureClientWithBackend(LayersBackend aLayersBackend)
// Create YCbCrTexture for basice backend.
if (aLayersBackend == LayersBackend::LAYERS_BASIC) {
return TextureClient::CreateForYCbCr(nullptr, clientData.mYSize,
clientData.mCbCrSize, StereoMode::MONO,
return TextureClient::CreateForYCbCr(nullptr,
clientData.mYSize,
clientData.mYStride,
clientData.mCbCrSize,
clientData.mCbCrStride,
StereoMode::MONO,
YUVColorSpace::BT601,
8,
TextureFlags::DEALLOCATE_CLIENT);
}