зеркало из https://github.com/mozilla/pjs.git
Bug 584754: Use the D3D9Ex device where available. r=vlad
This commit is contained in:
Родитель
00f20cad84
Коммит
37c237bad6
|
@ -70,9 +70,17 @@ CanvasLayerD3D9::Initialize(const Data& aData)
|
|||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
|
||||
if (mD3DManager->deviceManager()->HasDynamicTextures()) {
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, D3DUSAGE_DYNAMIC,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
} else {
|
||||
// D3DPOOL_MANAGED is fine here since we require Dynamic Textures for D3D9Ex
|
||||
// devices.
|
||||
device()->CreateTexture(mBounds.width, mBounds.height, 1, 0,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -47,10 +47,17 @@ namespace layers {
|
|||
|
||||
const LPCWSTR kClassName = L"D3D9WindowClass";
|
||||
|
||||
#define USE_D3D9EX
|
||||
|
||||
typedef IDirect3D9* (WINAPI*Direct3DCreate9Func)(
|
||||
UINT SDKVersion
|
||||
);
|
||||
|
||||
typedef HRESULT (WINAPI*Direct3DCreate9ExFunc)(
|
||||
UINT SDKVersion,
|
||||
IDirect3D9Ex **ppD3D
|
||||
);
|
||||
|
||||
struct vertex {
|
||||
float x, y;
|
||||
};
|
||||
|
@ -171,6 +178,7 @@ SwapChainD3D9::Reset()
|
|||
#define LACKS_CAP(a, b) !(((a) & (b)) == (b))
|
||||
|
||||
DeviceManagerD3D9::DeviceManagerD3D9()
|
||||
: mHasDynamicTextures(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -178,6 +186,8 @@ bool
|
|||
DeviceManagerD3D9::Init()
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
HRESULT hr;
|
||||
|
||||
if (!GetClassInfoW(GetModuleHandle(NULL), kClassName, &wc)) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASSW));
|
||||
wc.hInstance = GetModuleHandle(NULL);
|
||||
|
@ -198,14 +208,32 @@ DeviceManagerD3D9::Init()
|
|||
return false;
|
||||
}
|
||||
|
||||
Direct3DCreate9Func d3d9create = (Direct3DCreate9Func)
|
||||
GetProcAddress(LoadLibraryW(L"d3d9.dll"), "Direct3DCreate9");
|
||||
HMODULE d3d9 = LoadLibraryW(L"d3d9.dll");
|
||||
Direct3DCreate9Func d3d9Create = (Direct3DCreate9Func)
|
||||
GetProcAddress(d3d9, "Direct3DCreate9");
|
||||
Direct3DCreate9ExFunc d3d9CreateEx = (Direct3DCreate9ExFunc)
|
||||
GetProcAddress(d3d9, "Direct3DCreate9Ex");
|
||||
|
||||
if (!d3d9create) {
|
||||
#ifdef USE_D3D9EX
|
||||
if (d3d9CreateEx) {
|
||||
hr = d3d9CreateEx(D3D_SDK_VERSION, getter_AddRefs(mD3D9Ex));
|
||||
if (SUCCEEDED(hr)) {
|
||||
mD3D9 = mD3D9Ex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mD3D9) {
|
||||
if (!d3d9Create) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mD3D9 = dont_AddRef(d3d9create(D3D_SDK_VERSION));
|
||||
mD3D9 = dont_AddRef(d3d9Create(D3D_SDK_VERSION));
|
||||
|
||||
if (!mD3D9) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
@ -218,7 +246,35 @@ DeviceManagerD3D9::Init()
|
|||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = mFocusWnd;
|
||||
|
||||
HRESULT hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
|
||||
if (mD3D9Ex) {
|
||||
hr = mD3D9Ex->CreateDeviceEx(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
mFocusWnd,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
D3DCREATE_MULTITHREADED |
|
||||
D3DCREATE_MIXED_VERTEXPROCESSING,
|
||||
&pp,
|
||||
NULL,
|
||||
getter_AddRefs(mDeviceEx));
|
||||
if (SUCCEEDED(hr)) {
|
||||
mDevice = mDeviceEx;
|
||||
}
|
||||
|
||||
D3DCAPS9 caps;
|
||||
if (mDeviceEx->GetDeviceCaps(&caps)) {
|
||||
if (LACKS_CAP(caps.Caps2, D3DCAPS2_DYNAMICTEXTURES)) {
|
||||
// XXX - Should we actually hit this we'll need a CanvasLayer that
|
||||
// supports static D3DPOOL_DEFAULT textures.
|
||||
NS_WARNING("D3D9Ex device not used because of lack of support for \
|
||||
dynamic textures. This is unexpected.");
|
||||
mDevice = nsnull;
|
||||
mDeviceEx = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDevice) {
|
||||
hr = mD3D9->CreateDevice(D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
mFocusWnd,
|
||||
D3DCREATE_FPU_PRESERVE |
|
||||
|
@ -231,6 +287,7 @@ DeviceManagerD3D9::Init()
|
|||
NS_WARNING("Failed to create Device for DeviceManagerD3D9.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!VerifyCaps()) {
|
||||
return false;
|
||||
|
@ -265,9 +322,9 @@ DeviceManagerD3D9::Init()
|
|||
}
|
||||
|
||||
hr = mDevice->CreateVertexBuffer(sizeof(vertex) * 4,
|
||||
D3DUSAGE_WRITEONLY,
|
||||
0,
|
||||
0,
|
||||
D3DPOOL_MANAGED,
|
||||
D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mVB),
|
||||
NULL);
|
||||
|
||||
|
@ -385,6 +442,27 @@ DeviceManagerD3D9::VerifyReadyForRendering()
|
|||
HRESULT hr = mDevice->TestCooperativeLevel();
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (IsD3D9Ex()) {
|
||||
hr = mDeviceEx->CheckDeviceState(mFocusWnd);
|
||||
if (FAILED(hr)) {
|
||||
D3DPRESENT_PARAMETERS pp;
|
||||
memset(&pp, 0, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
pp.BackBufferWidth = 1;
|
||||
pp.BackBufferHeight = 1;
|
||||
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
pp.Windowed = TRUE;
|
||||
pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
pp.hDeviceWindow = mFocusWnd;
|
||||
|
||||
hr = mDeviceEx->ResetEx(&pp, NULL);
|
||||
// Handle D3DERR_DEVICEREMOVED!
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -473,6 +551,10 @@ DeviceManagerD3D9::VerifyCaps()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (HAS_CAP(caps.Caps2, D3DCAPS2_DYNAMICTEXTURES)) {
|
||||
mHasDynamicTextures = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ public:
|
|||
|
||||
IDirect3DDevice9 *device() { return mDevice; }
|
||||
|
||||
bool IsD3D9Ex() { return mDeviceEx; }
|
||||
|
||||
bool HasDynamicTextures() { return mHasDynamicTextures; }
|
||||
|
||||
enum ShaderMode {
|
||||
RGBLAYER,
|
||||
YCBCRLAYER,
|
||||
|
@ -153,9 +157,15 @@ private:
|
|||
/* The D3D device we use */
|
||||
nsRefPtr<IDirect3DDevice9> mDevice;
|
||||
|
||||
/* The D3D9Ex device - only valid on Vista+ with WDDM */
|
||||
nsRefPtr<IDirect3DDevice9Ex> mDeviceEx;
|
||||
|
||||
/* An instance of the D3D9 object */
|
||||
nsRefPtr<IDirect3D9> mD3D9;
|
||||
|
||||
/* An instance of the D3D9Ex object - only valid on Vista+ with WDDM */
|
||||
nsRefPtr<IDirect3D9Ex> mD3D9Ex;
|
||||
|
||||
/* Vertex shader used for layer quads */
|
||||
nsRefPtr<IDirect3DVertexShader9> mLayerVS;
|
||||
|
||||
|
@ -179,6 +189,9 @@ private:
|
|||
*/
|
||||
HWND mFocusWnd;
|
||||
|
||||
/* If this device supports dynamic textures */
|
||||
bool mHasDynamicTextures;
|
||||
|
||||
nsAutoRefCnt mRefCnt;
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
|
|
|
@ -244,6 +244,7 @@ PlanarYCbCrImageD3D9::PlanarYCbCrImageD3D9(mozilla::layers::LayerManagerD3D9* aM
|
|||
void
|
||||
PlanarYCbCrImageD3D9::SetData(const PlanarYCbCrImage::Data &aData)
|
||||
{
|
||||
// XXX - For D3D9Ex we really should just copy to systemmem surfaces here.
|
||||
// For now, we copy the data
|
||||
int width_shift = 0;
|
||||
int height_shift = 0;
|
||||
|
@ -309,76 +310,116 @@ PlanarYCbCrImageD3D9::AllocateTextures()
|
|||
{
|
||||
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
D3DLOCKED_RECT lockrectY;
|
||||
D3DLOCKED_RECT lockrectCb;
|
||||
D3DLOCKED_RECT lockrectCr;
|
||||
PRUint8* src;
|
||||
PRUint8* dest;
|
||||
//XXX: ensure correct usage flags
|
||||
|
||||
nsRefPtr<IDirect3DSurface9> tmpSurfaceY;
|
||||
nsRefPtr<IDirect3DSurface9> tmpSurfaceCb;
|
||||
nsRefPtr<IDirect3DSurface9> tmpSurfaceCr;
|
||||
|
||||
if (mManager->deviceManager()->IsD3D9Ex()) {
|
||||
// D3D9Ex does not support the managed pool, could use dynamic textures
|
||||
// here. But since an Image is immutable static textures are probably a
|
||||
// better idea.
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
mManager->device()->CreateOffscreenPlainSurface(mData.mYSize.width,
|
||||
mData.mYSize.height,
|
||||
D3DFMT_L8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(tmpSurfaceY),
|
||||
NULL);
|
||||
mManager->device()->CreateOffscreenPlainSurface(mData.mCbCrSize.width,
|
||||
mData.mCbCrSize.height,
|
||||
D3DFMT_L8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(tmpSurfaceCb),
|
||||
NULL);
|
||||
mManager->device()->CreateOffscreenPlainSurface(mData.mCbCrSize.width,
|
||||
mData.mCbCrSize.height,
|
||||
D3DFMT_L8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(tmpSurfaceCr),
|
||||
NULL);
|
||||
tmpSurfaceY->LockRect(&lockrectY, NULL, 0);
|
||||
tmpSurfaceCb->LockRect(&lockrectCb, NULL, 0);
|
||||
tmpSurfaceCr->LockRect(&lockrectCr, NULL, 0);
|
||||
} else {
|
||||
mManager->device()->CreateTexture(mData.mYSize.width, mData.mYSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mYTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mYTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mYChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mYSize.height; h++) {
|
||||
memcpy(dest, src, mData.mYSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mYStride;
|
||||
}
|
||||
|
||||
mYTexture->UnlockRect(0);
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCbTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCbTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
src = mData.mCbChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCbTexture->UnlockRect(0);
|
||||
|
||||
|
||||
//XXX: ensure correct usage flags
|
||||
mManager->device()->CreateTexture(mData.mCbCrSize.width, mData.mCbCrSize.height,
|
||||
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mCrTexture), NULL);
|
||||
|
||||
|
||||
/* lock the entire texture */
|
||||
mCrTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
mYTexture->LockRect(0, &lockrectY, NULL, 0);
|
||||
mCbTexture->LockRect(0, &lockrectCb, NULL, 0);
|
||||
mCrTexture->LockRect(0, &lockrectCr, NULL, 0);
|
||||
}
|
||||
|
||||
src = mData.mCrChannel;
|
||||
src = mData.mYChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrect.pBits;
|
||||
dest = (PRUint8*)lockrectY.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mYSize.height; h++) {
|
||||
memcpy(dest, src, mData.mYSize.width);
|
||||
dest += lockrectY.Pitch;
|
||||
src += mData.mYStride;
|
||||
}
|
||||
|
||||
src = mData.mCbChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrectCb.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrect.Pitch;
|
||||
dest += lockrectCb.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
mCrTexture->UnlockRect(0);
|
||||
src = mData.mCrChannel;
|
||||
//FIX cast
|
||||
dest = (PRUint8*)lockrectCr.pBits;
|
||||
|
||||
// copy over data
|
||||
for (int h=0; h<mData.mCbCrSize.height; h++) {
|
||||
memcpy(dest, src, mData.mCbCrSize.width);
|
||||
dest += lockrectCr.Pitch;
|
||||
src += mData.mCbCrStride;
|
||||
}
|
||||
|
||||
if (mManager->deviceManager()->IsD3D9Ex()) {
|
||||
tmpSurfaceY->UnlockRect();
|
||||
tmpSurfaceCb->UnlockRect();
|
||||
tmpSurfaceCr->UnlockRect();
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
mYTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(tmpSurfaceY, NULL, dstSurface, NULL);
|
||||
mCbTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(tmpSurfaceCb, NULL, dstSurface, NULL);
|
||||
mCrTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(tmpSurfaceCr, NULL, dstSurface, NULL);
|
||||
} else {
|
||||
mYTexture->UnlockRect(0);
|
||||
mCbTexture->UnlockRect(0);
|
||||
mCrTexture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -426,31 +467,49 @@ CairoImageD3D9::SetData(const CairoImage::Data &aData)
|
|||
context->SetSource(aData.mSurface);
|
||||
context->Paint();
|
||||
|
||||
//XXX: make sure we're using the correct usage flags
|
||||
if (mManager->deviceManager()->IsD3D9Ex()) {
|
||||
// D3D9Ex doesn't support managed textures. We could use dynamic textures
|
||||
// here but since Images are immutable that probably isn't such a great
|
||||
// idea.
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
nsRefPtr<IDirect3DSurface9> surface;
|
||||
mManager->device()->CreateOffscreenPlainSurface(aData.mSize.width,
|
||||
aData.mSize.height,
|
||||
D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
getter_AddRefs(surface),
|
||||
NULL);
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
surface->LockRect(&lockedRect, NULL, 0);
|
||||
for (int y = 0; y < aData.mSize.height; y++) {
|
||||
memcpy((char*)lockedRect.pBits + lockedRect.Pitch * y,
|
||||
imageSurface->Data() + imageSurface->Stride() * y,
|
||||
aData.mSize.width * 4);
|
||||
}
|
||||
surface->UnlockRect();
|
||||
nsRefPtr<IDirect3DSurface9> dstSurface;
|
||||
mTexture->GetSurfaceLevel(0, getter_AddRefs(dstSurface));
|
||||
mManager->device()->UpdateSurface(surface, NULL, dstSurface, NULL);
|
||||
} else {
|
||||
mManager->device()->CreateTexture(aData.mSize.width, aData.mSize.height,
|
||||
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
|
||||
getter_AddRefs(mTexture), NULL);
|
||||
|
||||
D3DLOCKED_RECT lockrect;
|
||||
/* lock the entire texture */
|
||||
mTexture->LockRect(0, &lockrect, NULL, 0);
|
||||
|
||||
PRUint8* src = imageSurface->Data();
|
||||
//FIX cast
|
||||
PRUint8* dest = (PRUint8*)lockrect.pBits;
|
||||
|
||||
// copy over data. If we don't need to do any swaping we can
|
||||
// use memcpy
|
||||
for (int i=0; i<aData.mSize.width*aData.mSize.height; i++) {
|
||||
dest[0] = src[0];
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[3] = src[3];
|
||||
dest += 4;
|
||||
src += 4;
|
||||
for (int y = 0; y < aData.mSize.height; y++) {
|
||||
memcpy((char*)lockrect.pBits + lockrect.Pitch * y,
|
||||
imageSurface->Data() + imageSurface->Stride() * y,
|
||||
aData.mSize.width * 4);
|
||||
}
|
||||
|
||||
mTexture->UnlockRect(0);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
|
|
Загрузка…
Ссылка в новой задаче