2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Driver Surace Functions
5 * FILE: subsys/win32k/eng/surface.c
6 * PROGRAMERS: Jason Filby
9 * - Create a GDI bitmap with all formats, perform all drawing operations on them, render to VGA surface
10 * refer to \test\microwin\src\engine\devdraw.c for info on correct pixel plotting for various formats
18 LONG giUniqueSurface
= 0;
21 gajBitsPerFormat
[11] =
27 16, /* 4: BMF_16BPP */
28 24, /* 5: BMF_24BPP */
29 32, /* 6: BMF_32BPP */
39 BitmapFormat(ULONG cBits
, ULONG iCompression
)
46 if (cBits
<= 1) return BMF_1BPP
;
47 if (cBits
<= 4) return BMF_4BPP
;
48 if (cBits
<= 8) return BMF_8BPP
;
49 if (cBits
<= 16) return BMF_16BPP
;
50 if (cBits
<= 24) return BMF_24BPP
;
51 if (cBits
<= 32) return BMF_32BPP
;
67 SURFACE_vCleanup(PVOID ObjectBody
)
69 PSURFACE psurf
= (PSURFACE
)ObjectBody
;
70 PVOID pvBits
= psurf
->SurfObj
.pvBits
;
72 /* Check if the surface has bits */
75 /* Only bitmaps can have bits */
76 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
78 /* Check if it is a DIB section */
79 if (psurf
->hDIBSection
)
81 /* Unmap the section view */
82 EngUnmapSectionView(pvBits
, psurf
->dwOffset
, psurf
->hSecure
);
84 else if (psurf
->SurfObj
.fjBitmap
& BMF_USERMEM
)
86 /* Bitmap was allocated from usermode memory */
87 EngFreeUserMem(pvBits
);
89 else if (psurf
->SurfObj
.fjBitmap
& BMF_KMSECTION
)
91 /* Bitmap was allocated from a kernel section */
92 if (!EngFreeSectionMem(NULL
, pvBits
))
94 DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits
);
95 // Should we BugCheck here?
99 else if (psurf
->SurfObj
.fjBitmap
& BMF_POOLALLOC
)
101 /* Free a pool allocation */
109 PALETTE_ShareUnlockPalette(psurf
->ppal
);
116 SURFACE_AllocSurface(
122 _In_opt_ ULONG cjWidth
,
123 _In_opt_ PVOID pvBits
)
125 ULONG cBitsPixel
, cjBits
, cjObject
;
130 ASSERT(!pvBits
|| (iType
== STYPE_BITMAP
));
133 if ((iFormat
< BMF_1BPP
) || (iFormat
> BMF_PNG
))
135 DPRINT1("Invalid bitmap format: %lu\n", iFormat
);
139 /* Get bits per pixel from the format */
140 cBitsPixel
= gajBitsPerFormat
[iFormat
];
142 /* Are bits and a width in bytes given? */
143 if (pvBits
&& cjWidth
)
145 /* Align the width (Windows compatibility, drivers expect that) */
146 cjWidth
= WIDTH_BYTES_ALIGN32((cjWidth
<< 3) / cBitsPixel
, cBitsPixel
);
150 /* Calculate width from the bitmap width in pixels */
151 cjWidth
= WIDTH_BYTES_ALIGN32(cx
, cBitsPixel
);
154 /* Calculate the bitmap size in bytes */
155 cjBits
= cjWidth
* cy
;
157 /* Check if we need an extra large object */
158 if ((iType
== STYPE_BITMAP
) && (pvBits
== NULL
) &&
159 !(fjBitmap
& BMF_USERMEM
) && !(fjBitmap
& BMF_KMSECTION
))
161 /* Allocate an object large enough to hold the bits */
162 cjObject
= sizeof(SURFACE
) + cjBits
;
166 /* Otherwise just allocate the SURFACE structure */
167 cjObject
= sizeof(SURFACE
);
170 /* Check for arithmetic overflow */
171 if ((cjBits
< cjWidth
) || (cjObject
< sizeof(SURFACE
)))
177 /* Allocate a SURFACE object */
178 psurf
= (PSURFACE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP
, cjObject
);
184 /* Initialize the basic fields */
185 pso
= &psurf
->SurfObj
;
186 pso
->hsurf
= psurf
->BaseObject
.hHmgr
;
187 pso
->sizlBitmap
.cx
= cx
;
188 pso
->sizlBitmap
.cy
= cy
;
189 pso
->iBitmapFormat
= iFormat
;
191 pso
->fjBitmap
= (USHORT
)fjBitmap
;
192 pso
->iUniq
= InterlockedIncrement(&giUniqueSurface
);
193 pso
->cjBits
= cjBits
;
195 /* Check if we need a bitmap buffer */
196 if (iType
== STYPE_BITMAP
)
198 /* Check if we got one or if we need to allocate one */
201 /* Use the caller provided buffer */
202 pso
->pvBits
= pvBits
;
204 else if (fjBitmap
& BMF_USERMEM
)
206 /* User mode memory was requested */
207 pso
->pvBits
= EngAllocUserMem(cjBits
, 0);
209 /* Check for failure */
212 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
216 else if (fjBitmap
& BMF_KMSECTION
)
218 /* Use a kernel mode section */
219 pso
->pvBits
= EngAllocSectionMem(&pvSection
,
220 (fjBitmap
& BMF_NOZEROINIT
) ?
224 /* Check for failure */
227 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
231 /* Free the section already, but keep the mapping */
232 EngFreeSectionMem(pvSection
, NULL
);
236 /* Buffer is after the object */
237 pso
->pvBits
= psurf
+ 1;
239 /* Zero the buffer, except requested otherwise */
240 if (!(fjBitmap
& BMF_NOZEROINIT
))
242 RtlZeroMemory(pso
->pvBits
, cjBits
);
246 /* Set pvScan0 and lDelta */
247 if (fjBitmap
& BMF_TOPDOWN
)
249 /* Topdown is the normal way */
250 pso
->pvScan0
= pso
->pvBits
;
251 pso
->lDelta
= cjWidth
;
255 /* Inversed bitmap (bottom up) */
256 pso
->pvScan0
= ((PCHAR
)pso
->pvBits
+ pso
->cjBits
- cjWidth
);
257 pso
->lDelta
= -(LONG
)cjWidth
;
262 /* There are no bitmap bits */
263 pso
->pvScan0
= pso
->pvBits
= NULL
;
267 /* Assign a default palette and increment its reference count */
268 SURFACE_vSetPalette(psurf
, appalSurfaceDefault
[iFormat
]);
280 _In_opt_ PVOID pvBits
)
285 /* Allocate a surface */
286 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
,
295 DPRINT1("SURFACE_AllocSurface failed.\n");
299 /* Get the handle for the bitmap */
300 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
302 /* Set public ownership */
303 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
305 /* Unlock the surface and return */
306 SURFACE_UnlockSurface(psurf
);
315 EngCreateDeviceBitmap(
323 /* Allocate a surface */
324 psurf
= SURFACE_AllocSurface(STYPE_DEVBITMAP
,
333 DPRINT1("SURFACE_AllocSurface failed.\n");
337 /* Set the device handle */
338 psurf
->SurfObj
.dhsurf
= dhsurf
;
340 /* Set public ownership */
341 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
343 /* Get the handle for the bitmap */
344 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
346 /* Unlock the surface and return */
347 SURFACE_UnlockSurface(psurf
);
353 EngCreateDeviceSurface(
361 /* Allocate a surface */
362 psurf
= SURFACE_AllocSurface(STYPE_DEVICE
,
371 DPRINT1("SURFACE_AllocSurface failed.\n");
375 /* Set the device handle */
376 psurf
->SurfObj
.dhsurf
= dhsurf
;
378 /* Set public ownership */
379 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
381 /* Get the handle for the surface */
382 hsurf
= psurf
->SurfObj
.hsurf
;
384 /* Unlock the surface and return */
385 SURFACE_UnlockSurface(psurf
);
401 ppdev
= (PDEVOBJ
*)hdev
;
403 /* Lock the surface */
404 psurf
= SURFACE_ShareLockSurface(hsurf
);
409 pso
= &psurf
->SurfObj
;
411 /* Associate the hdev */
413 pso
->dhpdev
= ppdev
->dhpdev
;
415 /* Hook up specified functions */
416 psurf
->flags
&= ~HOOK_FLAGS
;
417 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
419 /* Assign the PDEV's palette */
420 ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
421 SURFACE_vSetPalette(psurf
, ppal
);
422 PALETTE_ShareUnlockPalette(ppal
);
424 SURFACE_ShareUnlockSurface(psurf
);
435 _In_ FLONG flSurface
,
439 _Reserved_ VOID
*pvReserved
)
446 psurf
= SURFACE_ShareLockSurface(hsurf
);
452 ppdev
= (PDEVOBJ
*)hdev
;
453 pso
= &psurf
->SurfObj
;
454 pso
->dhsurf
= dhsurf
;
455 pso
->lDelta
= lDelta
;
456 pso
->pvScan0
= pvScan0
;
458 /* Associate the hdev */
460 pso
->dhpdev
= ppdev
->dhpdev
;
462 /* Hook up specified functions */
463 psurf
->flags
&= ~HOOK_FLAGS
;
464 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
466 /* Assign the PDEV's palette */
467 ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
468 SURFACE_vSetPalette(psurf
, ppal
);
469 PALETTE_ShareUnlockPalette(ppal
);
471 SURFACE_ShareUnlockSurface(psurf
);
480 _In_ _Post_ptr_invalid_ HSURF hsurf
)
484 psurf
= SURFACE_ShareLockSurface(hsurf
);
487 DPRINT1("Could not reference surface to delete\n");
491 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
504 return FillSolid(pso
, prcl
, iColor
);
511 NtGdiEngLockSurface(IN HSURF hsurf
)
513 return EngLockSurface(hsurf
);
522 SURFACE
*psurf
= SURFACE_ShareLockSurface(hsurf
);
524 return psurf
? &psurf
->SurfObj
: NULL
;
529 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
538 _In_ _Post_ptr_invalid_ SURFOBJ
*pso
)
542 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
543 SURFACE_ShareUnlockSurface(psurf
);