/******************************Module*Header**********************************\ * * ******************* * * GDI SAMPLE CODE * * ******************* * * Module Name: gdi.h * * Contains all the gdi related stuff * * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved. \*****************************************************************************/ #ifndef __GDI__H__ #define __GDI__H__ typedef struct _PDev PDev; #define CLIP_LIMIT 50 // We'll take 800 bytes of stack space typedef struct _ClipEnum { LONG c; RECTL arcl[CLIP_LIMIT]; // Space for enumerating complex clipping } ClipEnum; /* ce, pce */ // // Text stuff. Specifies foreground and background colours for faking a 1bpp // XLATEOBJ // typedef struct _XlateColors { ULONG iBackColor; ULONG iForeColor; } XlateColors; #define SF_VM 0x01 // kept in video memory #define SF_SM 0x02 // kept in system memory #define SF_AGP 0x04 // kept in AGP memory #define SF_LIST 0x08 // in surface list #define SF_ALLOCATED 0x10 // surface memory allocated by us #define SF_DIRECTDRAW 0x20 // wrapper of a Direct Draw surface typedef ULONG SurfFlags; typedef struct _Surf { SurfFlags flags; // Type (video memory or system memory) PDev* ppdev; // Need this for deleting the bitmap struct _Surf* psurfNext; struct _Surf* psurfPrev; ULONG cBlt; // Counts down the number of blts necessary // at the current uniqueness before we'll // consider putting the DIB back into // off-screen memory ULONG iUniq; // Tells us whether there have been any // heap 'free's since the last time we // looked at LONG cx; // Bitmap width in pixels LONG cy; // Bitmap height in pixels union { ULONG ulByteOffset; // Offset from start of video memory if // DT_VM VOID* pvScan0; // pointer to system memory if DT_SM }; LONG lDelta; // Stride in bytes for this bitmap VIDEOMEMORY* pvmHeap; // DirectDraw heap this was allocated from HSURF hsurf; // Handle to associated GDI surface (if any) // this DIB // New fields to support linear heap allocation of surface // Only valid if dt == DT_VM ULONG ulPackedPP; // padcked partial products needed by // Permedia hardware for given surface // lDelta ULONG ulPixOffset; // Pixel Offset from start of video memory ULONG ulPixDelta; // stride in pixels ULONG ulChecksum; } Surf; // dsurf, pdsurf #define NUM_BUFFER_POINTS 96 // Maximum number of points in a path // for which we'll attempt to join // all the path records so that the // path may still be drawn by FastFill #define FIX_SHIFT 4L #define FIX_MASK (- (1 << FIX_SHIFT)) // // Maximum number of rects we'll fill per call to the fill code // #define MAX_PATH_RECTS 50 #define RECT_BYTES (MAX_PATH_RECTS * sizeof(RECTL)) #define EDGE_BYTES (TMP_BUFFER_SIZE - RECT_BYTES) #define MAX_EDGES (EDGE_BYTES/sizeof(EDGE)) #define RIGHT 0 #define LEFT 1 #define NEARLY_ONE 0x0000FFFF // // Describe a single non-horizontal edge of a path to fill. // typedef struct _EDGE { PVOID pNext; INT iScansLeft; INT X; INT Y; INT iErrorTerm; INT iErrorAdjustUp; INT iErrorAdjustDown; INT iXWhole; INT iXDirection; INT iWindingDirection; } EDGE, *PEDGE; typedef struct _EDGEDATA { LONG lCurrentXPos; // Current x position LONG lXAdvance; // Number of pixels to advance x on each scan LONG lError; // Current DDA error LONG lErrorUp; // DDA error increment on each scan LONG lErrorDown; // DDA error adjustment POINTFIX* pptfx; // Points to start of current edge LONG lPtfxDelta; // Delta (in bytes) from pptfx to next point LONG lNumOfScanToGo; // Number of scans to go for this edge } EDGEDATA; // Ed, pEd // // // The x86 C compiler insists on making a divide and modulus operation // into two DIVs, when it can in fact be done in one. So we use this // macro. // // Note: QUOTIENT_REMAINDER implicitly takes unsigned arguments. #if defined(i386) #define QUOTIENT_REMAINDER(ulNumerator, ulDenominator, ulQuotient, ulRemainder) \ { \ __asm mov eax, ulNumerator \ __asm sub edx, edx \ __asm div ulDenominator \ __asm mov ulQuotient, eax \ __asm mov ulRemainder, edx \ } #else #define QUOTIENT_REMAINDER(ulNumerator, ulDenominator, ulQuotient, ulRemainder) \ { \ ulQuotient = (ULONG) ulNumerator / (ULONG) ulDenominator; \ ulRemainder = (ULONG) ulNumerator % (ULONG) ulDenominator; \ } #endif // // Rendering constant definition // #define __RENDER_TEXTURE_ENABLE (1 << 13) #define __FX_TEXREADMODE_SWRAP_REPEAT (1 << 1) #define __FX_TEXREADMODE_TWRAP_REPEAT (1 << 3) #define __FX_TEXREADMODE_8HIGH (3 << 13) #define __FX_TEXREADMODE_8WIDE (3 << 9) #define __FX_TEXREADMODE_2048HIGH (11 << 13) #define __FX_TEXREADMODE_2048WIDE (11 << 9) #define __FX_TEXTUREREADMODE_PACKED_DATA (1 << 24) #define __FX_8x8REPEAT_TEXTUREREADMODE ( __PERMEDIA_ENABLE \ | __FX_TEXREADMODE_TWRAP_REPEAT \ | __FX_TEXREADMODE_SWRAP_REPEAT \ | __FX_TEXREADMODE_8HIGH \ | __FX_TEXREADMODE_8WIDE) #define __FX_TEXTUREDATAFORMAT_32BIT_RGBA 0x00 #define __FX_TEXTUREDATAFORMAT_32BIT 0x10 #define __FX_TEXTUREDATAFORMAT_8BIT 0xe #define __FX_TEXTUREDATAFORMAT_16BIT 0x11 #define __FX_TEXTUREDATAFORMAT_4BIT 0xf #define __P2_TEXTURE_DATAFORMAT_FLIP (1 << 9) #define __FX_TEXLUTMODE_DIRECT_ENTRY (1 << 1) #define __FX_TEXLUTMODE_4PIXELS_PER_ENTRY (2 << 10) //log2 #define __FX_TEXLUTMODE_2PIXELS_PER_ENTRY (1 << 10) //log2 #define __FX_TEXLUTMODE_1PIXEL_PER_ENTRY 0 //log2 #define STRETCH_MAX_EXTENT 32767 // //-----------------------Function***Prototypes-------------------------------- // // Low-level blt function prototypes // //---------------------------------------------------------------------------- typedef struct _GFNPB { VOID (*pgfn)(struct _GFNPB *); // pointer to graphics function PDev * ppdev; // driver ppdev Surf * psurfDst; // destination surface RECTL * prclDst; // original unclipped destination rectangle Surf * psurfSrc; // source surface RECTL * prclSrc; // original unclipped source rectangle POINTL * pptlSrc; // original unclipped source point // NOTE: pdsurfSrc must be null if // there is no source. If there is // a source either (pptlSrc must be // valid) or (pptlSrc is NULL and prclSrc // is valid). RECTL * pRects; // rectangle list LONG lNumRects; // number of rectangles in list ULONG colorKey; // colorKey for transparent operations ULONG solidColor; // solid color used in fills RBrush * prbrush; // pointer to brush POINTL * pptlBrush; // brush origin CLIPOBJ * pco; // clipping object XLATEOBJ * pxlo; // color translatoin object POINTL * pptlMask; // original uncliped mask origin ULONG ulRop4; // original rop4 UCHAR ucAlpha; // alpha value for constant blends TRIVERTEX * ptvrt; // verticies used for gradient fills ULONG ulNumTvrt; // number of verticies PVOID pvMesh; // connectivity for gradient fills ULONG ulNumMesh; // number of connectivity elements ULONG ulMode; // drawing mode SURFOBJ * psoSrc; // GDI managed surface source SURFOBJ * psoDst; // GDI managed surface destination } GFNPB; long flt_to_fix_1_30(float f); BOOL bConstructGET(EDGE* pGETHead, EDGE* pFreeEdges, PATHOBJ* ppo, PATHDATA* pd, BOOL bMore, RECTL* pClipRect); EDGE* pAddEdgeToGET(EDGE* pGETHead, EDGE* pFreeEdge, POINTFIX* ppfxEdgeStart, POINTFIX* ppfxEdgeEnd, RECTL* pClipRect); void vAdjustErrorTerm(INT* pErrorTerm, INT iErrorAdjustUp, INT iErrorAdjustDown, INT yJump, INT* pXStart, INT iXDirection); VOID vAdvanceAETEdges(EDGE* pAETHead); VOID vMoveNewEdges(EDGE* pGETHead, EDGE* pAETHead, INT iCurrentY); VOID vXSortAETEdges(EDGE* pAETHead); // // Prototypes for lower level rendering functions // BOOL bFillPolygon(PDev* ppdev, Surf* pSurfDst, LONG lEdges, POINTFIX* pptfxFirst, ULONG ulSolidColor, ULONG ulRop4, CLIPOBJ* pco, RBrush* prb, POINTL* pptlBrush); BOOL bFillSpans(PDev* ppdev, Surf* pSurfDst, LONG lEdges, POINTFIX* pptfxFirst, POINTFIX* pptfxTop, POINTFIX* pptfxLast, ULONG ulSolidColor, ULONG ulRop4, CLIPOBJ* pco, RBrush* prb, POINTL* pptlBrush); BOOL bInitializeStrips(PDev* ppdev, ULONG iSolidColor, DWORD logicop, RECTL* prclClip); void vAlphaBlend(GFNPB * ppb); void vAlphaBlendDownload(GFNPB * ppb); void vConstantAlphaBlend(GFNPB * ppb); void vConstantAlphaBlendDownload(GFNPB * ppb); void vCopyBlt(GFNPB * ppb); void vCopyBltNative(GFNPB * ppb); void vGradientFillRect(GFNPB * ppb); void vGradientFillTri(GFNPB * ppb); void vImageDownload(GFNPB * ppb); void vInvert(GFNPB * ppb); void vMonoDownload(GFNPB * ppb); void vMonoOffset(GFNPB * ppb); void vMonoPatFill(GFNPB * ppb); void vPatFill(GFNPB * ppb); void vPatternFillRects(GFNPB * ppb); void vPatRealize(GFNPB * ppb); void vResetStrips(PDev* ppdev); void vRop2Blt(GFNPB * ppb); void vSolidFill(GFNPB * ppb); void vSolidFillWithRop(GFNPB * ppb); void vTransparentBlt(GFNPB * ppb); // // Text stuff // BOOL bEnableText(PDev* ppdev); VOID vDisableText(PDev* ppdev); VOID vAssertModeText(PDev* ppdev, BOOL bEnable); // // Palette stuff // BOOL bEnablePalette(PDev* ppdev); BOOL bInitializePalette(PDev* ppdev, DEVINFO* pdi); VOID vDisablePalette(PDev* ppdev); VOID vUninitializePalette(PDev* ppdev); // // Upload and download functions // VOID vDownloadNative(GFNPB* ppb); VOID vUploadNative(GFNPB* ppb); // // StretchBlt stuff // DWORD dwGetPixelSize(ULONG ulBitmapFormat, DWORD* pdwFormatBits, DWORD* pdwFormatExtention); BOOL bStretchInit(SURFOBJ* psoDst, SURFOBJ* psoSrc); VOID vStretchBlt(SURFOBJ* psoDst, SURFOBJ* psoSrc, RECTL* rDest, RECTL* rSrc, RECTL* prclClip); VOID vStretchReset(PDev* ppdev); // // Work in progress // VOID vCheckGdiContext(PPDev ppdev); VOID vOldStyleDMA(PPDev ppdev); VOID vNewStyleDMA(PPDev ppdev); // Input buffer access methods // // InputBufferStart/InputBufferContinue/InputBufferCommit // // This method is used when the caller does not know // the upper limit of the amount of space that needs to be reserved // or needs to reserve space that exceeds that maximum allowed to // be reserved MAX_FIFO_RESERVATION. // // InputBufferStart() is used to get a pointer to the first available entry in // the input fifo, a pointer to the end of the reservation and // a pointer to the end of the usable area of the buffer. // // InputBufferContinue() is called to extend the current reservation. // // InputBufferCommit() is called when the caller is done using the reserved space. // // Please see textout.c for an example usage of these methods. // // InputBufferReserve/InputBufferCommit // // This method is used when the caller needs to make only one // reservation of some small known quantity. // // InputBufferReserve() is called to establish the reservation. // // InputBufferCommit() is called when the caller is done using the reserved space. // // Please see textout.c for the usage of InputBufferReserve/InputBufferCommit. // // A caller is free to use these access methods at any time. Once either // InputBufferStart or InputBufferReserve is called, the caller must pair the // call with either a InputBufferFinish or a InputBufferCommit before making // another reservation. // // A caller is free to use either of these methods at any time. // // Before calling any of the CPermedia class access methods, the caller // must call InputBufferFlush (see below). Because of this, a caller must // call InputBufferFlush or InputBufferExecute before returning to GDI. // // When the caller is done and wishes to initial the transmission of what // has been placed in the input fifo, the caller can call InputBufferExecute // (see below). // // InputBufferFlush // // InputBufferFlush is a neccessary evil only as long as these macros are not // part of the official input buffer access schemes. Flush is really // the means we sync up our copy of the input buffer state to the // CPermedia class. If these methods were instead part of the fundamental // input fifo mechanism, then we could do away with the need for Flush. // // InputBufferExecute // // Flush is a neccessary evil only as long as these macros are not // part of the official input buffer access schemes. If and when these // new access schemes are made part of the official input fifo buffer // mechanism, then it can be replaced by that mechanism's input fifo // execute method. // // // InputBufferMakeSpace // // This is a private call and no one should find need to call it directly. // // // Other Notes: // // We will play with making the access routines inline functions instead // of macros taking a look at the code generated. If acceptable, // these macros may turn into function calls in the non-Debug build. // // The InputBufferStart/InputBufferContinue mechansism keeps state on the stack // to avoid the dereferences to ppdev freeing up a register in cases where ppdev // references are not needed in the inner loop that contains InputBufferContinue. // // MAX_IN_FIFO_RESERVATION should be bumped up considerably when we add an // emulation buffer for the non-DMA case #define MAX_INPUT_BUFFER_RESERVATION (INPUT_BUFFER_SIZE>>3) // in longs #if DBG extern void InputBufferStart( PPDev ppdev, ULONG ulLongs, PULONG* ppulBuffer, PULONG* ppulBufferEnd, PULONG* ppulReservationEnd); extern void InputBufferContinue( PPDev ppdev, ULONG ulLongs, PULONG* ppulBuffer, PULONG* ppulBufferEnd, PULONG* ppulReservationEnd); extern void InputBufferReserve( PPDev ppdev, ULONG ulLongs, PULONG* ppulBuffer); extern void InputBufferCommit( PPDev ppdev, PULONG pulBuffer); #else #define InputBufferStart(ppdev, ulLongs, ppulBuffer, ppulBufferEnd, ppulReservationEnd) \ { \ *(ppulBuffer) = ppdev->pulInFifoPtr; \ *(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \ *(ppulBufferEnd) = ppdev->pulInFifoEnd; \ if(*(ppulReservationEnd) > *(ppulBufferEnd)) \ { \ InputBufferSwap(ppdev); \ *(ppulBuffer) = ppdev->pulInFifoPtr; \ *(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \ *(ppulBufferEnd) = ppdev->pulInFifoEnd; \ } \ } #define InputBufferContinue(ppdev, ulLongs, ppulBuffer, ppulBufferEnd, ppulReservationEnd) \ { \ *(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \ if(*(ppulReservationEnd) > *(ppulBufferEnd)) \ { \ ppdev->pulInFifoPtr = *(ppulBuffer); \ InputBufferSwap(ppdev); \ *(ppulBuffer) = ppdev->pulInFifoPtr; \ *(ppulReservationEnd) = *(ppulBuffer) + ulLongs; \ *(ppulBufferEnd) = ppdev->pulInFifoEnd; \ } \ } #define InputBufferReserve(ppdev, ulLongs, ppulBuffer) \ { \ if(ppdev->pulInFifoPtr + ulLongs > ppdev->pulInFifoEnd) \ { \ InputBufferSwap(ppdev); \ } \ *(ppulBuffer) = ppdev->pulInFifoPtr; \ } #define InputBufferCommit(ppdev, pulBuffer) ppdev->pulInFifoPtr = pulBuffer #endif void FASTCALL InputBufferFlush(PPDev ppdev); void FASTCALL InputBufferSwap(PPDev ppdev); void InputBufferSync(PPDev ppdev); extern BOOL bGdiContext; #endif // __GDI__H__