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.
532 lines
19 KiB
532 lines
19 KiB
/******************************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__
|