Bug 767480 - PlanarYCbCrImage refactoring. r=roc

This commit is contained in:
Kan-Ru Chen (陳侃如) 2012-08-21 17:31:36 +08:00
parent 693f238524
commit 31f25ec5f6
6 changed files with 112 additions and 108 deletions

View File

@ -202,19 +202,22 @@ VideoData* VideoData::Create(nsVideoInfo& aInfo,
data.mYChannel = Y.mData;
data.mYSize = gfxIntSize(Y.mWidth, Y.mHeight);
data.mYStride = Y.mStride;
data.mYOffset = Y.mOffset;
data.mYSkip = Y.mSkip;
data.mCbChannel = Cb.mData;
data.mCrChannel = Cr.mData;
data.mCbCrSize = gfxIntSize(Cb.mWidth, Cb.mHeight);
data.mCbCrStride = Cb.mStride;
data.mCbOffset = Cb.mOffset;
data.mCbSkip = Cb.mSkip;
data.mCrOffset = Cr.mOffset;
data.mCrSkip = Cr.mSkip;
data.mPicX = aPicture.x;
data.mPicY = aPicture.y;
data.mPicSize = gfxIntSize(aPicture.width, aPicture.height);
data.mStereoMode = aInfo.mStereoMode;
videoImage->CopyData(data,
Y.mOffset, Y.mSkip,
Cb.mOffset, Cb.mSkip,
Cr.mOffset, Cr.mSkip);
videoImage->CopyData(data);
return v.forget();
}

View File

@ -423,10 +423,7 @@ CopyPlane(PRUint8 *aDst, PRUint8 *aSrc,
}
void
PlanarYCbCrImage::CopyData(const Data& aData,
PRInt32 aYOffset, PRInt32 aYSkip,
PRInt32 aCbOffset, PRInt32 aCbSkip,
PRInt32 aCrOffset, PRInt32 aCrSkip)
PlanarYCbCrImage::CopyData(const Data& aData)
{
mData = aData;
@ -445,13 +442,13 @@ PlanarYCbCrImage::CopyData(const Data& aData,
CopyPlane(mData.mYChannel, aData.mYChannel,
mData.mYSize, mData.mYStride,
aYOffset, aYSkip);
mData.mYOffset, mData.mYSkip);
CopyPlane(mData.mCbChannel, aData.mCbChannel,
mData.mCbCrSize, mData.mCbCrStride,
aCbOffset, aCbSkip);
mData.mCbOffset, mData.mCbSkip);
CopyPlane(mData.mCrChannel, aData.mCrChannel,
mData.mCbCrSize, mData.mCbCrStride,
aCrOffset, aCrSkip);
mData.mCrOffset, mData.mCrSkip);
mSize = aData.mPicSize;
}

View File

