mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
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:
parent
6e1769b5cd
commit
9a3a9f486e
@ -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) {
|
||||
|
@ -56,6 +56,7 @@ enum class SurfaceFormat : int8_t {
|
||||
|
||||
// This one is a single-byte, so endianness isn't an issue.
|
||||
A8,
|
||||
A16,
|
||||
|
||||
R8G8,
|
||||
|
||||
|
@ -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,
|
||||
ImageDataSerializer::ComputeYCbCrOffsets(aYStride, aYSize.height,
|
||||
aCbCrStride, aCbCrSize.height,
|
||||
yOffset, cbOffset, crOffset);
|
||||
|
||||
bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
|
||||
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;
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
TextureData* data =
|
||||
BufferTextureData::CreateForYCbCr(aAllocator,
|
||||
aYSize, aYStride,
|
||||
aCbCrSize, aCbCrStride,
|
||||
aStereoMode, aYUVColorSpace,
|
||||
aTextureFlags);
|
||||
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,7 +1308,9 @@ TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||
aAllocator->GetTextureForwarder());
|
||||
}
|
||||
|
||||
TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, LayersIPCChannel* aAllocator)
|
||||
TextureClient::TextureClient(TextureData* aData,
|
||||
TextureFlags aFlags,
|
||||
LayersIPCChannel* aAllocator)
|
||||
: AtomicRefCountedWithFinalize("TextureClient")
|
||||
, mAllocator(aAllocator)
|
||||
, mActor(nullptr)
|
||||
@ -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) {
|
||||
for (uint32_t k = 0; k < bytesPerPixel; ++k) {
|
||||
*dst = *src;
|
||||
src += 1 + skip;
|
||||
dst += 1 + aDst.skip;
|
||||
src += 1;
|
||||
dst += 1;
|
||||
}
|
||||
src += skip;
|
||||
dst += aDst.skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 ||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user