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 ULONG giUniqueSurface
= 0;
21 gajBitsPerFormat
[11] =
27 16, /* 4: BMF_16BPP */
28 24, /* 5: BMF_24BPP */
29 32, /* 6: BMF_32BPP */
37 ULONG FASTCALL
BitmapFormat(ULONG cBits
, ULONG iCompression
)
44 if (cBits
<= 1) return BMF_1BPP
;
45 if (cBits
<= 4) return BMF_4BPP
;
46 if (cBits
<= 8) return BMF_8BPP
;
47 if (cBits
<= 16) return BMF_16BPP
;
48 if (cBits
<= 24) return BMF_24BPP
;
49 if (cBits
<= 32) return BMF_32BPP
;
65 SURFACE_Cleanup(PVOID ObjectBody
)
67 PSURFACE psurf
= (PSURFACE
)ObjectBody
;
68 PVOID pvBits
= psurf
->SurfObj
.pvBits
;
71 /* Check if the surface has bits */
74 /* Only bitmaps can have bits */
75 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
77 /* Check if it is a DIB section */
78 if (psurf
->hDIBSection
)
80 /* Unsecure the memory */
81 EngUnsecureMem(psurf
->hSecure
);
83 /* Calculate the real start of the section */
84 pvBits
= (PVOID
)((ULONG_PTR
)pvBits
- psurf
->dwOffset
);
86 /* Unmap the section */
87 Status
= MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits
);
88 if (!NT_SUCCESS(Status
))
90 DPRINT1("Could not unmap section view!\n");
91 // Should we BugCheck here?
95 else if (psurf
->SurfObj
.fjBitmap
& BMF_USERMEM
)
97 /* Bitmap was allocated from usermode memory */
98 EngFreeUserMem(pvBits
);
100 else if (psurf
->SurfObj
.fjBitmap
& BMF_KMSECTION
)
102 /* Bitmap was allocated from a kernel section */
103 if (!EngFreeSectionMem(NULL
, pvBits
))
105 DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits
);
106 // Should we BugCheck here?
110 else if (psurf
->SurfObj
.fjBitmap
& BMF_RLE_HACK
)
112 /* HACK: Free RLE decompressed bits */
117 /* There should be nothing to free */
118 ASSERT(psurf
->SurfObj
.fjBitmap
& BMF_DONT_FREE
);
125 PALETTE_ShareUnlockPalette(psurf
->ppal
);
134 SURFACE_AllocSurface(
144 if (iFormat
< BMF_1BPP
|| iFormat
> BMF_PNG
)
146 DPRINT1("Invalid bitmap format: %ld\n", iFormat
);
150 /* Allocate a SURFACE object */
151 psurf
= (PSURFACE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP
, sizeof(SURFACE
));
155 /* Initialize the basic fields */
156 pso
= &psurf
->SurfObj
;
157 pso
->hsurf
= psurf
->BaseObject
.hHmgr
;
158 pso
->sizlBitmap
.cx
= cx
;
159 pso
->sizlBitmap
.cy
= cy
;
160 pso
->iBitmapFormat
= iFormat
;
162 pso
->iUniq
= InterlockedIncrement((PLONG
)&giUniqueSurface
);
164 /* Assign a default palette and increment its reference count */
165 psurf
->ppal
= appalSurfaceDefault
[iFormat
];
166 GDIOBJ_vReferenceObjectByPointer(&psurf
->ppal
->BaseObject
);
174 SURFACE_bSetBitmapBits(
178 IN PVOID pvBits OPTIONAL
)
180 SURFOBJ
*pso
= &psurf
->SurfObj
;
184 /* Only bitmaps can have bits */
185 ASSERT(psurf
->SurfObj
.iType
== STYPE_BITMAP
);
187 /* Get bits per pixel from the format */
188 cBitsPixel
= gajBitsPerFormat
[pso
->iBitmapFormat
];
190 /* Is a width in bytes given? */
193 /* Align the width (Windows compatibility, drivers expect that) */
194 ulWidth
= WIDTH_BYTES_ALIGN32((ulWidth
<< 3) / cBitsPixel
, cBitsPixel
);
198 /* Calculate width from the bitmap width in pixels */
199 ulWidth
= WIDTH_BYTES_ALIGN32(pso
->sizlBitmap
.cx
, cBitsPixel
);
202 /* Calculate the bitmap size in bytes */
203 pso
->cjBits
= ulWidth
* pso
->sizlBitmap
.cy
;
205 /* Did the caller provide bits? */
208 /* Yes, so let him free it */
209 fjBitmap
|= BMF_DONT_FREE
;
211 else if (pso
->cjBits
)
213 /* We must allocate memory, check what kind */
214 if (fjBitmap
& BMF_USERMEM
)
216 /* User mode memory was requested */
217 pvBits
= EngAllocUserMem(pso
->cjBits
, 0);
221 /* Use a kernel mode section */
222 fjBitmap
|= BMF_KMSECTION
;
223 pvBits
= EngAllocSectionMem(&pvSection
,
224 (fjBitmap
& BMF_NOZEROINIT
) ?
226 pso
->cjBits
, TAG_DIB
);
228 /* Free the section already, but keep the mapping */
229 if (pvBits
) EngFreeSectionMem(pvSection
, NULL
);
232 /* Check for failure */
233 if (!pvBits
) return FALSE
;
236 /* Set pvBits, pvScan0 and lDelta */
237 pso
->pvBits
= pvBits
;
238 if (fjBitmap
& BMF_TOPDOWN
)
240 /* Topdown is the normal way */
241 pso
->pvScan0
= pso
->pvBits
;
242 pso
->lDelta
= ulWidth
;
246 /* Inversed bitmap (bottom up) */
247 pso
->pvScan0
= (PVOID
)((ULONG_PTR
)pso
->pvBits
+ pso
->cjBits
- ulWidth
);
248 pso
->lDelta
= -(LONG
)ulWidth
;
251 pso
->fjBitmap
= (USHORT
)fjBitmap
;
269 /* Allocate a surface */
270 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
273 DPRINT1("SURFACE_AllocSurface failed.\n");
277 /* Get the handle for the bitmap */
278 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
280 /* Set the bitmap bits */
281 if (!SURFACE_bSetBitmapBits(psurf
, fl
, lWidth
, pvBits
))
283 /* Bail out if that failed */
284 DPRINT1("SURFACE_bSetBitmapBits failed.\n");
285 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
289 /* Set public ownership */
290 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
292 /* Unlock the surface and return */
293 SURFACE_UnlockSurface(psurf
);
302 EngCreateDeviceBitmap(
310 /* Allocate a surface */
311 psurf
= SURFACE_AllocSurface(STYPE_DEVBITMAP
, sizl
.cx
, sizl
.cy
, iFormat
);
317 /* Set the device handle */
318 psurf
->SurfObj
.dhsurf
= dhsurf
;
320 /* Get the handle for the bitmap */
321 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
323 /* Set public ownership */
324 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
326 /* Unlock the surface and return */
327 SURFACE_UnlockSurface(psurf
);
333 EngCreateDeviceSurface(
341 /* Allocate a surface */
342 psurf
= SURFACE_AllocSurface(STYPE_DEVICE
, sizl
.cx
, sizl
.cy
, iFormat
);
348 /* Set the device handle */
349 psurf
->SurfObj
.dhsurf
= dhsurf
;
351 /* Get the handle for the surface */
352 hsurf
= psurf
->SurfObj
.hsurf
;
354 /* Set public ownership */
355 GDIOBJ_vSetObjectOwner(&psurf
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
357 /* Unlock the surface and return */
358 SURFACE_UnlockSurface(psurf
);
373 ppdev
= (PDEVOBJ
*)hdev
;
375 /* Lock the surface */
376 psurf
= SURFACE_ShareLockSurface(hsurf
);
381 pso
= &psurf
->SurfObj
;
383 /* Associate the hdev */
385 pso
->dhpdev
= ppdev
->dhpdev
;
387 /* Hook up specified functions */
388 psurf
->flags
&= ~HOOK_FLAGS
;
389 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
392 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
394 SURFACE_ShareUnlockSurface(psurf
);
415 psurf
= SURFACE_ShareLockSurface(hsurf
);
421 ppdev
= (PDEVOBJ
*)hdev
;
422 pso
= &psurf
->SurfObj
;
423 pso
->dhsurf
= dhsurf
;
424 pso
->lDelta
= lDelta
;
425 pso
->pvScan0
= pvScan0
;
427 /* Associate the hdev */
429 pso
->dhpdev
= ppdev
->dhpdev
;
431 /* Hook up specified functions */
432 psurf
->flags
&= ~HOOK_FLAGS
;
433 psurf
->flags
|= (flHooks
& HOOK_FLAGS
);
436 psurf
->ppal
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
438 SURFACE_ShareUnlockSurface(psurf
);
446 EngDeleteSurface(IN HSURF hsurf
)
450 psurf
= SURFACE_ShareLockSurface(hsurf
);
453 DPRINT1("Could not reference surface to delete\n");
457 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
470 return FillSolid(pso
, prcl
, iColor
);
477 NtGdiEngLockSurface(IN HSURF hsurf
)
479 return EngLockSurface(hsurf
);
485 EngLockSurface(IN HSURF hsurf
)
487 SURFACE
*psurf
= SURFACE_ShareLockSurface(hsurf
);
489 return psurf
? &psurf
->SurfObj
: NULL
;
494 NtGdiEngUnlockSurface(IN SURFOBJ
*pso
)
502 EngUnlockSurface(IN SURFOBJ
*pso
)
506 SURFACE
*psurf
= CONTAINING_RECORD(pso
, SURFACE
, SurfObj
);
507 SURFACE_ShareUnlockSurface(psurf
);