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_Cleanup(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
);
118 SURFACE_AllocSurface(
124 _In_opt_ ULONG cjWidth
,
125 _In_opt_ PVOID pvBits
)
127 ULONG cBitsPixel
, cjBits
, cjObject
;
132 ASSERT(!pvBits
|| (iType
== STYPE_BITMAP
));
135 if ((iFormat
< BMF_1BPP
) || (iFormat
> BMF_PNG
))
137 DPRINT1("Invalid bitmap format: %lu\n", iFormat
);
141 /* Get bits per pixel from the format */
142 cBitsPixel
= gajBitsPerFormat
[iFormat
];
144 /* Are bits and a width in bytes given? */
145 if (pvBits
&& cjWidth
)
147 /* Align the width (Windows compatibility, drivers expect that) */
148 cjWidth
= WIDTH_BYTES_ALIGN32((cjWidth
<< 3) / cBitsPixel
, cBitsPixel
);
152 /* Calculate width from the bitmap width in pixels */
153 cjWidth
= WIDTH_BYTES_ALIGN32(cx
, cBitsPixel
);
156 /* Calculate the bitmap size in bytes */
157 cjBits
= cjWidth
* cy
;
159 /* Check if we need an extra large object */
160 if ((iType
== STYPE_BITMAP
) && (pvBits
== NULL
) &&
161 !(fjBitmap
& BMF_USERMEM
) && !(fjBitmap
& BMF_KMSECTION
))
163 /* Allocate an object large enough to hold the bits */
164 cjObject
= sizeof(SURFACE
) + cjBits
;
168 /* Otherwise just allocate the SURFACE structure */
169 cjObject
= sizeof(SURFACE
);
172 /* Check for arithmetic overflow */
173 if ((cjBits
< cjWidth
) || (cjObject
< sizeof(SURFACE
)))
179 /* Allocate a SURFACE object */
180 psurf
= (PSURFACE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP
, cjObject
);
186 /* Initialize the basic fields */
187 pso
= &psurf
->SurfObj
;
188 pso
->hsurf
= psurf
->BaseObject
.hHmgr
;
189 pso
->sizlBitmap
.cx
= cx
;
190 pso
->sizlBitmap
.cy
= cy
;
191 pso
->iBitmapFormat
= iFormat
;
193 pso
->fjBitmap
= (USHORT
)fjBitmap
;
194 pso
->iUniq
= InterlockedIncrement(&giUniqueSurface
);
195 pso
->cjBits
= cjBits
;
197 /* Check if we need a bitmap buffer */
198 if (iType
== STYPE_BITMAP
)
200 /* Check if we got one or if we need to allocate one */
203 /* Use the caller provided buffer */
204 pso
->pvBits
= pvBits
;
206 else if (fjBitmap
& BMF_USERMEM
)
208 /* User mode memory was requested */
209 pso
->pvBits
= EngAllocUserMem(cjBits
, 0);
211 /* Check for failure */
214 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
218 else if (fjBitmap
& BMF_KMSECTION
)
220 /* Use a kernel mode section */
221 pso
->pvBits
= EngAllocSectionMem(&pvSection
,
222 (fjBitmap
& BMF_NOZEROINIT
) ?
226 /* Check for failure */
229 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
233 /* Free the section already, but keep the mapping */
234 EngFreeSectionMem(pvSection
, NULL
);
238 /* Buffer is after the object */
239 pso
->pvBits
= psurf
+ 1;
241 /* Zero the buffer, except requested otherwise */
242 if (!(fjBitmap
& BMF_NOZEROINIT
))
244 RtlZeroMemory(pso
->pvBits
, cjBits
);
248 /* Set pvScan0 and lDelta */
249 if (fjBitmap
& BMF_TOPDOWN
)
251 /* Topdown is the normal way */
252 pso
->pvScan0
= pso
->pvBits
;
253 pso
->lDelta
= cjWidth
;
257 /* Inversed bitmap (bottom up) */
258 pso
->pvScan0
= ((PCHAR
)pso
->pvBits
+ pso
->cjBits
- cjWidth
);
259 pso
->lDelta
= -(LONG
)cjWidth
;
264 /* There are no bitmap bits */
265 pso
->pvScan0
= pso
->pvBits
= NULL
;
269 /* Assign a default palette and increment its reference count */
270 SURFACE_vSetPalette(psurf
, appalSurfaceDefault
[iFormat
]);
287 /* Allocate a surface */
288 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
,
297 DPRINT1("SURFACE_AllocSurface failed.\n");
301 /* Get the handle for the bitmap */
302 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
304 /* Set public ownership */
305 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
307 /* Unlock the surface and return */
308 SURFACE_UnlockSurface(psurf
);
317 EngCreateDeviceBitmap(
325 /* Allocate a surface */
326 psurf
= SURFACE_AllocSurface(STYPE_DEVBITMAP
,
335 DPRINT1("SURFACE_AllocSurface failed.\n");
339 /* Set the device handle */
340 psurf
->SurfObj
.dhsurf
= dhsurf
;
342 /* Get the handle for the bitmap */
343 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
345 /* Set public ownership */
346 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
348 /* Unlock the surface and return */
349 SURFACE_UnlockSurface(psurf
);
355 EngCreateDeviceSurface(
363 /* Allocate a surface */
364 psurf
= SURFACE_AllocSurface(STYPE_DEVICE
,
373 DPRINT1("SURFACE_AllocSurface failed.\n");
377 /* Set the device handle */
378 psurf
->SurfObj
.dhsurf
= dhsurf
;
380 /* Get the handle for the surface */
381 hsurf
= psurf
->SurfObj
.hsurf
;
383 /* Set public ownership */
384 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
386 /* Unlock the surface and return */
387 SURFACE_UnlockSurface(psurf
);
403 ppdev
= (PDEVOBJ
*)hdev
;
405 /* Lock the surface */
406 psurf
= SURFACE_ShareLockSurface(hsurf
);
411 pso
= &psurf
->SurfObj
;
413 /* Associate the hdev */
415 pso
->dhpdev
= ppdev
->dhpdev
;
417 /* Hook up specified functions */
418 psurf
->flags
&= ~HOOK_FLAGS
;
419 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
421 /* Assign the PDEV's palette */
422 ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
423 SURFACE_vSetPalette(psurf
, ppal
);
424 PALETTE_ShareUnlockPalette(ppal
);
426 SURFACE_ShareUnlockSurface(psurf
);
437 _In_ FLONG flSurface
,
441 _Reserved_ VOID
*pvReserved
)
448 psurf
= SURFACE_ShareLockSurface(hsurf
);
454 ppdev
= (PDEVOBJ
*)hdev
;
455 pso
= &psurf
->SurfObj
;
456 pso
->dhsurf
= dhsurf
;
457 pso
->lDelta
= lDelta
;
458 pso
->pvScan0
= pvScan0
;
460 /* Associate the hdev */
462 pso
->dhpdev
= ppdev
->dhpdev
;
464 /* Hook up specified functions */
465 psurf
->flags
&= ~HOOK_FLAGS
;
466 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
468 /* Assign the PDEV's palette */
469 ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
470 SURFACE_vSetPalette(psurf
, ppal
);
471 PALETTE_ShareUnlockPalette(ppal
);
473 SURFACE_ShareUnlockSurface(psurf
);
486 psurf
= SURFACE_ShareLockSurface(hsurf
);
489 DPRINT1("Could not reference surface to delete\n");
493 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
506 return FillSolid(pso
, prcl
, iColor
);
513 NtGdiEngLockSurface(IN HSURF hsurf
)
515 return EngLockSurface(hsurf
);
524 SURFACE
*psurf
= SURFACE_ShareLockSurface(hsurf
);
526 return psurf
? &psurf
->SurfObj
: NULL
;
531 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
544 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
545 SURFACE_ShareUnlockSurface(psurf
);