@ -603,6 +603,11 @@ private:
* The Image that is rendered is the picture region defined by
* mPicX, mPicY and mPicSize. The size of the rendered image is
* mPicSize, not mYSize or mCbCrSize.
*
* mYOffset, mYSkip, mCbOffset, mCbSkip, mCrOffset, mCrSkip are added
* to support various output formats from hardware decoder. m*Offset
* are the extra left stride and m*Skip are per-pixel skips in the
* source image.
*/
class THEBES_API PlanarYCbCrImage : public Image {
public:
@ -611,11 +616,17 @@ public:
PRUint8* mYChannel;
PRInt32 mYStride;
gfxIntSize mYSize;
PRInt32 mYOffset;
PRInt32 mYSkip;
// Chroma buffers
PRUint8* mCbChannel;
PRUint8* mCrChannel;
PRInt32 mCbCrStride;
gfxIntSize mCbCrSize;
PRInt32 mCbOffset;
PRInt32 mCbSkip;
PRInt32 mCrOffset;
PRInt32 mCrSkip;
// Picture region
PRUint32 mPicX;
PRUint32 mPicY;
@ -653,21 +664,24 @@ public:
*/
virtual const Data* GetData() { return &mData; }
/**
* Return the number of bytes of heap memory used to store this image.
*/
virtual PRUint32 GetDataSize() { return mBufferSize; }
virtual bool IsValid() { return !!mBufferSize; }
virtual gfxIntSize GetSize() { return mSize; }
PlanarYCbCrImage(BufferRecycleBin *aRecycleBin);
protected:
/**
* Make a copy of the YCbCr data into local storage.
*
* @param aData Input image data.
* @param aYOffset Pixels to skip between lines in the Y plane.
* @param aYSkip Pixels to skip between pixels in the Y plane.
* @param aCbOffset Pixels to skip between lines in the Cb plane.
* @param aCbSkip Pixels to skip between pixels in the Cb plane.
* @param aCrOffset Pixels to skip between lines in the Cr plane.
* @param aCrSkip Pixels to skip between pixels in the Cr plane.
*/
void CopyData(const Data& aData,
PRInt32 aYOffset = 0, PRInt32 aYSkip = 0,
PRInt32 aCbOffset = 0, PRInt32 aCbSkip = 0,
PRInt32 aCrOffset = 0, PRInt32 aCrSkip = 0);
void CopyData(const Data& aData);
/**
* Return a buffer to store image data in.
@ -676,19 +690,11 @@ public:
*/
virtual PRUint8* AllocateBuffer(PRUint32 aSize);
/**
* Return the number of bytes of heap memory used to store this image.
*/
virtual PRUint32 GetDataSize() { return mBufferSize; }
already_AddRefed<gfxASurface> GetAsSurface();
virtual gfxIntSize GetSize() { return mSize; }
void SetOffscreenFormat(gfxASurface::gfxImageFormat aFormat) { mOffscreenFormat = aFormat; }
gfxASurface::gfxImageFormat GetOffscreenFormat() { return mOffscreenFormat; }
// XXX - not easy to protect these sadly.
nsAutoArrayPtr<PRUint8> mBuffer;
PRUint32 mBufferSize;
Data mData;
@ -696,8 +702,6 @@ public:
gfxASurface::gfxImageFormat mOffscreenFormat;
nsCountedRef<nsMainThreadSurfaceRef> mSurface;
nsRefPtr<BufferRecycleBin> mRecycleBin;
PlanarYCbCrImage(BufferRecycleBin *aRecycleBin);
};
/**
@ -827,4 +831,4 @@ public:
} //namespace
} //namespace
#endif
#endif

View File

@ -224,7 +224,7 @@ ImageLayerD3D10::RenderLayer()
PlanarYCbCrImage *yuvImage =
static_cast<PlanarYCbCrImage*>(image);
if (!yuvImage->mBufferSize) {
if (!yuvImage->IsValid()) {
return;
}
@ -261,7 +261,7 @@ ImageLayerD3D10::RenderLayer()
*/
if (GetNv3DVUtils()) {
Nv_Stereo_Mode mode;
switch (yuvImage->mData.mStereoMode) {
switch (yuvImage->GetData()->mStereoMode) {
case STEREO_MODE_LEFT_RIGHT:
mode = NV_STEREO_MODE_LEFT_RIGHT;
break;
@ -282,10 +282,10 @@ ImageLayerD3D10::RenderLayer()
// Send control data even in mono case so driver knows to leave stereo mode.
GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
if (yuvImage->mData.mStereoMode != STEREO_MODE_MONO) {
if (yuvImage->GetData()->mStereoMode != STEREO_MODE_MONO) {
// Dst resource is optional
GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->mData.mYSize.width,
(unsigned int)yuvImage->mData.mYSize.height, (HANDLE)(data->mYTexture), (HANDLE)(NULL));
GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->GetData()->mYSize.width,
(unsigned int)yuvImage->GetData()->mYSize.height, (HANDLE)(data->mYTexture), (HANDLE)(NULL));
}
}
@ -299,10 +299,10 @@ ImageLayerD3D10::RenderLayer()
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
ShaderConstantRectD3D10(
(float)yuvImage->mData.mPicX / yuvImage->mData.mYSize.width,
(float)yuvImage->mData.mPicY / yuvImage->mData.mYSize.height,
(float)yuvImage->mData.mPicSize.width / yuvImage->mData.mYSize.width,
(float)yuvImage->mData.mPicSize.height / yuvImage->mData.mYSize.height)
(float)yuvImage->GetData()->mPicX / yuvImage->GetData()->mYSize.width,
(float)yuvImage->GetData()->mPicY / yuvImage->GetData()->mYSize.height,
(float)yuvImage->GetData()->mPicSize.width / yuvImage->GetData()->mYSize.width,
(float)yuvImage->GetData()->mPicSize.height / yuvImage->GetData()->mYSize.height)
);
}
@ -330,26 +330,26 @@ void ImageLayerD3D10::AllocateTexturesYCbCr(PlanarYCbCrImage *aImage)
nsAutoPtr<PlanarYCbCrD3D10BackendData> backendData(
new PlanarYCbCrD3D10BackendData);
PlanarYCbCrImage::Data &data = aImage->mData;
const PlanarYCbCrImage::Data *data = aImage->GetData();
D3D10_SUBRESOURCE_DATA dataY;
D3D10_SUBRESOURCE_DATA dataCb;
D3D10_SUBRESOURCE_DATA dataCr;
CD3D10_TEXTURE2D_DESC descY(DXGI_FORMAT_R8_UNORM,
data.mYSize.width,
data.mYSize.height, 1, 1);
data->mYSize.width,
data->mYSize.height, 1, 1);
CD3D10_TEXTURE2D_DESC descCbCr(DXGI_FORMAT_R8_UNORM,
data.mCbCrSize.width,
data.mCbCrSize.height, 1, 1);
data->mCbCrSize.width,
data->mCbCrSize.height, 1, 1);
descY.Usage = descCbCr.Usage = D3D10_USAGE_IMMUTABLE;
dataY.pSysMem = data.mYChannel;
dataY.SysMemPitch = data.mYStride;
dataCb.pSysMem = data.mCbChannel;
dataCb.SysMemPitch = data.mCbCrStride;
dataCr.pSysMem = data.mCrChannel;
dataCr.SysMemPitch = data.mCbCrStride;
dataY.pSysMem = data->mYChannel;
dataY.SysMemPitch = data->mYStride;
dataCb.pSysMem = data->mCbChannel;
dataCb.SysMemPitch = data->mCbCrStride;
dataCr.pSysMem = data->mCrChannel;
dataCr.SysMemPitch = data->mCbCrStride;
HRESULT hr = device()->CreateTexture2D(&descY, &dataY, getter_AddRefs(backendData->mYTexture));
if (!FAILED(hr)) {

View File

@ -133,7 +133,7 @@ static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage,
nsAutoPtr<PlanarYCbCrD3D9BackendData> backendData(
new PlanarYCbCrD3D9BackendData);
PlanarYCbCrImage::Data &data = aImage->mData;
const PlanarYCbCrImage::Data *data = aImage->GetData();
D3DLOCKED_RECT lockrectY;
D3DLOCKED_RECT lockrectCb;
@ -160,31 +160,31 @@ static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage,
// better idea.
HRESULT hr;
hr = aDevice->CreateTexture(data.mYSize.width, data.mYSize.height,
hr = aDevice->CreateTexture(data->mYSize.width, data->mYSize.height,
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
getter_AddRefs(backendData->mYTexture), NULL);
if (!FAILED(hr)) {
hr = aDevice->CreateTexture(data.mCbCrSize.width, data.mCbCrSize.height,
hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height,
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
getter_AddRefs(backendData->mCbTexture), NULL);
}
if (!FAILED(hr)) {
hr = aDevice->CreateTexture(data.mCbCrSize.width, data.mCbCrSize.height,
hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height,
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
getter_AddRefs(backendData->mCrTexture), NULL);
}
if (!FAILED(hr)) {
hr = aDevice->CreateTexture(data.mYSize.width, data.mYSize.height,
hr = aDevice->CreateTexture(data->mYSize.width, data->mYSize.height,
1, 0, D3DFMT_L8, D3DPOOL_SYSTEMMEM,
getter_AddRefs(tmpYTexture), NULL);
}
if (!FAILED(hr)) {
hr = aDevice->CreateTexture(data.mCbCrSize.width, data.mCbCrSize.height,
hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height,
1, 0, D3DFMT_L8, D3DPOOL_SYSTEMMEM,
getter_AddRefs(tmpCbTexture), NULL);
}
if (!FAILED(hr)) {
hr = aDevice->CreateTexture(data.mCbCrSize.width, data.mCbCrSize.height,
hr = aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height,
1, 0, D3DFMT_L8, D3DPOOL_SYSTEMMEM,
getter_AddRefs(tmpCrTexture), NULL);
}
@ -203,16 +203,16 @@ static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage,
tmpSurfaceCr->LockRect(&lockrectCr, NULL, 0);
} else {
HRESULT hr;
hr = aDevice->CreateTexture(data.mYSize.width, data.mYSize.height,
hr = aDevice->CreateTexture(data->mYSize.width, data->mYSize.height,
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
getter_AddRefs(backendData->mYTexture), NULL);
if (!FAILED(hr)) {
aDevice->CreateTexture(data.mCbCrSize.width, data.mCbCrSize.height,
aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height,
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
getter_AddRefs(backendData->mCbTexture), NULL);
}
if (!FAILED(hr)) {
aDevice->CreateTexture(data.mCbCrSize.width, data.mCbCrSize.height,
aDevice->CreateTexture(data->mCbCrSize.width, data->mCbCrSize.height,
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
getter_AddRefs(backendData->mCrTexture), NULL);
}
@ -229,37 +229,37 @@ static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage,
backendData->mCrTexture->LockRect(0, &lockrectCr, NULL, 0);
}
src = data.mYChannel;
src = data->mYChannel;
//FIX cast
dest = (PRUint8*)lockrectY.pBits;
// copy over data
for (int h=0; h<data.mYSize.height; h++) {
memcpy(dest, src, data.mYSize.width);
for (int h=0; h<data->mYSize.height; h++) {
memcpy(dest, src, data->mYSize.width);
dest += lockrectY.Pitch;
src += data.mYStride;
src += data->mYStride;
}
src = data.mCbChannel;
src = data->mCbChannel;
//FIX cast
dest = (PRUint8*)lockrectCb.pBits;
// copy over data
for (int h=0; h<data.mCbCrSize.height; h++) {
memcpy(dest, src, data.mCbCrSize.width);
for (int h=0; h<data->mCbCrSize.height; h++) {
memcpy(dest, src, data->mCbCrSize.width);
dest += lockrectCb.Pitch;
src += data.mCbCrStride;
src += data->mCbCrStride;
}
src = data.mCrChannel;
src = data->mCrChannel;
//FIX cast
dest = (PRUint8*)lockrectCr.pBits;
// copy over data
for (int h=0; h<data.mCbCrSize.height; h++) {
memcpy(dest, src, data.mCbCrSize.width);
for (int h=0; h<data->mCbCrSize.height; h++) {
memcpy(dest, src, data->mCbCrSize.width);
dest += lockrectCr.Pitch;
src += data.mCbCrStride;
src += data->mCbCrStride;
}
if (isD3D9Ex) {
@ -300,7 +300,7 @@ ImageLayerD3D9::GetTexture(Image *aImage, bool& aHasAlpha)
{
NS_ASSERTION(aImage, "Null image.");
if (aImage->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP) {
if (aImage->GetFormat() == REMOTE_IMAGE_BITMAP) {
RemoteBitmapImage *remoteImage =
static_cast<RemoteBitmapImage*>(aImage);
@ -313,7 +313,7 @@ ImageLayerD3D9::GetTexture(Image *aImage, bool& aHasAlpha)
}
aHasAlpha = remoteImage->mFormat == RemoteImageData::BGRA32;
} else if (aImage->GetFormat() == ImageFormat::CAIRO_SURFACE) {
} else if (aImage->GetFormat() == CAIRO_SURFACE) {
CairoImage *cairoImage =
static_cast<CairoImage*>(aImage);
@ -370,10 +370,10 @@ ImageLayerD3D9::RenderLayer()
gfxIntSize size = mScaleMode == SCALE_NONE ? image->GetSize() : mScaleToSize;
if (image->GetFormat() == ImageFormat::CAIRO_SURFACE ||
image->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP)
if (image->GetFormat() == CAIRO_SURFACE ||
image->GetFormat() == REMOTE_IMAGE_BITMAP)
{
NS_ASSERTION(image->GetFormat() != ImageFormat::CAIRO_SURFACE ||
NS_ASSERTION(image->GetFormat() != CAIRO_SURFACE ||
!static_cast<CairoImage*>(image)->mSurface ||
static_cast<CairoImage*>(image)->mSurface->GetContentType() != gfxASurface::CONTENT_ALPHA,
"Image layer has alpha image");
@ -412,7 +412,7 @@ ImageLayerD3D9::RenderLayer()
PlanarYCbCrImage *yuvImage =
static_cast<PlanarYCbCrImage*>(image);
if (!yuvImage->mBufferSize) {
if (!yuvImage->IsValid()) {
return;
}
@ -442,10 +442,10 @@ ImageLayerD3D9::RenderLayer()
device()->SetVertexShaderConstantF(CBvTextureCoords,
ShaderConstantRect(
(float)yuvImage->mData.mPicX / yuvImage->mData.mYSize.width,
(float)yuvImage->mData.mPicY / yuvImage->mData.mYSize.height,
(float)yuvImage->mData.mPicSize.width / yuvImage->mData.mYSize.width,
(float)yuvImage->mData.mPicSize.height / yuvImage->mData.mYSize.height
(float)yuvImage->GetData()->mPicX / yuvImage->GetData()->mYSize.width,
(float)yuvImage->GetData()->mPicY / yuvImage->GetData()->mYSize.height,
(float)yuvImage->GetData()->mPicSize.width / yuvImage->GetData()->mYSize.width,
(float)yuvImage->GetData()->mPicSize.height / yuvImage->GetData()->mYSize.height
),
1);
@ -456,7 +456,7 @@ ImageLayerD3D9::RenderLayer()
*/
if (mD3DManager->GetNv3DVUtils()) {
Nv_Stereo_Mode mode;
switch (yuvImage->mData.mStereoMode) {
switch (yuvImage->GetData()->mStereoMode) {
case STEREO_MODE_LEFT_RIGHT:
mode = NV_STEREO_MODE_LEFT_RIGHT;
break;
@ -477,13 +477,13 @@ ImageLayerD3D9::RenderLayer()
// Send control data even in mono case so driver knows to leave stereo mode.
mD3DManager->GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
if (yuvImage->mData.mStereoMode != STEREO_MODE_MONO) {
if (yuvImage->GetData()->mStereoMode != STEREO_MODE_MONO) {
mD3DManager->GetNv3DVUtils()->SendNv3DVControl(mode, true, FIREFOX_3DV_APP_HANDLE);
nsRefPtr<IDirect3DSurface9> renderTarget;
device()->GetRenderTarget(0, getter_AddRefs(renderTarget));
mD3DManager->GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->mSize.width,
(unsigned int)yuvImage->mSize.height, (HANDLE)(data->mYTexture), (HANDLE)(renderTarget));
mD3DManager->GetNv3DVUtils()->SendNv3DVMetaData((unsigned int)yuvImage->GetSize().width,
(unsigned int)yuvImage->GetSize().height, (HANDLE)(data->mYTexture), (HANDLE)(renderTarget));
}
}
@ -522,8 +522,8 @@ ImageLayerD3D9::GetAsTexture(gfxIntSize* aSize)
return nullptr;
}
if (image->GetFormat() != ImageFormat::CAIRO_SURFACE &&
image->GetFormat() != ImageFormat::REMOTE_IMAGE_BITMAP) {
if (image->GetFormat() != CAIRO_SURFACE &&
image->GetFormat() != REMOTE_IMAGE_BITMAP) {
return nullptr;
}
@ -616,7 +616,7 @@ ShadowImageLayerD3D9::RenderLayer()
if (mBuffer) {
mBuffer->RenderTo(mD3DManager, GetEffectiveVisibleRegion());
} else if (mYCbCrImage) {
if (!mYCbCrImage->mBufferSize) {
if (!mYCbCrImage->IsValid()) {
return;
}
@ -631,7 +631,7 @@ ShadowImageLayerD3D9::RenderLayer()
return;
}
if (!mYCbCrImage->mBufferSize) {
if (!mYCbCrImage->IsValid()) {
return;
}
@ -640,8 +640,8 @@ ShadowImageLayerD3D9::RenderLayer()
device()->SetVertexShaderConstantF(CBvLayerQuad,
ShaderConstantRect(0,
0,
mYCbCrImage->mSize.width,
mYCbCrImage->mSize.height),
mYCbCrImage->GetSize().width,
mYCbCrImage->GetSize().height),
1);
mD3DManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER, GetMaskLayer());

View File

@ -253,7 +253,7 @@ ImageLayerOGL::RenderLayer(int,
PlanarYCbCrImage *yuvImage =
static_cast<PlanarYCbCrImage*>(image);
if (!yuvImage->mBufferSize) {
if (!yuvImage->IsValid()) {
return;
}
@ -293,8 +293,8 @@ ImageLayerOGL::RenderLayer(int,
program->Activate();
program->SetLayerQuadRect(nsIntRect(0, 0,
yuvImage->mSize.width,
yuvImage->mSize.height));
yuvImage->GetSize().width,
yuvImage->GetSize().height));
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
@ -302,9 +302,9 @@ ImageLayerOGL::RenderLayer(int,
program->LoadMask(GetMaskLayer());
mOGLManager->BindAndDrawQuadWithTextureRect(program,
yuvImage->mData.GetPictureRect(),
nsIntSize(yuvImage->mData.mYSize.width,
yuvImage->mData.mYSize.height));
yuvImage->GetData()->GetPictureRect(),
nsIntSize(yuvImage->GetData()->mYSize.width,
yuvImage->GetData()->mYSize.height));
// We shouldn't need to do this, but do it anyway just in case
// someone else forgets.
@ -532,32 +532,32 @@ ImageLayerOGL::ImageLayerOGL(LayerManagerOGL *aManager)
void
ImageLayerOGL::AllocateTexturesYCbCr(PlanarYCbCrImage *aImage)
{
if (!aImage->mBufferSize)
if (!aImage->IsValid())
return;
nsAutoPtr<PlanarYCbCrOGLBackendData> backendData(
new PlanarYCbCrOGLBackendData);
PlanarYCbCrImage::Data &data = aImage->mData;
const PlanarYCbCrImage::Data *data = aImage->GetData();
gl()->MakeCurrent();
mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_Y, data.mYSize, gl(), &backendData->mTextures[0]);
mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_Y, data->mYSize, gl(), &backendData->mTextures[0]);
SetClamping(gl(), backendData->mTextures[0].GetTextureID());
mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl(), &backendData->mTextures[1]);
mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data->mCbCrSize, gl(), &backendData->mTextures[1]);
SetClamping(gl(), backendData->mTextures[1].GetTextureID());
mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl(), &backendData->mTextures[2]);
mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data->mCbCrSize, gl(), &backendData->mTextures[2]);
SetClamping(gl(), backendData->mTextures[2].GetTextureID());
UploadYUVToTexture(gl(), aImage->mData,
UploadYUVToTexture(gl(), *data,
&backendData->mTextures[0],
&backendData->mTextures[1],
&backendData->mTextures[2]);
backendData->mYSize = aImage->mData.mYSize;
backendData->mCbCrSize = aImage->mData.mCbCrSize;
backendData->mYSize = data->mYSize;
backendData->mCbCrSize = data->mCbCrSize;
backendData->mTextureRecycleBin = mTextureRecycleBin;
aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());