Bug 757346; Use A8 textures (DX9). r=roc

This commit is contained in:
Nicholas Cameron 2012-06-26 14:43:31 +12:00
parent 162bac1537
commit df04b53eb1

View File

@ -20,73 +20,83 @@
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {
static inline _D3DFORMAT
D3dFormatForGfxFormat(gfxImageFormat aFormat)
{
if (aFormat == gfxASurface::ImageFormatA8) {
return D3DFMT_A8;
}
return D3DFMT_A8R8G8B8;
}
static already_AddRefed<IDirect3DTexture9> static already_AddRefed<IDirect3DTexture9>
DataToTexture(IDirect3DDevice9 *aDevice, DataToTexture(IDirect3DDevice9 *aDevice,
unsigned char *aData, unsigned char *aData,
int aStride, int aStride,
const gfxIntSize &aSize) const gfxIntSize &aSize,
_D3DFORMAT aFormat)
{ {
nsRefPtr<IDirect3DTexture9> texture; nsRefPtr<IDirect3DTexture9> texture;
nsRefPtr<IDirect3DDevice9Ex> deviceEx; nsRefPtr<IDirect3DDevice9Ex> deviceEx;
aDevice->QueryInterface(IID_IDirect3DDevice9Ex, aDevice->QueryInterface(IID_IDirect3DDevice9Ex,
(void**)getter_AddRefs(deviceEx)); (void**)getter_AddRefs(deviceEx));
nsRefPtr<IDirect3DSurface9> surface;
D3DLOCKED_RECT lockedRect;
if (deviceEx) { if (deviceEx) {
// D3D9Ex doesn't support managed textures. We could use dynamic textures // D3D9Ex doesn't support managed textures. We could use dynamic textures
// here but since Images are immutable that probably isn't such a great // here but since Images are immutable that probably isn't such a great
// idea. // idea.
if (FAILED(aDevice-> if (FAILED(aDevice->
CreateTexture(aSize.width, aSize.height, CreateTexture(aSize.width, aSize.height,
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, 1, 0, aFormat, D3DPOOL_DEFAULT,
getter_AddRefs(texture), NULL))) getter_AddRefs(texture), NULL)))
{ {
return NULL; return NULL;
} }
nsRefPtr<IDirect3DSurface9> surface; nsRefPtr<IDirect3DTexture9> tmpTexture;
if (FAILED(aDevice-> if (FAILED(aDevice->
CreateOffscreenPlainSurface(aSize.width, CreateTexture(aSize.width, aSize.height,
aSize.height, 1, 0, aFormat, D3DPOOL_SYSTEMMEM,
D3DFMT_A8R8G8B8, getter_AddRefs(tmpTexture), NULL)))
D3DPOOL_SYSTEMMEM,
getter_AddRefs(surface),
NULL)))
{ {
return NULL; return NULL;
} }
D3DLOCKED_RECT lockedRect; tmpTexture->GetSurfaceLevel(0, getter_AddRefs(surface));
surface->LockRect(&lockedRect, NULL, 0); surface->LockRect(&lockedRect, NULL, 0);
NS_ASSERTION(lockedRect.pBits, "Could not lock surface");
} else {
if (FAILED(aDevice->
CreateTexture(aSize.width, aSize.height,
1, 0, aFormat, D3DPOOL_MANAGED,
getter_AddRefs(texture), NULL)))
{
return NULL;
}
/* lock the entire texture */
texture->LockRect(0, &lockedRect, NULL, 0);
}
PRUint32 width = aSize.width;
if (aFormat == D3DFMT_A8R8G8B8) {
width *= 4;
}
for (int y = 0; y < aSize.height; y++) { for (int y = 0; y < aSize.height; y++) {
memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y, memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y,
aData + aStride * y, aData + aStride * y,
aSize.width * 4); width);
} }
if (deviceEx) {
surface->UnlockRect(); surface->UnlockRect();
nsRefPtr<IDirect3DSurface9> dstSurface; nsRefPtr<IDirect3DSurface9> dstSurface;
texture->GetSurfaceLevel(0, getter_AddRefs(dstSurface)); texture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
aDevice->UpdateSurface(surface, NULL, dstSurface, NULL); aDevice->UpdateSurface(surface, NULL, dstSurface, NULL);
} else { } else {
if (FAILED(aDevice->
CreateTexture(aSize.width, aSize.height,
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
getter_AddRefs(texture), NULL)))
{
return NULL;
}
D3DLOCKED_RECT lockrect;
/* lock the entire texture */
texture->LockRect(0, &lockrect, NULL, 0);
// copy over data. If we don't need to do any swaping we can
// use memcpy
for (int y = 0; y < aSize.height; y++) {
memcpy((char*)lockrect.pBits + lockrect.Pitch * y,
aData + aStride * y,
aSize.width * 4);
}
texture->UnlockRect(0); texture->UnlockRect(0);
} }
@ -111,7 +121,8 @@ SurfaceToTexture(IDirect3DDevice9 *aDevice,
context->Paint(); context->Paint();
} }
return DataToTexture(aDevice, imageSurface->Data(), imageSurface->Stride(), aSize); return DataToTexture(aDevice, imageSurface->Data(), imageSurface->Stride(),
aSize, D3dFormatForGfxFormat(imageSurface->Format()));
} }
static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage, static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage,
@ -294,7 +305,7 @@ ImageLayerD3D9::GetTexture(Image *aImage, bool& aHasAlpha)
if (!aImage->GetBackendData(LayerManager::LAYERS_D3D9)) { if (!aImage->GetBackendData(LayerManager::LAYERS_D3D9)) {
nsAutoPtr<TextureD3D9BackendData> dat(new TextureD3D9BackendData()); nsAutoPtr<TextureD3D9BackendData> dat(new TextureD3D9BackendData());
dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize); dat->mTexture = DataToTexture(device(), remoteImage->mData, remoteImage->mStride, remoteImage->mSize, D3DFMT_A8R8G8B8);
if (dat->mTexture) { if (dat->mTexture) {
aImage->SetBackendData(LayerManager::LAYERS_D3D9, dat.forget()); aImage->SetBackendData(LayerManager::LAYERS_D3D9, dat.forget());
} }