/******************************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