Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1363 lines
54 KiB

/******************************Module*Header*******************************\
* Module Name: ddraw.hxx
*
* DirectDraw extended objects.
*
* Created: 3-Dec-1995
* Author: J. Andrew Goossen [andrewgo]
*
* Copyright (c) 1995-1999 Microsoft Corporation
*
\**************************************************************************/
#ifndef GDIFLAGS_ONLY // used for gdikdx
// Handy forward declarations:
class EDD_SURFACE;
class EDD_VIDEOPORT;
class EDD_DIRECTDRAW_LOCAL;
class EDD_DIRECTDRAW_GLOBAL;
class EDD_DXDIRECTDRAW;
class EDD_DXVIDEOPORT;
class EDD_DXSURFACE;
class EDD_DXCAPTURE;
class EDD_MOTIONCOMP;
class EDD_VMEMMAPPING;
class DXOBJ;
#endif // GDIFLAGS_ONLY
#ifdef DXKERNEL_BUILD
extern PVOID gpDummyPage;
extern LONG gcDummyPageRefCnt;
extern HSEMAPHORE ghsemDummyPage;
// Ease the pain of probes:
inline
VOID
ProbeAndWriteRVal(
HRESULT* pRVal,
HRESULT RVal
)
{
ProbeAndWriteStructure(pRVal, RVal, HRESULT);
}
// Reasonable bounds for any drawing calls, to ensure that drivers won't
// overflow their math if given bad data:
#define DD_MAXIMUM_COORDINATE (0x8000)
#define DD_MINIMUM_COORDINATE -(0x8000)
// Function exports to handle enabling and disabling DirectDraw when
// the driver is loaded or unloaded.
BOOL bDdEnableDirectDraw(
HDEV hdev
);
VOID vDdDisableDirectDraw(
HDEV hdev
);
// Generic QueryInterface IO request function:
BOOL
bDdIoQueryInterface(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal,
const GUID* pguid,
DWORD cjInterface,
DWORD dwDesiredVersion,
INTERFACE* pInterface
);
// Function exports to be called from the handle manager cleanup code:
BOOL
bDdDeleteDirectDrawObject(
HANDLE hDirectDrawLocal,
BOOL bProcessTermination
);
BOOL
bDdDeleteSurfaceObject(
HANDLE hSurface,
DWORD* pdwRet
);
BOOL
bDdDeleteVideoPortObject(
HANDLE hVideoPort,
DWORD* pdwRet
);
BOOL
bDdReleaseDC(
EDD_SURFACE* peSurface,
BOOL bForce
);
BOOL
bDdDeleteMotionCompObject(
HANDLE hMotionComp,
DWORD* pdwRet
);
// Private support functions exported from WIN32K.SYS for DXAPI.SYS.
#define DXAPI_PRIVATE_VERSION_NUMBER 0x1001
extern "C"
VOID
APIENTRY
DdDxApiOpenDirectDraw(
DDOPENDIRECTDRAWIN* pOpenDirectDrawIn,
DDOPENDIRECTDRAWOUT* pOpenDirectDrawOut,
PKDEFERRED_ROUTINE pfnEventDpc,
ULONG VersionNumber
);
extern "C"
VOID
APIENTRY
DdDxApiOpenVideoPort(
DDOPENVIDEOPORTIN* pOpenVideoPortIn,
DDOPENVIDEOPORTOUT* pOpenVideoPortOut
);
extern "C"
VOID
APIENTRY
DdDxApiOpenSurface(
DDOPENSURFACEIN* pOpenSurfaceIn,
DDOPENSURFACEOUT* pOpenSurfaceOut
);
extern "C"
VOID
APIENTRY
DdDxApiCloseHandle(
DDCLOSEHANDLE* pCloseHandle,
DWORD* pdwRet
);
extern "C"
VOID
APIENTRY
DdDxApiOpenCaptureDevice(
DDOPENVPCAPTUREDEVICEIN* pOpenCaptureDeviceIn,
DDOPENVPCAPTUREDEVICEOUT* pOpenCaptureDeviceOut
);
extern "C"
VOID
APIENTRY
DdDxApiGetKernelCaps(
HANDLE hDirectDraw,
DDGETKERNELCAPSOUT* pGetKernelCaps
);
extern "C"
VOID
APIENTRY
DdDxApiLockDevice(
HDEV hdev
);
extern "C"
VOID
APIENTRY
DdDxApiUnlockDevice(
HDEV hdev
);
// Function exports for handling DXAPI non-paged allocations:
VOID
vDdSynchronizeVideoPort(
EDD_VIDEOPORT* peVideoPort
);
VOID
vDdSynchronizeSurface(
EDD_SURFACE* peSurface
);
VOID
vDdStopVideoPort(
EDD_VIDEOPORT* peVideoPort
);
VOID
vDdQueryMiniportDxApiSupport(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal
);
HANDLE
hDdOpenDxApiSurface(
EDD_SURFACE* peSurface
);
VOID
vDdCloseDxApiSurface(
EDD_SURFACE* peSurface
);
BOOL
bDdLoadDxApi(
EDD_DIRECTDRAW_LOCAL* peDirectDrawLocal
);
VOID
vDdUnloadDxApi(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal
);
VOID
vDdUnloadDxApiImage(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal
);
VOID
vDdLoseDxObjects(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal,
DXOBJ* pDxObj,
PVOID pDxThing,
DWORD dwType
);
VOID
vDdDxApiFreeSurface(
DXOBJ* pDxObj,
BOOL bDoCallBack
);
// Handle dynamic mode changes for DirectDraw:
VOID
vDdDynamicModeChange(
HDEV hdevOld,
HDEV hdevNew
);
VOID
vDdNotifyEvent(
EDD_DIRECTDRAW_GLOBAL* peDirectDraw,
DWORD dwEvent
);
#endif // DXKERNEL_BUILD
#ifndef GDIFLAGS_ONLY // used for gdikdx
typedef
VOID
(APIENTRY *PFNAUTOFLIPUPDATE)(
EDD_DXVIDEOPORT* peDxVideoPort,
EDD_DXSURFACE** apeDxSurfaceVideo,
ULONG cSurfacesVideo,
EDD_DXSURFACE** apeDxSurfaceVbi,
ULONG cSurfacesVbi
);
typedef enum {
LO_DIRECTDRAW,
LO_VIDEOPORT,
LO_SURFACE,
LO_CAPTURE
} LOTYPE;
typedef
void
(APIENTRY *PFNLOSEOBJECT)(
VOID* pvObject,
LOTYPE loType
);
typedef
void
(APIENTRY *PFNENABLEIRQ)(
EDD_DXVIDEOPORT* peDxVideoPort,
BOOL bEnable
);
typedef
void
(APIENTRY *PFNUPDATECAPTURE)(
EDD_DXVIDEOPORT* peDxVideoPort,
EDD_DXCAPTURE* peDxCapture,
BOOL bDelete
);
typedef
VOID
(APIENTRY *PFNDXAPIOPENDIRECTDRAW)(
DDOPENDIRECTDRAWIN* pOpenDirectDrawIn,
DDOPENDIRECTDRAWOUT* pOpenDirectDrawOut,
PKDEFERRED_ROUTINE pfnEventDpc,
ULONG DxApiPrivateVersionNumber
);
typedef
VOID
(APIENTRY *PFNDXAPIOPENVIDEOPORT)(
DDOPENVIDEOPORTIN* pOpenVideoPortIn,
DDOPENVIDEOPORTOUT* pOpenVideoPortOut
);
typedef
VOID
(APIENTRY *PFNDXAPIOPENSURFACE)(
DDOPENSURFACEIN* pOpenSurfaceIn,
DDOPENSURFACEOUT* pOpenSurfaceOut
);
typedef
VOID
(APIENTRY *PFNDXAPICLOSEHANDLE)(
DDCLOSEHANDLE* pCloseHandle,
DWORD* pdwRet
);
typedef
VOID
(APIENTRY *PFNDXAPIGETKERNELCAPS)(
HANDLE hDirectDraw,
DDGETKERNELCAPSOUT* pdwRet
);
typedef
VOID
(APIENTRY *PFNDXAPIOPENCAPTUREDEVICE)(
DDOPENVPCAPTUREDEVICEIN* pOpenCaptureDeviceIn,
DDOPENVPCAPTUREDEVICEOUT* pOpenCaptureDeviceOut
);
typedef
VOID
(APIENTRY *PFNDXAPILOCKDEVICE)(
HDEV hdev
);
typedef
VOID
(APIENTRY *PFNDXAPIUNLOCKDEVICE)(
HDEV hdev
);
typedef
VOID
(APIENTRY *PFNDXAPIINITIALIZE)(
PFNDXAPIOPENDIRECTDRAW pfnOpenDirectDraw,
PFNDXAPIOPENVIDEOPORT pfnOpenVideoPort,
PFNDXAPIOPENSURFACE pfnOpenSurface,
PFNDXAPICLOSEHANDLE pfnCloseHandle,
PFNDXAPIGETKERNELCAPS pfnGetKernelCaps,
PFNDXAPIOPENCAPTUREDEVICE pfnOpenCaptureDevice,
PFNDXAPILOCKDEVICE pfnLockDevice,
PFNDXAPIUNLOCKDEVICE pfnUnlockDevice
);
#endif
////////////////////////////////////////////////////////////////////////////
// The following 'extended' (hence the 'E') classes contain all the private
// GDI information associated with the public objects that we don't want
// the DirectDraw drivers to see.
/*********************************Class************************************\
* class DD_DIRECTDRAW_GLOBAL_DRIVER_DATA
*
* Contains all the DirectDraw mode-specific driver data. This entire
* structure is preserved, along with the driver instance, on a mode
* change (until such time as all D3D, WNDOBJ, and DRIVEROBJ objects
* referencing that mode are deleted).
*
\**************************************************************************/
#define DD_DRIVER_FLAG_EMULATE_SYSTEM_TO_VIDEO 0x0001
// Set if kernel-mode is emulating system-memory to
// video-memory calls
#define DD_DRIVERINFO_MISCELLANEOUS 0x0001
#define DD_DRIVERINFO_VIDEOPORT 0x0002
#define DD_DRIVERINFO_COLORCONTROL 0x0004
#define DD_DRIVERINFO_D3DCALLBACKS2 0x0008
#define DD_DRIVERINFO_MOTIONCOMP 0x0040
#define DD_DRIVERINFO_MISCELLANEOUS2 0x0080
#define DD_DRIVERINFO_MORECAPS 0x0100
#define DD_DRIVERINFO_D3DCALLBACKS3 0x0200
#define DD_DRIVERINFO_NT 0x0400
#define DD_DRIVERINFO_PRIVATECAPS 0x0800
#define DD_DRIVERINFO_MORESURFACECAPS 0x1000
#ifndef GDIFLAGS_ONLY // used for gdikdx
class DD_DIRECTDRAW_GLOBAL_DRIVER_DATA
{
public:
LONG cDriverReferences; // References to driver instance
FLONG flDriver; // DD_DRIVER_FLAGs
FLONG flDriverInfo; // DD_DRIVERINFO flags to indicate
// what DriverInfo calls the driver
// succeeded
LONGLONG llAssertModeTimeout;// Duration for which we'll wait
// for an application to give up
// a lock before changing modes
// (in 100 nanosecond units)
DWORD dwNumHeaps; // Number of heaps
VIDEOMEMORY* pvmList; // Pointer to list of heaps
DWORD dwNumFourCC; // Number of FourCC codes
DWORD* pdwFourCC; // Pointer to list of FourCC codes
DD_HALINFO HalInfo; // Driver information
// VPE capabilities:
DXAPI_INTERFACE DxApiInterface; // Call-tables into miniport
VOID* HwDeviceExtension; // Miniport's context
AGP_INTERFACE AgpInterface; // AGP provider interface.
DDKERNELCAPS DDKernelCaps;
DD_MORECAPS MoreCaps;
DD_NTPRIVATEDRIVERCAPS PrivateCaps;
// DirectDraw entry points:
DD_CALLBACKS CallBacks;
DD_SURFACECALLBACKS SurfaceCallBacks;
DD_PALETTECALLBACKS PaletteCallBacks;
// DX3-style Direct3D driver information and entry points:
D3DNTHAL_GLOBALDRIVERDATA D3dDriverData;
D3DNTHAL_CALLBACKS D3dCallBacks;
DD_D3DBUFCALLBACKS D3dBufCallbacks;
// New DX5 entry points:
D3DNTHAL_CALLBACKS2 D3dCallBacks2;
// Other entry points:
DD_VIDEOPORTCALLBACKS VideoPortCallBacks;
DD_MISCELLANEOUSCALLBACKS MiscellaneousCallBacks;
DD_MISCELLANEOUS2CALLBACKS Miscellaneous2CallBacks;
DD_NTCALLBACKS NTCallBacks;
DD_COLORCONTROLCALLBACKS ColorControlCallBacks;
DD_KERNELCALLBACKS DxApiCallBacks;
// New DX6 entry points:
D3DNTHAL_CALLBACKS3 D3dCallBacks3;
DD_MOTIONCOMPCALLBACKS MotionCompCallbacks;
DD_MORESURFACECAPS MoreSurfaceCaps;
};
#endif // GDIFLAGS_ONLY used for gdikdx
/*********************************Class************************************\
* class DD_DIRECTDRAW_GLOBAL_PDEV_DATA
*
* Contains all the DirectDraw data that stays with PDEV after a mode
* change.
*
\**************************************************************************/
#define DD_GLOBAL_FLAG_DRIVER_ENABLED 0x0001
// Driver's DirectDraw component is enabled
#define DD_GLOBAL_FLAG_MODE_CHANGED 0x0002
// Set if DirectDraw was disabled because the display
// mode has changed
#define DD_GLOBAL_FLAG_BOUNDS_SET 0x0004
// Set after a blt to the primary surface
#ifndef GDIFLAGS_ONLY // used for gdikdx
// Structure used to defer the freeing of usermem until the surface using it
// has been unlocked.
typedef struct _DD_USERMEM_DEFER
{
PVOID pUserMem;
EDD_SURFACE* peSurface;
struct _DD_USERMEM_DEFER* pNext;
} DD_USERMEM_DEFER;
class DD_DIRECTDRAW_GLOBAL_PDEV_DATA
{
public:
// Any fields in this section may be accessed only if the DEVLOCK is held:
EDD_DIRECTDRAW_LOCAL* peDirectDrawLocalList;
// Pointer to list of associated
// DirectDraw local objects
EDD_SURFACE* peSurface_PrimaryLockList;
// List of primary surfaces that
// have an active lock
FLONG fl; // DD_GLOBAL_FLAGs
ULONG cSurfaceLocks; // Number of surface locks currently
// held
PKEVENT pAssertModeEvent; // Wait event for a time-out on
// waiting for everyone to give
// up their surface locks
EDD_SURFACE* peSurfaceCurrent; // Surface that's currently visible
// as a result of a 'flip'
EDD_SURFACE* peSurfacePrimary; // Primary surface that was flipped
// away from
BOOL bSuspended; // All DirectDraw HAL calls are
// suspended (can be checked only
// under the devlock). Note that
// this does NOT necessarily mean
// that the PDEV is disabled. It
// also does not mean that system-
// memory surfaces can't be used
LONG cMaps; // Count of mappings of the frame
// buffer
ULONG cSurfaceAliasedLocks;// Number of aliased surface locks
// currently held
EDD_DXDIRECTDRAW* peDxDirectDraw; // Non-pageable part of the object,
// allocated on demand for DXAPI
// clients
HANDLE hDirectDraw; // DXAPI instance handle, used for
// VPE software autoflipping
PFNAUTOFLIPUPDATE pfnAutoflipUpdate; // DXAPI.SYS routine for updating
// the software autoflipping list
PFNLOSEOBJECT pfnLoseObject; // DXAPI.SYS routine for marking
// DXAPI objects as lost
PFNENABLEIRQ pfnEnableIRQ; // DXAPI.SYS routine to enable/disable
// video port VSYNC IRQs
PFNUPDATECAPTURE pfnUpdateCapture; // DXAPI.SYS routine to add
// capture objects to vports
LPDXAPI pfnDxApi; // DXAPI.SYS entry point for all
// its public APIs
HANDLE hDxApi; // Module handle for dyna-loaded
// DXAPI.SYS
DWORD dwDxApiRefCnt; // Ref count for objects using DxApi
DWORD dwDxApiExplicitLoads;// Prevents ring 3 from unloading
// DXAPI.SYS if it didn't load it
RECTL rclBounds; // Accumulation rectangle of blts
// to primary surface
DD_USERMEM_DEFER* pUserMemDefer;
// Any fields below this point may be read if an associated Local
// DirectDraw or Surface lock is held:
HDEV hdev; // Handle to device
// Any fields below must use Interlocked intrinsics to access:
VOID* hdcCache; // Cached GetDC DC
};
/*********************************Class************************************\
* class EDD_DIRECTDRAW_GLOBAL
*
* This object is global to the PDEV.
*
* Locking convention:
*
* This data is static once created (except for cLocal), so the only
* worry is that the data may get deleted while someone is reading it.
* However, this cannot happen while a lock is held on an associated
* DirectDraw or Surface object. So the rule is:
*
* o Always have a lock held on an associated DirectDraw or Surface
* object when reading this structure.
*
\**************************************************************************/
class EDD_DIRECTDRAW_GLOBAL : public _DD_DIRECTDRAW_GLOBAL,
public _DD_DIRECTDRAW_LOCAL,
public DD_DIRECTDRAW_GLOBAL_DRIVER_DATA,
public DD_DIRECTDRAW_GLOBAL_PDEV_DATA
{
// See above structures for contents.
//
// NOTE: Don't add any fields here! Add them to _DRIVER_DATA or _PDEV_DATA!
};
// Add or remove references to the DirectDraw driver instance:
VOID vDdIncrementReferenceCount(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal
);
VOID vDdDecrementReferenceCount(
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal
);
// Debug macro to ensure that we own the devlock in the appropriate places:
#if DBG
VOID vDdAssertShareDevLock();
VOID vDdAssertDevlock(EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal);
VOID vDdAssertNoDevlock(EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal);
#define DD_ASSERTSHAREDEVLOCK() vDdAssertShareDevlock()
#define DD_ASSERTDEVLOCK(p) vDdAssertDevlock(p)
#define DD_ASSERTNODEVLOCK(p) vDdAssertNoDevlock(p)
#else
#define DD_ASSERTSHAREDEVLOCK()
#define DD_ASSERTDEVLOCK(p)
#define DD_ASSERTNODEVLOCK(p)
#endif
#endif // GDIFLAGS_ONLY used for gdikdx
/*********************************Class************************************\
* class EDD_SURFACE
*
\**************************************************************************/
#define DD_SURFACE_FLAG_PRIMARY 0x0001 // Surface is primary display
#define DD_SURFACE_FLAG_CLIP 0x0002 // There is an HWND associated
// with this surface, so pay
// attention to clipping
#define DD_SURFACE_FLAG_DRIVER_CREATED 0x0004 // Surface was created by the
// driver, so call the driver
// at surface deletion
#define DD_SURFACE_FLAG_CREATE_COMPLETE 0x0008 // Surface has been completely
// created; ignore any further
// NtGdiDdCreateSurfaceObject
// calls with this surface
#define DD_SURFACE_FLAG_UMEM_ALLOCATED 0x0010 // User-mode memory was allocated
// for the surface on behalf
// of the driver
#define DD_SURFACE_FLAG_VMEM_ALLOCATED 0x0020 // Video memory was allocated
// for the surface
#define DD_SURFACE_FLAG_UPDATE_OVERLAY_CALLED 0x0040 // Flag that prevents us from calling
// UpdateOverlay if the driver failed
// to create the surface
#define DD_SURFACE_FLAG_BITMAP_NEEDS_LOCKING 0x0080 // True if the 'hbmGdi' GDI
// representation used by GDI needs
// to have driver's DdLock function
// called before use
#define DD_SURFACE_FLAG_FLIP_PENDING 0x0100 // Set when surface is flipped by
// driver; this is not a reliable
// mechanism to determine flip status
// but will be used when emulating
// system to video blts in kernel
// mode to tell us if we need to
// wait for the flip to finish.
#define DD_SURFACE_FLAG_WRONG_DRIVER 0x0200 // Set when surface is transferred to
// different video driver other than
// it created when the surface is
// "driver managed".
#define DD_SURFACE_FLAG_FAKE_ALIAS_LOCK 0x0400 // Set when we want a NONSYSLOCK lock on
// an AGP surface to behave like
// NONSYSLOCK, even though the driver doesn't
// expose an AGP heap.
#define DD_SURFACE_FLAG_ALIAS_LOCK 0x0800 // Indicates that user mode is holding an
// aliased lock and that we cannot free
// any user mem that the surface may use.
#define DD_SURFACE_FLAG_DEFER_USERMEM 0x1000 // Indicates the surface has allocated
// usermem that needs to be freed via
// the defered list.
#define DD_SURFACE_FLAG_SYSMEM_CREATESURFACEEX 0x2000 // CreateSurfaceEx has been called on
// this system memory surface (which
// means driver has been associated
// to this surface)
#ifndef GDIFLAGS_ONLY // used for gdikdx
class EDD_SURFACE : public DD_OBJECT,
public _DD_SURFACE_LOCAL,
public _DD_SURFACE_MORE,
public _DD_SURFACE_GLOBAL,
public _DD_SURFACE_INT
{
public:
LIST_ENTRY List_eSurface; // List chain of surfaces
// associated with the
// Local DirectDraw object
EDD_SURFACE* peSurface_PrimaryLockNext;
// Next in chain of primary
// surfaces that have an
// active lock
EDD_DXSURFACE* peDxSurface; // Non-pageable part of the
// object, allocated on demand
// for DXAPI clients
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal; // Global DirectDraw object.
EDD_DIRECTDRAW_LOCAL* peDirectDrawLocal; // Local DirectDraw object
FLONG fl; // DD_SURFACE_FLAGs (zeroed when
// surface lost)
ULONG cLocks; // Count of simultaneous Locks
// of this surface
ULONG iVisRgnUniqueness; // Identifies the VisRgn state
// from when the application
// last down-loaded the
// VisRgn
BOOL bLost; // TRUE if surface can't be
// used. NOTE: This field
// is accessible only while
// the devlock is held. This
// is also why it's a BOOL
// and not an 'fl' flag
HANDLE hSecure; // Handle to secured memory
// for DDSCAPS_SYSTEMMEMORY
// surfaces
HDC hdc; // DC handle if a GetDC is
// active; zero if not
HBITMAP hbmGdi; // GDI handle for the surface;
// zero if GetDC hasn't yet
// been called. NOTE: Don't
// convert to SURFOBJ*, as
// 'pConvertDfbSurfaceToDib' may
// get called on it during a
// mode change.
HPALETTE hpalGdi; // GDI handle for the palette
// used in hbmGdi.
HANDLE hSurface; // DXAPI instance handle, used
// for VPE software
// autoflipping
union {
// 'rclLock' is used only for primary surfaces, and the overlay
// dimensions are used only for overlay surfaces. Since the two
// will never overlap, we can use a union to save some space:
RECTL rclLock; // Union of all Lock rectangles
// for this surface
struct {
DWORD dwOverlaySrcWidth; // Used by DXAPI
DWORD dwOverlaySrcHeight; // Used by DXAPI
DWORD dwOverlayDestWidth; // Used by DXAPI
DWORD dwOverlayDestHeight;// Used by DXAPI
};
};
// User-mode surface pointer for Direct3D TextureGetSurf support:
ULONG_PTR upUserModePtr; // LPDIRECTDRAWSURFACE
// If this surface has an NOSYSLOCK lock outstanding, then this point
// to the view of the video memory in which the lock is.
// Currently this is property of the surface. To be similar to the Win9x
// sematics, there should be a pointer per access rect in a surface.
// But we still don't keep track of access rects in the kernel so this
// is a compromise.
EDD_VMEMMAPPING* peMap;
// We need to track the correct peDirectDrawGlobal to be used when freeing this
// mapping. When a mode switch changes the driver we need to make sure the
// original driver is called to free the mapping.
EDD_DIRECTDRAW_GLOBAL* peVirtualMapDdGlobal;
// basically same purpose as above for driver managed surface to keep track
// which video driver create this surface.
ULONG_PTR pldevCreator;
EDD_DIRECTDRAW_GLOBAL* peDdGlobalCreator;
// tracking which graphics device owns this paticualar system memory
// surface, filled when CreateSurfaceEx called for system memory surface.
// only valid with DD_SURFACE_FLAG_CREATESURFACEEX flag.
ULONG_PTR pGraphicsDeviceCreator;
// keep original width and height of DXT textures
DWORD wWidthOriginal;
DWORD wHeightOriginal;
};
#endif
/*********************************Class************************************\
* class EDD_DIRECTDRAW_LOCAL
*
* Essentially, this is a DirectDraw object that is handed out to
* user-mode processes. It should be exclusively locked.
*
\**************************************************************************/
#define DD_LOCAL_FLAG_MEMORY_MAPPED 0x0001 // Frame buffer is mapped into
// the application's space
#define DD_LOCAL_DISABLED 0x0002 // This object has been disabled
// Amount of AGP memory to map at a time when doing user-mode mappings.
// This is dependent on the define AGP_BLOCK_SIZE in nt\drivers\video\ms\port\agp.c
// These two defines must be the same!!
#define DDLOCAL_AGP_MAPPING_PAGES 16
// Since we now allow outstanding locks to video memory even after a mode
// switch there can be multiple views of video memory in any process's
// address space. Only one of these maps to real video memory. The rest are
// just mapped to a dummy page. These user-mode visible "views" of video
// memory correspond to "aliased heaps" on DDraw Win9x. The following
// structure is used to track the lifetime of such mappings.
//
// This structure now tracks AGP heap mappings as well.
#define DD_VMEMMAPPING_FLAG_ALIASED 0x0001
#define DD_VMEMMAPPING_FLAG_AGP 0x0002
// fpProcess is an AGP heap
#ifndef GDIFLAGS_ONLY // used for gdikdx
class EDD_VMEMMAPPING
{
public:
LONG cReferences; // References
FLONG fl; // DD_VMEMMAPPING_FLAGs
union
{
FLATPTR fpProcess; // Video memory base virtual address
VOID* pvVirtAddr; // AGP: Base virtual address
};
VOID* pvReservation; // AGP: User address reservation handle
ULONG ulMapped; // AGP: Highest mapped offset for heap
DWORD iHeapIndex; // AGP: Global heap index into pvmList
BYTE* pAgpVirtualCommitMask;
DWORD dwAgpVirtualCommitMaskSize;
};
class EDD_DIRECTDRAW_LOCAL : public DD_OBJECT,
public _DD_DIRECTDRAW_LOCAL
{
public:
ULONG cSurface; // Number of surfaces associated
// with this DirectDraw object
ULONG cActiveSurface; // Number of surfaces which is
// *not* lost.
LIST_ENTRY ListHead_eSurface; // List of surfaces associated
// with this DirectDraw object
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal; // Pointer to global object
EDD_VIDEOPORT* peVideoPort_DdList; // Pointer to list of
// videoports associated with
// this DirectDraw object
EDD_MOTIONCOMP* peMotionComp_DdList;// Pointer to list of
// motion comp objects
// associated with
// this DirectDraw object
EDD_DIRECTDRAW_LOCAL* peDirectDrawLocalNext;
// Next in chain of DirectDraw
// local objects associated
// with the Global DirectDraw
// object
FLATPTR fpProcess; // Address of frame buffer in
// owning process' address
// space
FLONG fl; // DD_LOCAL_FLAGs
HANDLE UniqueProcess; // Process identifier
PEPROCESS Process; // Process structure pointer
EDD_VMEMMAPPING** ppeMapAgp; // Pointers to current AGP
// heap mappings, if any
int iAgpHeapsMapped; // Count of mapped heaps.
EDD_VMEMMAPPING* peMapCurrent; // Pointer to the current mapping, if any
LPWORD pGammaRamp; // Pointer to gamma ramp set by ddraw
public:
EDD_SURFACE *peSurface_Enum(EDD_SURFACE *peSurface)
{
EDD_SURFACE *peSurface_Next = NULL;
if (!IsListEmpty(&ListHead_eSurface))
{
PLIST_ENTRY p = NULL;
if (peSurface == NULL)
{
// Enum 1st one. get from list head.
p = ListHead_eSurface.Flink;
}
else
{
// Enum next one, check if this is last one or not.
if (peSurface->List_eSurface.Flink != &ListHead_eSurface)
{
p = peSurface->List_eSurface.Flink;
}
}
if (p)
{
peSurface_Next = CONTAINING_RECORD(p,EDD_SURFACE,List_eSurface);
}
}
return (peSurface_Next);
}
};
#endif
#ifdef DXKERNEL_BUILD
/********************************Function**********************************\
* inline EDD_SURFACE* pedFromLp
*
\**************************************************************************/
inline
EDD_SURFACE*
pedFromLp(
DD_SURFACE_LOCAL* pSurfaceLocal
)
{
return((EDD_SURFACE*) ((BYTE*) pSurfaceLocal
- offsetof(EDD_SURFACE, DD_SURFACE_LOCAL::lpGbl)));
}
/*********************************Class************************************\
* class EDD_VIDEOPORT
*
\**************************************************************************/
#define DD_VIDEOPORT_FLAG_DRIVER_CREATED 0x0001
// Videoport was created by the
// driver, so call the driver
// at surface deletion
class EDD_VIDEOPORT : public DD_OBJECT,
public _DD_VIDEOPORT_LOCAL
{
public:
EDD_VIDEOPORT* peVideoPort_DdNext; // Next in chain of videoports
// associated with the Local
// DirectDraw object
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal; // Global DirectDraw object
EDD_DIRECTDRAW_LOCAL* peDirectDrawLocal; // Local DirectDraw object
FLONG fl; // DD_VIDEOPORT_FLAGs
DDPIXELFORMAT ddpfInputFormat; // Holds ddvpInfo.lpddpfInputFormat
EDD_DXVIDEOPORT* peDxVideoPort; // Non-pageable part of the
// object, allocated on demand
// for DXAPI clients
HANDLE hVideoPort; // DXAPI instance handle, used
// for VPE software
// autoflipping
DWORD cAutoflipVideo; // Number of autoflip surfaces
// for video
DWORD cAutoflipVbi; // Number of autoflip surfaces
// for VBI data
EDD_SURFACE* apeSurfaceVideo[MAX_AUTOFLIP_BUFFERS];
// Array of video autoflip
// surfaces
EDD_SURFACE* apeSurfaceVbi[MAX_AUTOFLIP_BUFFERS];
// Array of VBI autoflip
// surfaces
};
/********************************Function**********************************\
* EDD_VIDEOPORT* pedFromLp
*
\**************************************************************************/
inline
EDD_VIDEOPORT*
pedFromLp(
DD_VIDEOPORT_LOCAL* pVideoPortLocal
)
{
return((EDD_VIDEOPORT*) ((BYTE*) pVideoPortLocal
- offsetof(EDD_VIDEOPORT, lpDD)));
}
/*********************************Class************************************\
* class EDD_PALETTE
*
\**************************************************************************/
class EDD_PALETTE : public DD_OBJECT,
public _DD_PALETTE_LOCAL,
public _DD_PALETTE_GLOBAL
{
public:
};
/*********************************Class************************************\
* class EDD_CLIPPER
*
\**************************************************************************/
class EDD_CLIPPER : public DD_OBJECT,
public _DD_CLIPPER_LOCAL,
public _DD_CLIPPER_GLOBAL
{
public:
};
/*********************************Class************************************\
* class EDD_MOTIONCOMP
*
\**************************************************************************/
#define DD_MOTIONCOMP_FLAG_DRIVER_CREATED 0x0001
// Videoport was created by the
// driver, so call the driver
// at surface deletion
class EDD_MOTIONCOMP : public DD_OBJECT,
public _DD_MOTIONCOMP_LOCAL
{
public:
EDD_MOTIONCOMP* peMotionComp_DdNext;// Next in chain of video objects
// associated with the Local
// DirectDraw object
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal; // Global DirectDraw object
EDD_DIRECTDRAW_LOCAL* peDirectDrawLocal; // Local DirectDraw object
FLONG fl; // DD_MOTIONCOMP_FLAGs
};
////////////////////////////////////////////////////////////////////////////
// DXAPI structures
typedef struct _DXAPI_EVENT DXAPI_EVENT;
typedef struct _DXAPI_EVENT {
EDD_DXDIRECTDRAW* peDxDirectDraw; // Associated DirectDraw object
EDD_DXVIDEOPORT* peDxVideoPort; // NULL if event is not tied
// to a videoport
DWORD dwEvent;
DWORD dwIrqFlag; // 0 if not an interrupt event
LPDD_NOTIFYCALLBACK pfnCallBack;
PVOID pContext;
DXAPI_EVENT* pDxEvent_Next;
} DXAPI_EVENT;
/*********************************Class************************************\
* class EDD_DXDIRECTDRAW
*
* The non-pageable part of the EDD_DIRECTDRAW_GLOBAL structure, allocated
* on demand for DXAPI clients.
*
\**************************************************************************/
/*
* We keep two disptach lists - one for the callbacks registered by the clients
* and another for our own callbacks. We do this so we can gaurentee that we
* call the clients first so they can call the skip fucntions before we execute
* our skip logic within our own callbacks.
*/
#define NUM_DISPATCH_LISTS 2
#define CLIENT_DISPATCH_LIST 0
#define INTERNAL_DISPATCH_LIST 1
class EDD_DXDIRECTDRAW
{
public:
BOOL bLost; // DirectDraw object is lost
EDD_DIRECTDRAW_GLOBAL* peDirectDrawGlobal; // Owning DirectDraw object;
// NULL if lost
DXOBJ* pDxObj_List; // List of open DXAPI objects
// for this DirectDraw object
HDEV hdev; // Identifies owning PDEV
DXAPI_INTERFACE DxApiInterface; // Call-tables into miniport
VOID* HwDeviceExtension; // Miniport's context
DWORD dwIRQCaps; // Miniport's interrupt
// capabilities
KDPC EventDpc; // DPC for handling interrupt
// call-backs
KSPIN_LOCK SpinLock; // SpinLock for protecting
// DXAPI event list and
// serializing raised
// IRQL calls to miniport
DWORD dwSynchedIrqFlags; // Used temporarily for
// atomically reading
// the miniport's dwIrqFlags
// interrupt status
DX_IRQDATA IrqData; // Context miniport passes
// back to us on its
// IRQCallBack call during an
// interrupt
DXAPI_EVENT* pDxEvent_PassiveList; // List of passive-level
// events, protected by
// devlock
DXAPI_EVENT* pDxEvent_DispatchList[2];// Lists of dispatch-level
// events, protected by
// spinlock
DXAPI_EVENT* pDxEvent_CaptureList; // List of video ports
// capturing
};
#endif // DXKERNEL_BUILD
/*********************************Class************************************\
* class EDD_DXVIDEOPORT
*
* The non-pageable part of the EDD_VIDEOPORT structure, allocated
* on demand for DXAPI clients.
*
\**************************************************************************/
#define DD_DXVIDEOPORT_FLAG_ON 0x0001
// The video port is on
#define DD_DXVIDEOPORT_FLAG_AUTOFLIP 0x0002
// Video data is autoflipped using IRQ
#define DD_DXVIDEOPORT_FLAG_AUTOFLIP_VBI 0x0004
// VBI data is autoflipped using IRQ
#define DD_DXVIDEOPORT_FLAG_BOB 0x0008
// Video data using bob via the IRQ
#define DD_DXVIDEOPORT_FLAG_CAPTURING 0x0010
// VP has capture buffers in queue
#define DD_DXVIDEOPORT_FLAG_NEW_STATE 0x0020
// A new state change has been posted
#define DD_DXVIDEOPORT_FLAG_SKIPPED_LAST 0x0040
// The previous field was skipped
// - VP needs restoring
#define DD_DXVIDEOPORT_FLAG_SKIP_SET 0x0080
// dwStartSkip contains valid data
#define DD_DXVIDEOPORT_FLAG_NEXT_SKIP_SET 0x0100
// dwNextSkip contains valid data
#define DD_DXVIDEOPORT_FLAG_FLIP_NEXT 0x0200
// This video field was not
// flipped due to interleaving
#define DD_DXVIDEOPORT_FLAG_FLIP_NEXT_VBI 0x0400
// This VBI field was not
// flipped due to interleaving
#define DD_DXVIDEOPORT_FLAG_VBI_INTERLEAVED 0x0800
// Is the VBI data interleaved?
#define DD_DXVIDEOPORT_FLAG_HALFLINES 0x1000
// Due to half lines, even field
// data is shifted down one line
#define DD_DXVIDEOPORT_FLAG_DISABLEAUTOFLIP 0x2000
// Overlay autoflipping is
// temporarily disabled
#define DD_DXVIDEOPORT_FLAG_SOFTWAREBOB 0x4000
// Don't use hardware bob
#define DD_DXVIDEOPORT_FLAG_REGISTERED_IRQ 0x8000
// Have added the video port VSYNC to the list of registered callbacks
#ifdef DXKERNEL_BUILD
class EDD_DXVIDEOPORT : public DDVIDEOPORTDATA
{
public:
BOOL bLost; // Videoport is lost
EDD_VIDEOPORT* peVideoPort; // Owning videoport; NULL if
// lost
DXOBJ* pDxObj_List; // List of open DXAPI objects
// for this VideoPort
EDD_DXDIRECTDRAW* peDxDirectDraw; // Owning DXAPI DirectDraw
// object
EDD_DXCAPTURE* peDxCapture; // List of capture objects
// capturing from vport
DWORD dwVideoPortID; // ddvpDesc.dwVideoPortID
FLONG flFlags; // DD_DXVIDEOPORT_FLAGs
BOOL bSoftwareAutoflip;
BOOL bSkip;
// The following fields are updated asynchronously from the VideoPort
// DPC, so be very careful when modifying them. In general, the
// device's spinlock must acquired to use the fields.
DWORD dwCurrentField; // Current field number
DWORD iCurrentVideo; // Surface index of current
// autoflip videoport video
// output
DWORD iCurrentVbi; // Surface index of current
// autoflip videoport VBI
// output
DWORD dwFieldToSkip; // Field to be skipped
// (relative to current field)
DWORD dwNextFieldToSkip; // So client can specify two
// fields w/o waiting for
// the first one to skip
DWORD dwSetStateField; // Field number at which new
// SetState is to take effect
DWORD dwSetStateState; // New SetState state
DWORD cAutoflipVideo; // Number of autoflip surfaces
// for video
DWORD cAutoflipVbi; // Number of autoflip surfaces
// for VBI data
EDD_DXSURFACE* apeDxSurfaceVideo[MAX_AUTOFLIP_BUFFERS];
// Array of video autoflip
// surfaces
EDD_DXSURFACE* apeDxSurfaceVbi[MAX_AUTOFLIP_BUFFERS];
// Array of VBI autoflip
// surfaces
PKEVENT pNotifyEvent;
HANDLE pNotifyEventHandle;
LPDDVIDEOPORTNOTIFY pNotifyBuffer;
PMDL pNotifyMdl;
};
#endif // DXKERNEL_BUILD
/*********************************Class************************************\
* class EDD_DXSURFACE
*
* The non-pageable part of the EDD_SURFACE structure, allocated
* on demand for DXAPI clients.
*
\**************************************************************************/
#define DD_DXSURFACE_FLAG_STATE_SET 0x0001
// State was explicitly set
// via DxApi
#define DD_DXSURFACE_FLAG_STATE_BOB 0x0002
// State is bob
#define DD_DXSURFACE_FLAG_STATE_WEAVE 0x0004
// State is weave
#define DD_DXSURFACE_FLAG_CAN_BOB_INTERLEAVED 0x0008
// Surface can be bobbed when
// interleaved
#define DD_DXSURFACE_FLAG_CAN_BOB_NONINTERLEAVED 0x0010
// Surface can be bobbed when
// not interleaved
#define DD_DXSURFACE_FLAG_TRANSFER 0x0020
// A busmaster was made from
// this surface
#ifdef DXKERNEL_BUILD
class EDD_DXSURFACE : public DDSURFACEDATA
{
public:
BOOL bLost; // Surface is lost
EDD_SURFACE* peSurface; // Owning surface; NULL if lost
DXOBJ* pDxObj_List; // List of open DXAPI objects
// for this surface
EDD_DXDIRECTDRAW* peDxDirectDraw; // Owning DXAPI DirectDraw
// object
EDD_DXVIDEOPORT* peDxVideoPort; // Video port associated with
// surface
FLONG flFlags;
};
#endif // DXKERNEL_BUILD
/*********************************Class************************************\
* class EDD_DXCAPTURE
*
* The non-pageable capture structure used to capture from the video port,
* allocated on demand for DXAPI clients.
*
\**************************************************************************/
#define DD_DXCAPTUREBUFF_FLAG_IN_USE 0x0001
// The buffer is currently begin used
#define DD_DXCAPTUREBUFF_FLAG_WAITING 0x0002
// The buffer is waiting to be filled
#define DD_DXCAPTUREBUFF_FLAG_FLUSH 0x0004
// The buffer has been flushed - set the event
#ifdef DXKERNEL_BUILD
typedef struct _DXCAPTUREBUFF
{
FLONG flFlags;
PMDL pBuffMDL;
PKEVENT pBuffKEvent;
PVOID lpBuffInfo;
DWORD dwClientFlags;
EDD_DXSURFACE* peDxSurface;
} DXCAPTUREBUFF;
#endif // DXKERNEL_BUILD
#define DD_DXCAPTURE_FLAG_VBI 0x0001
// Object is capturing VBI
#define DD_DXCAPTURE_FLAG_VIDEO 0x0002
// Object is capturing video
#define DXCAPTURE_MAX_CAPTURE_BUFFS 10
#ifdef DXKERNEL_BUILD
class EDD_DXCAPTURE
{
public:
BOOL bLost; // Capture object is lost
DXOBJ* pDxObj_List; // List of open DXAPI objects
// for this Capture object
FLONG flFlags; // DD_DXCAPTURE_FLAGs
DWORD dwStartLine; // Line in buffer to start
// capturing
DWORD dwEndLine; // Line in buffer to end
// capturing (inclusive)
DWORD dwCaptureEveryNFields;// 1 = capture every field,
// 2 = capture every 2nd field,
// etc.
DWORD dwCaptureCountDown; // Used internally to handle
// dwCaptureEveryNFields
DWORD dwTransferId; // ????
// The following fields are updated asynchronously from the DPC,
// so be very careful when modifying them. In general, the
// device's spinlock must acquired to use the fields.
EDD_DXVIDEOPORT* peDxVideoPort; // Owning videoport; NULL if
// lost
EDD_DXCAPTURE* peDxCaptureNext; // Next object in list of objects
// associated with vport
DWORD dwTop; // ????
DWORD dwBottom; // ????
DXCAPTUREBUFF CaptureQueue[DXCAPTURE_MAX_CAPTURE_BUFFS];
};
/*********************************Class************************************\
* class DXOBJ
*
* Non-pageable structure used to represent all objects passed out to DXAPI
* clients. There may be more than one DXOBJ instance per actual DXAPI
* object, so they're kept in a linked list.
*
* Whenever we give out an object handle via DXAPI, it's actually a pointer
* to one of these objects.
*
\**************************************************************************/
typedef enum {
DXT_INVALID,
DXT_DIRECTDRAW,
DXT_SURFACE,
DXT_VIDEOPORT,
DXT_CAPTURE,
} DXTYPE;
class DXOBJ
{
public:
DXTYPE iDxType; // DXAPI object type
LPDD_NOTIFYCALLBACK pfnClose; // Call-back context data
PVOID pContext; // for informing DXAPI
DWORD dwEvent; // client when object
// is no longer valid
DXOBJ* pDxObj_Next; // There may be more than one
// DXAPI instance per actual
// DXAPI object, so this
// points to the next instance
// for this DXAPI object
DWORD dwFlags; // DXT_ flags
PEPROCESS pepSession; // Pointer to CsrSS process of
// the session who own this
// object. (need for TS)
union {
EDD_DXDIRECTDRAW* peDxDirectDraw; // Points to owning DXAPI object
EDD_DXSURFACE* peDxSurface; // of the respective type
EDD_DXVIDEOPORT* peDxVideoPort;
EDD_DXCAPTURE* peDxCapture;
};
};
#endif // DXKERNEL_BUILD