Aric Stewart : quartz: Implement a Default Presenter in VMR9.

Alexandre Julliard julliard at winehq.org
Tue May 22 14:21:28 CDT 2012


Module: wine
Branch: master
Commit: 38c31973d47c0711c1d32a71ab77fb1e906ac776
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=38c31973d47c0711c1d32a71ab77fb1e906ac776

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon May 21 07:53:44 2012 -0500

quartz: Implement a Default Presenter in VMR9.

---

 dlls/quartz/vmr9.c |  254 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 252 insertions(+), 2 deletions(-)

diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 809ee0f..fc04269 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -123,6 +123,28 @@ static inline VMR9Impl *impl_from_IVMRSurfaceAllocatorNotify9( IVMRSurfaceAlloca
     return CONTAINING_RECORD(iface, VMR9Impl, IVMRSurfaceAllocatorNotify9_iface);
 }
 
+typedef struct
+{
+    IVMRImagePresenter9 IVMRImagePresenter9_iface;
+
+    LONG refCount;
+
+    IDirect3DDevice9 *d3d9_dev;
+    IDirect3D9 *d3d9_ptr;
+    IDirect3DVertexBuffer9 *d3d9_vertex;
+
+    VMR9AllocationInfo info;
+
+    VMR9Impl* pVMR9;
+} VMR9DefaultAllocatorPresenterImpl;
+
+static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
+{
+    return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
+}
+
+static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv);
+
 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
 {
     VMR9Impl *This = (VMR9Impl *)iface;
@@ -886,10 +908,21 @@ static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface
     {
     case VMR9Mode_Windowed:
     case VMR9Mode_Windowless:
-        This->allocator = NULL;
-        This->presenter = NULL;
         This->allocator_is_ex = 0;
         This->cookie = ~0;
+
+        hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
+        if (SUCCEEDED(hr))
+            hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
+        if (FAILED(hr))
+        {
+            ERR("Unable to find Presenter interface\n");
+            IVMRSurfaceAllocatorEx9_Release(This->presenter);
+            This->allocator = NULL;
+            This->presenter = NULL;
+        }
+        else
+            hr = IVMRSurfaceAllocator9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
         break;
     case VMR9Mode_Renderless:
         break;
@@ -1262,3 +1295,220 @@ fail:
     CoTaskMemFree(pVMR9);
     return hr;
 }
+
+
+
+static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
+{
+    VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+    TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
+    else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
+        *ppv = &This->IVMRImagePresenter9_iface;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s\n", debugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
+{
+    VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+    ULONG refCount = InterlockedIncrement(&This->refCount);
+
+    TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
+{
+    VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+    ULONG refCount = InterlockedDecrement(&This->refCount);
+
+    TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
+
+    if (!refCount)
+    {
+        TRACE("Destroying\n");
+        IUnknown_Release(This->d3d9_ptr);
+
+        if (This->d3d9_vertex)
+        {
+            IUnknown_Release(This->d3d9_vertex);
+            This->d3d9_vertex = NULL;
+        }
+        CoTaskMemFree(This);
+        return 0;
+    }
+    return refCount;
+}
+
+static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
+{
+    VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+
+    TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
+    return S_OK;
+}
+
+static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
+{
+    VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+
+    TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
+    return S_OK;
+}
+
+#define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
+struct VERTEX { float x, y, z, rhw, u, v; };
+
+static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
+{
+    IDirect3DTexture9 *texture = NULL;
+    HRESULT hr;
+
+    hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
+    if (FAILED(hr))
+    {
+        FIXME("SetFVF: %08x\n", hr);
+        return hr;
+    }
+
+    hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
+    if (FAILED(hr))
+    {
+        FIXME("SetStreamSource: %08x\n", hr);
+        return hr;
+    }
+
+    hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
+    if (FAILED(hr))
+    {
+        FIXME("IDirect3DSurface9_GetContainer failed\n");
+        return hr;
+    }
+    hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
+    IDirect3DTexture9_Release(texture);
+    if (FAILED(hr))
+    {
+        FIXME("SetTexture: %08x\n", hr);
+        return hr;
+    }
+
+    hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
+    if (FAILED(hr))
+    {
+        FIXME("DrawPrimitive: %08x\n", hr);
+        return hr;
+    }
+
+    return S_OK;
+}
+
+static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
+{
+    VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+    HRESULT hr;
+    RECT output;
+    BOOL render = FALSE;
+
+    TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
+    GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
+    TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom);
+
+    /* This might happen if we don't have active focus (eg on a different virtual desktop) */
+    if (!This->d3d9_dev)
+        return S_OK;
+
+    /* Display image here */
+    hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
+    if (FAILED(hr))
+        FIXME("hr: %08x\n", hr);
+    hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
+    if (SUCCEEDED(hr))
+    {
+        if (This->d3d9_vertex)
+            hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
+        else
+            hr = E_NOTIMPL;
+        render = SUCCEEDED(hr);
+    }
+    else
+        FIXME("BeginScene: %08x\n", hr);
+    hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
+    if (render && SUCCEEDED(hr))
+    {
+        hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
+        if (FAILED(hr))
+            FIXME("Presenting image: %08x\n", hr);
+    }
+
+    return S_OK;
+}
+
+static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
+{
+    VMR9_ImagePresenter_QueryInterface,
+    VMR9_ImagePresenter_AddRef,
+    VMR9_ImagePresenter_Release,
+    VMR9_ImagePresenter_StartPresenting,
+    VMR9_ImagePresenter_StopPresenting,
+    VMR9_ImagePresenter_PresentImage
+};
+
+static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv)
+{
+    HRESULT hr = S_OK;
+    int i;
+    VMR9DefaultAllocatorPresenterImpl* This;
+
+    This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
+    if (!This)
+        return E_OUTOFMEMORY;
+
+    This->d3d9_ptr = NULL;
+    if (!This->d3d9_ptr)
+    {
+        WARN("Could not initialize d3d9.dll\n");
+        CoTaskMemFree(This);
+        return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
+    }
+
+    i = 0;
+    do
+    {
+        D3DDISPLAYMODE mode;
+
+        hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
+    } while (FAILED(hr));
+    if (FAILED(hr))
+        ERR("HR: %08x\n", hr);
+    if (hr == D3DERR_NOTAVAILABLE)
+    {
+        ERR("Format not supported\n");
+        IUnknown_Release(This->d3d9_ptr);
+        CoTaskMemFree(This);
+        return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
+    }
+
+    This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
+
+    This->refCount = 1;
+    This->pVMR9 = parent;
+    This->d3d9_dev = NULL;
+    This->d3d9_vertex = NULL;
+
+    *ppv = This;
+    return S_OK;
+}




More information about the wine-cvs mailing list