[PATCH 1/8] ddraw: device::GetCurrentViewport returns an error if no viewport is set

Stefan Dösinger stefan at codeweavers.com
Sat Jan 26 06:39:42 CST 2013


Note that I do not know of any application that needs this or any of the
following fixes. However, patch 2 and 6 fix a memory leak where the
currently active viewport was never released when the device was
destroyed.

I have written the test in patch 8 as a background check for some Wine
1.4 bugfix(I don't remember which one). The overall behavior
demonstrated by the test and implemented by the other patches is sane,
so think it's worth implementing even without any evident bugfixes.
---
 dlls/ddraw/device.c   | 14 ++++++++------
 dlls/ddraw/viewport.c | 18 ++++++++----------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 5d30994..c604c6a 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -1758,16 +1758,18 @@ static HRESULT WINAPI d3d_device3_GetCurrentViewport(IDirect3DDevice3 *iface, ID
         return DDERR_INVALIDPARAMS;
 
     wined3d_mutex_lock();
-    *viewport = &device->current_viewport->IDirect3DViewport3_iface;
+    if (!device->current_viewport)
+    {
+        wined3d_mutex_unlock();
+        WARN("No current viewport, returning D3DERR_NOCURRENTVIEWPORT\n");
+        return D3DERR_NOCURRENTVIEWPORT;
+    }
 
-    /* AddRef the returned viewport */
-    if (*viewport)
-        IDirect3DViewport3_AddRef(*viewport);
+    *viewport = &device->current_viewport->IDirect3DViewport3_iface;
+    IDirect3DViewport3_AddRef(*viewport);
 
     TRACE("Returning interface %p.\n", *viewport);
-
     wined3d_mutex_unlock();
-
     return D3D_OK;
 }
 
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index 9231c19..f9eddda 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -342,10 +342,10 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
     This->viewports.vp1.dvMinZ = 0.0;
     This->viewports.vp1.dvMaxZ = 1.0;
 
-    if (This->active_device) {
+    if (This->active_device)
+    {
         IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
-        IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
-        if (current_viewport)
+        if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport)))
         {
             if (current_viewport == iface) viewport_activate(This, FALSE);
             IDirect3DViewport3_Release(current_viewport);
@@ -705,8 +705,7 @@ static HRESULT WINAPI d3d_viewport_Clear(IDirect3DViewport3 *iface,
     hr = IDirect3DDevice7_Clear(&This->active_device->IDirect3DDevice7_iface, rect_count, rects,
             flags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET), color, 1.0, 0x00000000);
 
-    IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
-    if (current_viewport)
+    if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport)))
     {
         struct d3d_viewport *vp = impl_from_IDirect3DViewport3(current_viewport);
         viewport_activate(vp, TRUE);
@@ -979,10 +978,10 @@ static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVI
     memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
     memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
 
-    if (This->active_device) {
+    if (This->active_device)
+    {
         IDirect3DDevice3 *d3d_device3 = &This->active_device->IDirect3DDevice3_iface;
-        IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
-        if (current_viewport)
+        if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport)))
         {
             if (current_viewport == iface) viewport_activate(This, FALSE);
             IDirect3DViewport3_Release(current_viewport);
@@ -1087,8 +1086,7 @@ static HRESULT WINAPI d3d_viewport_Clear2(IDirect3DViewport3 *iface, DWORD rect_
 
     hr = IDirect3DDevice7_Clear(&viewport->active_device->IDirect3DDevice7_iface,
             rect_count, rects, flags, color, depth, stencil);
-    IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport);
-    if (current_viewport)
+    if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(d3d_device3, &current_viewport)))
     {
         struct d3d_viewport *vp = impl_from_IDirect3DViewport3(current_viewport);
         viewport_activate(vp, TRUE);
-- 
1.7.12.4




More information about the wine-patches mailing list