10 // Gdi Batch Flush support functions.
16 // based on IntEngEnter from eng/engmisc.c
20 DoDeviceSync( SURFOBJ
*Surface
, PRECTL Rect
, FLONG fl
)
22 PGDIDEVICE Device
= (GDIDEVICE
*)Surface
->hdev
;
23 // No punting and "Handle to a surface, provided that the surface is device-managed.
24 // Otherwise, dhsurf is zero".
25 if (!(Device
->flFlags
& PDEV_DRIVER_PUNTED_CALL
) && (Surface
->dhsurf
))
27 if (Device
->DriverFunctions
.SynchronizeSurface
)
28 return Device
->DriverFunctions
.SynchronizeSurface(Surface
, Rect
, fl
);
31 if (Device
->DriverFunctions
.Synchronize
)
32 return Device
->DriverFunctions
.Synchronize(Surface
->dhpdev
, Rect
);
40 SynchonizeDriver(FLONG Flags
)
45 if (Flags
& GCAPS2_SYNCFLUSH
)
46 Flags
= DSS_FLUSH_EVENT
;
47 if (Flags
& GCAPS2_SYNCTIMER
)
48 Flags
= DSS_TIMER_EVENT
;
50 Device
= IntEnumHDev();
52 SurfObj
= EngLockSurface((HSURF
)Device
->Handle
);
54 DoDeviceSync( SurfObj
, NULL
, Flags
);
55 EngUnlockSurface(SurfObj
);
64 GdiFlushUserBatch(HDC hDC
, PGDIBATCHHDR pHdr
)
67 PDC_ATTR Dc_Attr
= NULL
;
68 if (hDC
&& !IsObjectDead(hDC
))
73 Dc_Attr
= dc
->pDc_Attr
;
74 if (!Dc_Attr
) Dc_Attr
= &dc
->Dc_Attr
;
77 // The thread is approaching the end of sunset.
80 case GdiBCPatBlt
: // Highest pri first!
88 case GdiBCSetBrushOrg
:
90 PGDIBSSETBRHORG pgSBO
;
92 pgSBO
= (PGDIBSSETBRHORG
) pHdr
;
93 Dc_Attr
->ptlBrushOrigin
= pgSBO
->ptlBrushOrigin
;
96 case GdiBCExtSelClipRgn
:
102 pgO
= (PGDIBSOBJECT
) pHdr
;
103 if(NT_SUCCESS(TextIntRealizeFont((HFONT
) pgO
->hgdiobj
)))
104 Dc_Attr
->hlfntNew
= (HFONT
) pgO
->hgdiobj
;
109 PGDIBSOBJECT pgO
= (PGDIBSOBJECT
) pHdr
;
110 NtGdiDeleteObject( pgO
->hgdiobj
);
116 if (dc
) DC_UnlockDc(dc
);
117 return pHdr
->Size
; // Return the full size of the structure.
123 * Flushes the calling thread's current batch.
129 SynchonizeDriver(GCAPS2_SYNCFLUSH
);
133 * NtGdiFlushUserBatch
135 * Callback for thread batch flush routine.
137 * Think small & fast!
141 NtGdiFlushUserBatch(VOID
)
143 PTEB pTeb
= NtCurrentTeb();
144 ULONG GdiBatchCount
= pTeb
->GdiBatchCount
;
146 if( (GdiBatchCount
> 0) && (GdiBatchCount
<= (GDIBATCHBUFSIZE
/4)))
148 HDC hDC
= (HDC
) pTeb
->GdiTebBatch
.HDC
;
150 // If hDC is zero and the buffer fills up with delete objects we need to run
151 // anyway. So, hard code to the system batch limit.
153 if ((hDC
) || ((!hDC
) && (GdiBatchCount
>= GDI_BATCH_LIMIT
)))
155 PULONG pHdr
= &pTeb
->GdiTebBatch
.Buffer
[0];
156 // No need to init anything, just go!
157 for (; GdiBatchCount
> 0; GdiBatchCount
--)
159 // Process Gdi Batch!
160 pHdr
+= GdiFlushUserBatch( hDC
, (PGDIBATCHHDR
) pHdr
);
162 // Exit and clear out for the next round.
163 pTeb
->GdiTebBatch
.Offset
= 0;
164 pTeb
->GdiBatchCount
= 0;
165 pTeb
->GdiTebBatch
.HDC
= 0;
168 return STATUS_SUCCESS
;