Bug 865104 - Support YCbCr images with BasicCompositor instead of doing the conversion on the main thread. r=nrc,nical

This commit is contained in:
Matt Woodrow 2013-07-03 16:35:51 -04:00
Родитель 2de21281eb
Коммит 931b937052
2 изменённых файлов: 80 добавлений и 1 удалений

Просмотреть файл

@ -6,6 +6,7 @@
#include "BasicCompositor.h"
#include "ipc/AutoOpenSurface.h"
#include "mozilla/layers/Effects.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "nsIWidget.h"
#include "gfx2DGlue.h"
#include "gfxUtils.h"
@ -48,8 +49,11 @@ protected:
mSize = IntSize(mThebesImage->Width(), mThebesImage->Height());
}
virtual void EnsureSurface() { }
virtual bool Lock() MOZ_OVERRIDE
{
EnsureSurface();
if (!mSurface) {
mSurface = mCompositor->GetDrawTarget()->CreateSourceSurfaceFromData(mThebesImage->Data(),
mSize,
@ -74,11 +78,84 @@ protected:
IntSize mSize;
};
DeserializerToPlanarYCbCrImageData(YCbCrImageDataDeserializer& aDeserializer, PlanarYCbCrImage::Data& aData)
{
aData.mYChannel = aDeserializer.GetYData();
aData.mYStride = aDeserializer.GetYStride();
aData.mYSize = aDeserializer.GetYSize();
aData.mCbChannel = aDeserializer.GetCbData();
aData.mCrChannel = aDeserializer.GetCrData();
aData.mCbCrStride = aDeserializer.GetCbCrStride();
aData.mCbCrSize = aDeserializer.GetCbCrSize();
aData.mPicSize = aDeserializer.GetYSize();
}
class YCbCrTextureHostBasic : public TextureSourceBasic
{
public:
virtual void UpdateImpl(const SurfaceDescriptor& aImage,
nsIntRegion *aRegion,
nsIntPoint*) MOZ_OVERRIDE
{
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
mSurface = nullptr;
ConvertImageToRGB(aImage);
}
virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
nsIntRegion* aRegion) MOZ_OVERRIDE
{
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
mSurface = nullptr;
}
virtual void EnsureSurface() MOZ_OVERRIDE
{
if (!mBuffer) {
return;
}
ConvertImageToRGB(*mBuffer);
}
void ConvertImageToRGB(const SurfaceDescriptor& aImage)
{
YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
PlanarYCbCrImage::Data data;
DeserializerToPlanarYCbCrImageData(deserializer, data);
gfxASurface::gfxImageFormat format = gfxASurface::ImageFormatRGB24;
gfxIntSize size;
gfxUtils::GetYCbCrToRGBDestFormatAndSize(data, format, size);
if (size.width > PlanarYCbCrImage::MAX_DIMENSION ||
size.height > PlanarYCbCrImage::MAX_DIMENSION) {
NS_ERROR("Illegal image dest width or height");
return;
}
mThebesSurface = mThebesImage =
new gfxImageSurface(size, format);
gfxUtils::ConvertYCbCrToRGB(data, format, size,
mThebesImage->Data(),
mThebesImage->Stride());
mSize = IntSize(size.width, size.height);
mFormat =
(format == gfxASurface::CONTENT_COLOR_ALPHA) ? FORMAT_B8G8R8A8 :
FORMAT_B8G8R8X8;
}
};
TemporaryRef<TextureHost>
CreateBasicTextureHost(SurfaceDescriptorType aDescriptorType,
uint32_t aTextureHostFlags,
uint32_t aTextureFlags)
{
if (aDescriptorType == SurfaceDescriptor::TYCbCrImage) {
return new YCbCrTextureHostBasic();
}
MOZ_ASSERT(aDescriptorType == SurfaceDescriptor::TShmem ||
aDescriptorType == SurfaceDescriptor::TMemoryImage,
"We can only support Shmem currently");

Просмотреть файл

@ -100,7 +100,9 @@ CompositableClient::CreateTextureClient(TextureClientType aTextureClientType)
}
break;
case TEXTURE_YCBCR:
if (parentBackend == LAYERS_OPENGL || parentBackend == LAYERS_D3D11) {
if (parentBackend == LAYERS_OPENGL ||
parentBackend == LAYERS_D3D11 ||
parentBackend == LAYERS_BASIC) {
result = new TextureClientShmemYCbCr(GetForwarder(), GetTextureInfo());
}
break;