Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1e2413f4
Commit
1e2413f4
authored
Jun 16, 2006
by
Stefan Dösinger
Committed by
Alexandre Julliard
Jun 19, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ddraw: Implement proper handle management.
parent
c13f097d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
248 additions
and
45 deletions
+248
-45
ddraw_private.h
dlls/ddraw/ddraw_private.h
+21
-0
device.c
dlls/ddraw/device.c
+132
-15
direct3d.c
dlls/ddraw/direct3d.c
+3
-0
material.c
dlls/ddraw/material.c
+26
-10
surface.c
dlls/ddraw/surface.c
+7
-0
texture.c
dlls/ddraw/texture.c
+13
-9
viewport.c
dlls/ddraw/viewport.c
+46
-11
No files found.
dlls/ddraw/ddraw_private.h
View file @
1e2413f4
...
...
@@ -232,6 +232,8 @@ struct IDirectDrawSurfaceImpl
/* For the ddraw surface list */
IDirectDrawSurfaceImpl
*
next
;
IDirectDrawSurfaceImpl
*
prev
;
DWORD
Handle
;
};
/* VTable declaration. It's located in surface.c / surface_thunks.c */
...
...
@@ -264,6 +266,19 @@ const IParentVtbl IParent_Vtbl;
/*****************************************************************************
* IDirect3DDevice implementation
*****************************************************************************/
typedef
enum
{
DDrawHandle_Unknown
=
0
,
DDrawHandle_Texture
=
1
,
DDrawHandle_Material
=
2
}
DDrawHandleTypes
;
struct
HandleEntry
{
void
*
ptr
;
DDrawHandleTypes
type
;
};
struct
IDirect3DDeviceImpl
{
/* IUnknown */
...
...
@@ -296,6 +311,10 @@ struct IDirect3DDeviceImpl
LPBYTE
vertex_buffer
;
DWORD
vertex_size
;
DWORD
buffer_size
;
/* Handle management */
struct
HandleEntry
*
Handles
;
DWORD
numHandles
;
};
/* Vtables in various versions */
...
...
@@ -309,6 +328,7 @@ const GUID IID_D3DDEVICE_WineD3D;
/* Helper functions */
HRESULT
IDirect3DImpl_GetCaps
(
IWineD3D
*
WineD3D
,
D3DDEVICEDESC
*
Desc123
,
D3DDEVICEDESC7
*
Desc7
);
DWORD
IDirect3DDeviceImpl_CreateHandle
(
IDirect3DDeviceImpl
*
This
);
/* Structures */
struct
EnumTextureFormatsCBS
...
...
@@ -443,6 +463,7 @@ struct IDirect3DMaterialImpl
IDirect3DDeviceImpl
*
active_device
;
D3DMATERIAL
mat
;
DWORD
Handle
;
void
(
*
activate
)(
IDirect3DMaterialImpl
*
this
);
};
...
...
dlls/ddraw/device.c
View file @
1e2413f4
...
...
@@ -286,6 +286,8 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
if
(
ref
==
0
)
{
IParent
*
IndexBufferParent
;
DWORD
i
;
/* Free the index buffer */
IWineD3DDevice_SetIndices
(
This
->
wineD3DDevice
,
NULL
,
...
...
@@ -316,6 +318,38 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
ERR
(
" (%p) The wineD3D device %p was destroyed unexpectadely. Prepare for trouble
\n
"
,
This
,
This
->
wineD3DDevice
);
}
/* The texture handles should be unset by now, but there might be some bits
* missing in our reference counting(needs test). Do a sanity check
*/
for
(
i
=
0
;
i
<
This
->
numHandles
;
i
++
)
{
if
(
This
->
Handles
[
i
].
ptr
)
{
switch
(
This
->
Handles
[
i
].
type
)
{
case
DDrawHandle_Texture
:
{
IDirectDrawSurfaceImpl
*
surf
=
(
IDirectDrawSurfaceImpl
*
)
This
->
Handles
[
i
].
ptr
;
FIXME
(
"Texture Handle %ld not unset properly
\n
"
,
i
+
1
);
surf
->
Handle
=
0
;
}
break
;
case
DDrawHandle_Material
:
{
IDirect3DMaterialImpl
*
mat
=
(
IDirect3DMaterialImpl
*
)
This
->
Handles
[
i
].
ptr
;
FIXME
(
"Material handle %ld not unset properly
\n
"
,
i
+
1
);
mat
->
Handle
=
0
;
}
default:
FIXME
(
"Unknown handle %ld not unset properly
\n
"
,
i
+
1
);
}
}
}
HeapFree
(
GetProcessHeap
(),
0
,
This
->
Handles
);
/* Release the render target and the WineD3D render target
* (See IDirect3D7::CreateDevice for more comments on this)
*/
...
...
@@ -492,22 +526,17 @@ IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
IDirect3DTexture2
*
Tex2
)
{
ICOM_THIS_FROM
(
IDirect3DDeviceImpl
,
IDirect3DDevice2
,
iface
);
IWineD3DTexture
*
tm
p
;
DWORD
swa
p
;
IDirectDrawSurfaceImpl
*
surf1
=
ICOM_OBJECT
(
IDirectDrawSurfaceImpl
,
IDirect3DTexture2
,
Tex1
);
IDirectDrawSurfaceImpl
*
surf2
=
ICOM_OBJECT
(
IDirectDrawSurfaceImpl
,
IDirect3DTexture2
,
Tex2
);
FIXM
E
(
"(%p)->(%p,%p)
\n
"
,
This
,
surf1
,
surf2
);
TRAC
E
(
"(%p)->(%p,%p)
\n
"
,
This
,
surf1
,
surf2
);
This
->
Handles
[
surf1
->
Handle
-
1
].
ptr
=
surf2
;
This
->
Handles
[
surf2
->
Handle
-
1
].
ptr
=
surf1
;
/* The texture handle is simply the interface address of the WineD3DTexture
* interface. Swap the interface pointers.
*/
tmp
=
surf1
->
wineD3DTexture
;
surf1
->
wineD3DTexture
=
surf2
->
wineD3DTexture
;
surf2
->
wineD3DTexture
=
tmp
;
/* What about the parent? Does it have to change too? This could cause a
* problem when Releasing the surfaces, Therefore the fixme
*/
swap
=
surf2
->
Handle
;
surf2
->
Handle
=
surf1
->
Handle
;
surf1
->
Handle
=
swap
;
return
D3D_OK
;
}
...
...
@@ -2029,9 +2058,32 @@ IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
switch
(
RenderStateType
)
{
case
D3DRENDERSTATE_TEXTUREHANDLE
:
return
IWineD3DDevice_SetTexture
(
This
->
wineD3DDevice
,
0
,
(
IWineD3DBaseTexture
*
)
Value
);
{
if
(
Value
==
0
)
{
return
IWineD3DDevice_SetTexture
(
This
->
wineD3DDevice
,
0
,
NULL
);
}
if
(
Value
>
This
->
numHandles
)
{
FIXME
(
"Specified handle %ld out of range
\n
"
,
Value
);
return
DDERR_INVALIDPARAMS
;
}
if
(
This
->
Handles
[
Value
-
1
].
type
!=
DDrawHandle_Texture
)
{
FIXME
(
"Handle %ld isn't a texture handle
\n
"
,
Value
);
return
DDERR_INVALIDPARAMS
;
}
else
{
IDirectDrawSurfaceImpl
*
surf
=
(
IDirectDrawSurfaceImpl
*
)
This
->
Handles
[
Value
-
1
].
ptr
;
return
IWineD3DDevice_SetTexture
(
This
->
wineD3DDevice
,
0
,
(
IWineD3DBaseTexture
*
)
surf
->
wineD3DTexture
);
}
}
case
D3DRENDERSTATE_TEXTUREMAG
:
{
...
...
@@ -4572,3 +4624,68 @@ const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
Thunk_IDirect3DDeviceImpl_1_BeginScene
,
Thunk_IDirect3DDeviceImpl_1_GetDirect3D
};
/*****************************************************************************
* IDirect3DDeviceImpl_CreateHandle
*
* Not called from the VTable
*
* Some older interface versions operate with handles, which are basically
* DWORDs which identify an interface, for example
* IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
*
* Those handle could be just casts to the interface pointers or vice versa,
* but that is not 64 bit safe and would mean blindly derefering a DWORD
* passed by the app. Instead there is a dynamic array in the device which
* keeps a DWORD to pointer information and a type for the handle.
*
* Basically this array only grows, when a handle is freed its pointer is
* just set to NULL. There will be much more reads from the array than
* insertion operations, so a dynamic array is fine.
*
* Params:
* This: D3DDevice implementation for which this handle should be created
*
* Returns:
* A free handle on success
* 0 on failure
*
*****************************************************************************/
DWORD
IDirect3DDeviceImpl_CreateHandle
(
IDirect3DDeviceImpl
*
This
)
{
DWORD
i
;
struct
HandleEntry
*
oldHandles
=
This
->
Handles
;
TRACE
(
"(%p)
\n
"
,
This
);
for
(
i
=
0
;
i
<
This
->
numHandles
;
i
++
)
{
if
(
This
->
Handles
[
i
].
ptr
==
NULL
&&
This
->
Handles
[
i
].
type
==
DDrawHandle_Unknown
)
{
TRACE
(
"Reusing freed handle %ld
\n
"
,
i
+
1
);
return
i
+
1
;
}
}
TRACE
(
"Growing the handle array
\n
"
);
This
->
numHandles
++
;
This
->
Handles
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
HandleEntry
)
*
This
->
numHandles
);
if
(
!
This
->
Handles
)
{
ERR
(
"Out of memory
\n
"
);
This
->
Handles
=
oldHandles
;
This
->
numHandles
--
;
return
0
;
}
if
(
oldHandles
)
{
memcpy
(
This
->
Handles
,
oldHandles
,
(
This
->
numHandles
-
1
)
*
sizeof
(
struct
HandleEntry
));
HeapFree
(
GetProcessHeap
(),
0
,
oldHandles
);
}
TRACE
(
"Returning %ld
\n
"
,
This
->
numHandles
);
return
This
->
numHandles
;
}
dlls/ddraw/direct3d.c
View file @
1e2413f4
...
...
@@ -729,6 +729,9 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface,
object
->
material
=
0
;
object
->
target
=
target
;
object
->
Handles
=
NULL
;
object
->
numHandles
=
0
;
/* This is for convenience */
object
->
wineD3DDevice
=
This
->
wineD3DDevice
;
...
...
dlls/ddraw/material.c
View file @
1e2413f4
...
...
@@ -147,9 +147,16 @@ IDirect3DMaterialImpl_Release(IDirect3DMaterial3 *iface)
TRACE
(
"(%p)->() decrementing from %lu.
\n
"
,
This
,
ref
+
1
);
if
(
!
ref
)
{
if
(
!
ref
)
{
if
(
This
->
Handle
)
{
This
->
ddraw
->
d3ddevice
->
Handles
[
This
->
Handle
-
1
].
ptr
=
NULL
;
This
->
ddraw
->
d3ddevice
->
Handles
[
This
->
Handle
-
1
].
type
=
DDrawHandle_Unknown
;
}
HeapFree
(
GetProcessHeap
(),
0
,
This
);
return
0
;
return
0
;
}
return
ref
;
}
...
...
@@ -301,15 +308,24 @@ IDirect3DMaterialImpl_GetHandle(IDirect3DMaterial3 *iface,
D3DMATERIALHANDLE
*
lpHandle
)
{
ICOM_THIS_FROM
(
IDirect3DMaterialImpl
,
IDirect3DMaterial3
,
iface
);
TRACE
(
"(%p/%p)->(%p,%p)
\n
"
,
This
,
iface
,
lpDirect3DDevice3
,
lpHandle
);
This
->
active_device
=
ICOM_OBJECT
(
IDirect3DDeviceImpl
,
IDirect3DDevice3
,
lpDirect3DDevice3
);
*
lpHandle
=
(
DWORD
)
This
;
/* Warning: this is not 64 bit clean.
Maybe also we need to store this material somewhere in the device ? */
IDirect3DDeviceImpl
*
device
=
ICOM_OBJECT
(
IDirect3DDeviceImpl
,
IDirect3DDevice3
,
lpDirect3DDevice3
);
TRACE
(
"(%p/%p)->(%p,%p)
\n
"
,
This
,
iface
,
device
,
lpHandle
);
if
(
!
This
->
Handle
)
{
This
->
Handle
=
IDirect3DDeviceImpl_CreateHandle
(
device
);
if
(
!
This
->
Handle
)
{
ERR
(
"Error creating a handle
\n
"
);
return
DDERR_INVALIDPARAMS
;
/* Unchecked */
}
device
->
Handles
[
This
->
Handle
-
1
].
ptr
=
This
;
device
->
Handles
[
This
->
Handle
-
1
].
type
=
DDrawHandle_Material
;
}
*
lpHandle
=
This
->
Handle
;
TRACE
(
" returning handle %08lx.
\n
"
,
*
lpHandle
);
return
DD_OK
;
return
D
3
D_OK
;
}
static
HRESULT
WINAPI
...
...
dlls/ddraw/surface.c
View file @
1e2413f4
...
...
@@ -229,6 +229,13 @@ static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This)
if
(
This
->
WineD3DSurface
)
IWineD3DSurface_Release
(
This
->
WineD3DSurface
);
/* Having a texture handle set implies that the device still exists */
if
(
This
->
Handle
)
{
This
->
ddraw
->
d3ddevice
->
Handles
[
This
->
Handle
-
1
].
ptr
=
NULL
;
This
->
ddraw
->
d3ddevice
->
Handles
[
This
->
Handle
-
1
].
type
=
DDrawHandle_Unknown
;
}
/* Reduce the ddraw surface count */
InterlockedDecrement
(
&
This
->
ddraw
->
surfaces
);
if
(
This
->
prev
)
...
...
dlls/ddraw/texture.c
View file @
1e2413f4
...
...
@@ -45,6 +45,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
d3d7
);
WINE_DECLARE_DEBUG_CHANNEL
(
ddraw_thunk
);
/*****************************************************************************
* IUnknown interfaces. They are thunks to IDirectDrawSurface7
...
...
@@ -218,14 +219,16 @@ IDirect3DTextureImpl_GetHandle(IDirect3DTexture2 *iface,
TRACE
(
"(%p)->(%p,%p)
\n
"
,
This
,
d3d
,
lpHandle
);
/* The handle is the WineD3DTexture interface. SetRenderState depends on this */
if
(
This
->
ddraw
->
wineD3DDevice
)
*
lpHandle
=
(
D3DTEXTUREHANDLE
)
This
->
wineD3DTexture
;
else
if
(
!
This
->
Handle
)
{
/* This is to fool applications which create a texture without a D3DDevice */
*
lpHandle
=
(
D3DTEXTUREHANDLE
)
This
;
This
->
Handle
=
IDirect3DDeviceImpl_CreateHandle
(
d3d
);
if
(
This
->
Handle
)
{
d3d
->
Handles
[
This
->
Handle
-
1
].
ptr
=
This
;
d3d
->
Handles
[
This
->
Handle
-
1
].
type
=
DDrawHandle_Texture
;
}
}
*
lpHandle
=
This
->
Handle
;
TRACE
(
" returning handle %08lx.
\n
"
,
*
lpHandle
);
...
...
@@ -238,10 +241,11 @@ Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface,
LPD3DTEXTUREHANDLE
lpHandle
)
{
ICOM_THIS_FROM
(
IDirectDrawSurfaceImpl
,
IDirect3DTexture
,
iface
);
TRACE
(
"(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.
\n
"
,
This
,
lpDirect3DDevice
,
lpHandle
);
IDirect3DDeviceImpl
*
d3d
=
ICOM_OBJECT
(
IDirect3DDeviceImpl
,
IDirect3DDevice
,
lpDirect3DDevice
);
TRACE_
(
ddraw_thunk
)(
"(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.
\n
"
,
This
,
d3d
,
lpHandle
);
return
IDirect3DTexture2_GetHandle
(
COM_INTERFACE_CAST
(
IDirectDrawSurfaceImpl
,
IDirect3DTexture
,
IDirect3DTexture2
,
iface
),
COM_INTERFACE_CAST
(
IDirect3DDeviceImpl
,
IDirect3DDevice
,
IDirect3DDevice2
,
lpDirect3DDevice
),
return
IDirect3DTexture2_GetHandle
(
ICOM_INTERFACE
(
This
,
IDirect3DTexture2
),
ICOM_INTERFACE
(
d3d
,
IDirect3DDevice2
),
lpHandle
);
}
...
...
dlls/ddraw/viewport.c
View file @
1e2413f4
...
...
@@ -384,14 +384,33 @@ IDirect3DViewportImpl_SetBackground(IDirect3DViewport3 *iface,
D3DMATERIALHANDLE
hMat
)
{
ICOM_THIS_FROM
(
IDirect3DViewportImpl
,
IDirect3DViewport3
,
iface
);
TRACE
(
"(%p)->(%08lx)
\n
"
,
This
,
(
DWORD
)
hMat
);
This
->
background
=
(
IDirect3DMaterialImpl
*
)
hMat
;
TRACE
(
" setting background color : %f %f %f %f
\n
"
,
This
->
background
->
mat
.
u
.
diffuse
.
u1
.
r
,
This
->
background
->
mat
.
u
.
diffuse
.
u2
.
g
,
This
->
background
->
mat
.
u
.
diffuse
.
u3
.
b
,
This
->
background
->
mat
.
u
.
diffuse
.
u4
.
a
);
TRACE
(
"(%p)->(%ld)
\n
"
,
This
,
(
DWORD
)
hMat
);
if
(
hMat
&&
hMat
>
This
->
ddraw
->
d3ddevice
->
numHandles
)
{
WARN
(
"Specified Handle %ld out of range
\n
"
,
hMat
);
return
DDERR_INVALIDPARAMS
;
}
else
if
(
hMat
&&
This
->
ddraw
->
d3ddevice
->
Handles
[
hMat
-
1
].
type
!=
DDrawHandle_Material
)
{
WARN
(
"Handle %ld is not a material handle
\n
"
,
hMat
);
return
DDERR_INVALIDPARAMS
;
}
if
(
hMat
)
{
This
->
background
=
(
IDirect3DMaterialImpl
*
)
This
->
ddraw
->
d3ddevice
->
Handles
[
hMat
-
1
].
ptr
;
TRACE
(
" setting background color : %f %f %f %f
\n
"
,
This
->
background
->
mat
.
u
.
diffuse
.
u1
.
r
,
This
->
background
->
mat
.
u
.
diffuse
.
u2
.
g
,
This
->
background
->
mat
.
u
.
diffuse
.
u3
.
b
,
This
->
background
->
mat
.
u
.
diffuse
.
u4
.
a
);
}
else
{
This
->
background
=
NULL
;
TRACE
(
"Setting background to NULL
\n
"
);
}
return
D3D_OK
;
}
...
...
@@ -406,8 +425,7 @@ IDirect3DViewportImpl_SetBackground(IDirect3DViewport3 *iface,
* lpValid: is set to FALSE if no background is set, TRUE if one is set
*
* Returns:
* D3D_OK, because it's a stub
* (DDERR_INVALIDPARAMS if Mat or Valid is NULL)
* D3D_OK
*
*****************************************************************************/
static
HRESULT
WINAPI
...
...
@@ -416,7 +434,24 @@ IDirect3DViewportImpl_GetBackground(IDirect3DViewport3 *iface,
BOOL
*
lpValid
)
{
ICOM_THIS_FROM
(
IDirect3DViewportImpl
,
IDirect3DViewport3
,
iface
);
FIXME
(
"(%p)->(%p,%p): stub!
\n
"
,
This
,
lphMat
,
lpValid
);
TRACE
(
"(%p)->(%p,%p)
\n
"
,
This
,
lphMat
,
lpValid
);
if
(
lpValid
)
{
*
lpValid
=
This
->
background
!=
NULL
;
}
if
(
lphMat
)
{
if
(
This
->
background
)
{
*
lphMat
=
This
->
background
->
Handle
;
}
else
{
*
lphMat
=
0
;
}
}
return
D3D_OK
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment