1 | /** @file
|
---|
2 | *
|
---|
3 | * VirtualBox Windows NT/2000/XP guest video driver
|
---|
4 | *
|
---|
5 | * VBVA dirty rectangles calculations.
|
---|
6 | *
|
---|
7 | * Copyright (C) 2006-2007 innotek GmbH
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
12 | * General Public License (GPL) as published by the Free Software
|
---|
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #include "driver.h"
|
---|
19 |
|
---|
20 | #ifdef VBOX_VBVA_ADJUST_RECT
|
---|
21 | static ULONG vbvaConvertPixel ( /*from*/ BYTE *pu8PixelFrom, int cbPixelFrom,
|
---|
22 | /*to*/ int cbPixelTo)
|
---|
23 | {
|
---|
24 | BYTE r, g, b;
|
---|
25 | ULONG ulConvertedPixel = 0;
|
---|
26 |
|
---|
27 | switch (cbPixelFrom)
|
---|
28 | {
|
---|
29 | case 4:
|
---|
30 | {
|
---|
31 | switch (cbPixelTo)
|
---|
32 | {
|
---|
33 | case 3:
|
---|
34 | {
|
---|
35 | memcpy (&ulConvertedPixel, pu8PixelFrom, 3);
|
---|
36 | } break;
|
---|
37 |
|
---|
38 | case 2:
|
---|
39 | {
|
---|
40 | ulConvertedPixel = *(ULONG *)pu8PixelFrom;
|
---|
41 |
|
---|
42 | r = (BYTE)(ulConvertedPixel >> 16);
|
---|
43 | g = (BYTE)(ulConvertedPixel >> 8);
|
---|
44 | b = (BYTE)(ulConvertedPixel);
|
---|
45 |
|
---|
46 | ulConvertedPixel = ((r >> 3) << 11) + ((g >> 2) << 5) + (b >> 3);
|
---|
47 | } break;
|
---|
48 | }
|
---|
49 | } break;
|
---|
50 |
|
---|
51 | case 3:
|
---|
52 | {
|
---|
53 | switch (cbPixelTo)
|
---|
54 | {
|
---|
55 | case 2:
|
---|
56 | {
|
---|
57 | memcpy (&ulConvertedPixel, pu8PixelFrom, 3);
|
---|
58 |
|
---|
59 | r = (BYTE)(ulConvertedPixel >> 16);
|
---|
60 | g = (BYTE)(ulConvertedPixel >> 8);
|
---|
61 | b = (BYTE)(ulConvertedPixel);
|
---|
62 |
|
---|
63 | ulConvertedPixel = ((r >> 3) << 11) + ((g >> 2) << 5) + (b >> 3);
|
---|
64 | } break;
|
---|
65 | }
|
---|
66 | } break;
|
---|
67 | }
|
---|
68 |
|
---|
69 | return ulConvertedPixel;
|
---|
70 | }
|
---|
71 |
|
---|
72 | BOOL vbvaFindChangedRect (SURFOBJ *psoDest, SURFOBJ *psoSrc, RECTL *prclDest, POINTL *pptlSrc)
|
---|
73 | {
|
---|
74 | int x, y;
|
---|
75 | int fTopNonEqualFound;
|
---|
76 | int yTopmost;
|
---|
77 | int yBottommost;
|
---|
78 | int cbPixelSrc;
|
---|
79 | int cbPixelDest;
|
---|
80 | RECTL rclDest;
|
---|
81 | RECTL rclSrc;
|
---|
82 | BYTE *pu8Src;
|
---|
83 | BYTE *pu8Dest;
|
---|
84 |
|
---|
85 | if (!prclDest || !pptlSrc)
|
---|
86 | {
|
---|
87 | return TRUE;
|
---|
88 | }
|
---|
89 |
|
---|
90 | DISPDBG((1, "vbvaFindChangedRect: dest %d,%d %dx%d from %d,%d\n",
|
---|
91 | prclDest->left, prclDest->top, prclDest->right - prclDest->left, prclDest->bottom - prclDest->top,
|
---|
92 | pptlSrc->x, pptlSrc->y
|
---|
93 | ));
|
---|
94 |
|
---|
95 | switch (psoDest->iBitmapFormat)
|
---|
96 | {
|
---|
97 | case BMF_16BPP: cbPixelDest = 2; break;
|
---|
98 | case BMF_24BPP: cbPixelDest = 3; break;
|
---|
99 | case BMF_32BPP: cbPixelDest = 4; break;
|
---|
100 | default: cbPixelDest = 0;
|
---|
101 | }
|
---|
102 |
|
---|
103 | switch (psoSrc->iBitmapFormat)
|
---|
104 | {
|
---|
105 | case BMF_16BPP: cbPixelSrc = 2; break;
|
---|
106 | case BMF_24BPP: cbPixelSrc = 3; break;
|
---|
107 | case BMF_32BPP: cbPixelSrc = 4; break;
|
---|
108 | default: cbPixelSrc = 0;
|
---|
109 | }
|
---|
110 |
|
---|
111 | if (cbPixelDest == 0 || cbPixelSrc == 0)
|
---|
112 | {
|
---|
113 | DISPDBG((1, "vbvaFindChangedRect: unsupported pixel format src %d dst %d\n", psoDest->iBitmapFormat, psoSrc->iBitmapFormat));
|
---|
114 | return TRUE;
|
---|
115 | }
|
---|
116 |
|
---|
117 | rclDest = *prclDest;
|
---|
118 |
|
---|
119 | vrdpAdjustRect (psoDest, &rclDest);
|
---|
120 |
|
---|
121 | pptlSrc->x += rclDest.left - prclDest->left;
|
---|
122 | pptlSrc->y += rclDest.top - prclDest->top;
|
---|
123 |
|
---|
124 | *prclDest = rclDest;
|
---|
125 |
|
---|
126 | if ( rclDest.right == rclDest.left
|
---|
127 | || rclDest.bottom == rclDest.top)
|
---|
128 | {
|
---|
129 | DISPDBG((1, "vbvaFindChangedRect: empty dest rect: %d-%d, %d-%d\n", rclDest.left, rclDest.right, rclDest.top, rclDest.bottom));
|
---|
130 | return FALSE;
|
---|
131 | }
|
---|
132 |
|
---|
133 | rclSrc.left = pptlSrc->x;
|
---|
134 | rclSrc.top = pptlSrc->y;
|
---|
135 | rclSrc.right = pptlSrc->x + (rclDest.right - rclDest.left);
|
---|
136 | rclSrc.bottom = pptlSrc->y + (rclDest.bottom - rclDest.top);
|
---|
137 | vrdpAdjustRect (psoSrc, &rclSrc);
|
---|
138 |
|
---|
139 | if ( rclSrc.right == rclSrc.left
|
---|
140 | || rclSrc.bottom == rclSrc.top)
|
---|
141 | {
|
---|
142 | prclDest->right = prclDest->left;
|
---|
143 | prclDest->bottom = prclDest->top;
|
---|
144 |
|
---|
145 | DISPDBG((1, "vbvaFindChangedRect: empty src rect: %d-%d, %d-%d\n", rclSrc.left, rclSrc.right, rclSrc.top, rclSrc.bottom));
|
---|
146 | return FALSE;
|
---|
147 | }
|
---|
148 |
|
---|
149 | VBVA_ASSERT(pptlSrc->x == rclSrc.left);
|
---|
150 | VBVA_ASSERT(pptlSrc->y == rclSrc.top);
|
---|
151 |
|
---|
152 | /*
|
---|
153 | * Compare the content of the screen surface (psoDest) with the source surface (psoSrc).
|
---|
154 | * Update the prclDest with the rectangle that will be actually changed after
|
---|
155 | * copying the source bits to the screen.
|
---|
156 | */
|
---|
157 | pu8Src = (BYTE *)psoSrc->pvScan0 + psoSrc->lDelta * pptlSrc->y + cbPixelSrc * pptlSrc->x;
|
---|
158 | pu8Dest = (BYTE *)psoDest->pvScan0 + psoDest->lDelta * prclDest->top + cbPixelDest * prclDest->left;
|
---|
159 |
|
---|
160 | /* Use the rclDest as the bounding rectangle for the changed area. */
|
---|
161 | rclDest.left = prclDest->right; /* +inf */
|
---|
162 | rclDest.right = prclDest->left; /* -inf */
|
---|
163 | rclDest.top = prclDest->bottom; /* +inf */
|
---|
164 | rclDest.bottom = prclDest->top; /* -inf */
|
---|
165 |
|
---|
166 | fTopNonEqualFound = 0;
|
---|
167 | yTopmost = prclDest->top; /* inclusive */
|
---|
168 | yBottommost = prclDest->top - 1; /* inclusive */
|
---|
169 |
|
---|
170 | for (y = prclDest->top; y < prclDest->bottom; y++)
|
---|
171 | {
|
---|
172 | int fLeftNonEqualFound = 0;
|
---|
173 |
|
---|
174 | /* Init to an empty line. */
|
---|
175 | int xLeftmost = prclDest->left; /* inclusive */
|
---|
176 | int xRightmost = prclDest->left - 1; /* inclusive */
|
---|
177 |
|
---|
178 | BYTE *pu8SrcLine = pu8Src;
|
---|
179 | BYTE *pu8DestLine = pu8Dest;
|
---|
180 |
|
---|
181 | for (x = prclDest->left; x < prclDest->right; x++)
|
---|
182 | {
|
---|
183 | int fEqualPixels;
|
---|
184 |
|
---|
185 | if (cbPixelSrc == cbPixelDest)
|
---|
186 | {
|
---|
187 | fEqualPixels = (memcmp (pu8SrcLine, pu8DestLine, cbPixelDest) == 0);
|
---|
188 | }
|
---|
189 | else
|
---|
190 | {
|
---|
191 | /* Convert larger pixel to the smaller pixel format. */
|
---|
192 | ULONG ulConvertedPixel;
|
---|
193 | if (cbPixelSrc > cbPixelDest)
|
---|
194 | {
|
---|
195 | /* Convert the source pixel to the destination pixel format. */
|
---|
196 | ulConvertedPixel = vbvaConvertPixel ( /*from*/ pu8SrcLine, cbPixelSrc,
|
---|
197 | /*to*/ cbPixelDest);
|
---|
198 | fEqualPixels = (memcmp (&ulConvertedPixel, pu8DestLine, cbPixelDest) == 0);
|
---|
199 | }
|
---|
200 | else
|
---|
201 | {
|
---|
202 | /* Convert the destination pixel to the source pixel format. */
|
---|
203 | ulConvertedPixel = vbvaConvertPixel ( /*from*/ pu8DestLine, cbPixelDest,
|
---|
204 | /*to*/ cbPixelSrc);
|
---|
205 | fEqualPixels = (memcmp (&ulConvertedPixel, pu8SrcLine, cbPixelSrc) == 0);
|
---|
206 | }
|
---|
207 | }
|
---|
208 |
|
---|
209 | if (fEqualPixels)
|
---|
210 | {
|
---|
211 | /* Equal pixels. */
|
---|
212 | if (!fLeftNonEqualFound)
|
---|
213 | {
|
---|
214 | xLeftmost = x;
|
---|
215 | }
|
---|
216 | }
|
---|
217 | else
|
---|
218 | {
|
---|
219 | fLeftNonEqualFound = 1;
|
---|
220 | xRightmost = x;
|
---|
221 | }
|
---|
222 |
|
---|
223 | pu8SrcLine += cbPixelSrc;
|
---|
224 | pu8DestLine += cbPixelDest;
|
---|
225 | }
|
---|
226 |
|
---|
227 | /* min */
|
---|
228 | if (rclDest.left > xLeftmost)
|
---|
229 | {
|
---|
230 | rclDest.left = xLeftmost;
|
---|
231 | }
|
---|
232 |
|
---|
233 | /* max */
|
---|
234 | if (rclDest.right < xRightmost)
|
---|
235 | {
|
---|
236 | rclDest.right = xRightmost;
|
---|
237 | }
|
---|
238 |
|
---|
239 | if (xLeftmost > xRightmost) /* xRightmost is inclusive, so '>', not '>='. */
|
---|
240 | {
|
---|
241 | /* Empty line. */
|
---|
242 | if (!fTopNonEqualFound)
|
---|
243 | {
|
---|
244 | yTopmost = y;
|
---|
245 | }
|
---|
246 | }
|
---|
247 | else
|
---|
248 | {
|
---|
249 | fTopNonEqualFound = 1;
|
---|
250 | yBottommost = y;
|
---|
251 | }
|
---|
252 |
|
---|
253 | pu8Src += psoSrc->lDelta;
|
---|
254 | pu8Dest += psoDest->lDelta;
|
---|
255 | }
|
---|
256 |
|
---|
257 | /* min */
|
---|
258 | if (rclDest.top > yTopmost)
|
---|
259 | {
|
---|
260 | rclDest.top = yTopmost;
|
---|
261 | }
|
---|
262 |
|
---|
263 | /* max */
|
---|
264 | if (rclDest.bottom < yBottommost)
|
---|
265 | {
|
---|
266 | rclDest.bottom = yBottommost;
|
---|
267 | }
|
---|
268 |
|
---|
269 | /* rclDest was calculated with right-bottom inclusive.
|
---|
270 | * The following checks and the caller require exclusive coords.
|
---|
271 | */
|
---|
272 | rclDest.right++;
|
---|
273 | rclDest.bottom++;
|
---|
274 |
|
---|
275 | DISPDBG((1, "vbvaFindChangedRect: new dest %d,%d %dx%d from %d,%d\n",
|
---|
276 | rclDest.left, rclDest.top, rclDest.right - rclDest.left, rclDest.bottom - rclDest.top,
|
---|
277 | pptlSrc->x, pptlSrc->y
|
---|
278 | ));
|
---|
279 |
|
---|
280 | /* Update the rectangle with the changed area. */
|
---|
281 | if ( rclDest.left >= rclDest.right
|
---|
282 | || rclDest.top >= rclDest.bottom)
|
---|
283 | {
|
---|
284 | /* Empty rect. */
|
---|
285 | DISPDBG((1, "vbvaFindChangedRect: empty\n"));
|
---|
286 | prclDest->right = prclDest->left;
|
---|
287 | prclDest->bottom = prclDest->top;
|
---|
288 | return FALSE;
|
---|
289 | }
|
---|
290 |
|
---|
291 | DISPDBG((1, "vbvaFindChangedRect: not empty\n"));
|
---|
292 |
|
---|
293 | pptlSrc->x += rclDest.left - prclDest->left;
|
---|
294 | pptlSrc->y += rclDest.top - prclDest->top;
|
---|
295 |
|
---|
296 | *prclDest = rclDest;
|
---|
297 |
|
---|
298 | return TRUE;
|
---|
299 | }
|
---|
300 | #endif /* VBOX_VBVA_ADJUST_RECT */
|
---|
301 |
|
---|
302 | void vboxReportDirtyRect (PPDEV ppdev, RECTL *pRectOrig)
|
---|
303 | {
|
---|
304 | if (ppdev)
|
---|
305 | {
|
---|
306 | VBVACMDHDR hdr;
|
---|
307 |
|
---|
308 | RECTL rect = *pRectOrig;
|
---|
309 |
|
---|
310 | if (rect.left < 0) rect.left = 0;
|
---|
311 | if (rect.top < 0) rect.top = 0;
|
---|
312 | if (rect.right > (int)ppdev->cxScreen) rect.right = ppdev->cxScreen;
|
---|
313 | if (rect.bottom > (int)ppdev->cyScreen) rect.bottom = ppdev->cyScreen;
|
---|
314 |
|
---|
315 | hdr.x = (int16_t)rect.left;
|
---|
316 | hdr.y = (int16_t)rect.top;
|
---|
317 | hdr.w = (uint16_t)(rect.right - rect.left);
|
---|
318 | hdr.h = (uint16_t)(rect.bottom - rect.top);
|
---|
319 |
|
---|
320 | hdr.x += (int16_t)ppdev->ptlDevOrg.x;
|
---|
321 | hdr.y += (int16_t)ppdev->ptlDevOrg.y;
|
---|
322 |
|
---|
323 | vboxWrite (ppdev, &hdr, sizeof(hdr));
|
---|
324 | }
|
---|
325 |
|
---|
326 | return;
|
---|
327 | }
|
---|
328 |
|
---|
329 | void vbvaReportDirtyRect (PPDEV ppdev, RECTL *prcl)
|
---|
330 | {
|
---|
331 | if (prcl)
|
---|
332 | {
|
---|
333 | DISPDBG((1, "DISP VBVA dirty rect: left %d, top: %d, width: %d, height: %d\n",
|
---|
334 | prcl->left, prcl->top, prcl->right - prcl->left, prcl->bottom - prcl->top));
|
---|
335 |
|
---|
336 | vboxReportDirtyRect(ppdev, prcl);
|
---|
337 | }
|
---|
338 | }
|
---|
339 |
|
---|
340 | void vbvaReportDirtyPath (PPDEV ppdev, PATHOBJ *ppo)
|
---|
341 | {
|
---|
342 | RECTFX rcfxBounds;
|
---|
343 | RECTL rclBounds;
|
---|
344 |
|
---|
345 | PATHOBJ_vGetBounds(ppo, &rcfxBounds);
|
---|
346 |
|
---|
347 | rclBounds.left = FXTOLFLOOR(rcfxBounds.xLeft);
|
---|
348 | rclBounds.right = FXTOLCEILING(rcfxBounds.xRight);
|
---|
349 | rclBounds.top = FXTOLFLOOR(rcfxBounds.yTop);
|
---|
350 | rclBounds.bottom = FXTOLCEILING(rcfxBounds.yBottom);
|
---|
351 |
|
---|
352 | vbvaReportDirtyRect (ppdev, &rclBounds);
|
---|
353 | }
|
---|
354 |
|
---|
355 | __inline void vbvaReportDirtyClip (PPDEV ppdev, CLIPOBJ *pco, RECTL *prcl)
|
---|
356 | {
|
---|
357 | if (prcl)
|
---|
358 | {
|
---|
359 | vbvaReportDirtyRect (ppdev, prcl);
|
---|
360 | }
|
---|
361 | else if (pco)
|
---|
362 | {
|
---|
363 | vbvaReportDirtyRect (ppdev, &pco->rclBounds);
|
---|
364 | }
|
---|
365 | }
|
---|
366 |
|
---|
367 |
|
---|
368 | void vbvaBitBlt (
|
---|
369 | SURFOBJ *psoTrg,
|
---|
370 | SURFOBJ *psoSrc,
|
---|
371 | SURFOBJ *psoMask,
|
---|
372 | CLIPOBJ *pco,
|
---|
373 | XLATEOBJ *pxlo,
|
---|
374 | RECTL *prclTrg,
|
---|
375 | POINTL *pptlSrc,
|
---|
376 | POINTL *pptlMask,
|
---|
377 | BRUSHOBJ *pbo,
|
---|
378 | POINTL *pptlBrush,
|
---|
379 | ROP4 rop4)
|
---|
380 | {
|
---|
381 | PPDEV ppdev = (PPDEV)psoTrg->dhpdev;
|
---|
382 |
|
---|
383 | vbvaReportDirtyClip (ppdev, pco, prclTrg);
|
---|
384 | }
|
---|
385 |
|
---|
386 | void vbvaTextOut(
|
---|
387 | SURFOBJ *pso,
|
---|
388 | STROBJ *pstro,
|
---|
389 | FONTOBJ *pfo,
|
---|
390 | CLIPOBJ *pco,
|
---|
391 | RECTL *prclExtra, // Obsolete, always NULL
|
---|
392 | RECTL *prclOpaque,
|
---|
393 | BRUSHOBJ *pboFore,
|
---|
394 | BRUSHOBJ *pboOpaque,
|
---|
395 | POINTL *pptlOrg,
|
---|
396 | MIX mix
|
---|
397 | )
|
---|
398 | {
|
---|
399 | PPDEV ppdev = (PPDEV)pso->dhpdev;
|
---|
400 |
|
---|
401 | vbvaReportDirtyClip (ppdev, pco, prclOpaque? prclOpaque: &pstro->rclBkGround);
|
---|
402 | }
|
---|
403 |
|
---|
404 | void vbvaLineTo(
|
---|
405 | SURFOBJ *pso,
|
---|
406 | CLIPOBJ *pco,
|
---|
407 | BRUSHOBJ *pbo,
|
---|
408 | LONG x1,
|
---|
409 | LONG y1,
|
---|
410 | LONG x2,
|
---|
411 | LONG y2,
|
---|
412 | RECTL *prclBounds,
|
---|
413 | MIX mix
|
---|
414 | )
|
---|
415 | {
|
---|
416 | PPDEV ppdev = (PPDEV)pso->dhpdev;
|
---|
417 |
|
---|
418 | vbvaReportDirtyClip (ppdev, pco, prclBounds);
|
---|
419 | }
|
---|
420 |
|
---|
421 | void vbvaStretchBlt(
|
---|
422 | SURFOBJ *psoDest,
|
---|
423 | SURFOBJ *psoSrc,
|
---|
424 | SURFOBJ *psoMask,
|
---|
425 | CLIPOBJ *pco,
|
---|
426 | XLATEOBJ *pxlo,
|
---|
427 | COLORADJUSTMENT *pca,
|
---|
428 | POINTL *pptlHTOrg,
|
---|
429 | RECTL *prclDest,
|
---|
430 | RECTL *prclSrc,
|
---|
431 | POINTL *pptlMask,
|
---|
432 | ULONG iMode
|
---|
433 | )
|
---|
434 | {
|
---|
435 | PPDEV ppdev = (PPDEV)psoDest->dhpdev;
|
---|
436 |
|
---|
437 | vbvaReportDirtyClip (ppdev, pco, prclDest);
|
---|
438 | }
|
---|
439 |
|
---|
440 | void vbvaCopyBits(
|
---|
441 | SURFOBJ *psoDest,
|
---|
442 | SURFOBJ *psoSrc,
|
---|
443 | CLIPOBJ *pco,
|
---|
444 | XLATEOBJ *pxlo,
|
---|
445 | RECTL *prclDest,
|
---|
446 | POINTL *pptlSrc
|
---|
447 | )
|
---|
448 | {
|
---|
449 | PPDEV ppdev = (PPDEV)psoDest->dhpdev;
|
---|
450 |
|
---|
451 | vbvaReportDirtyClip (ppdev, pco, prclDest);
|
---|
452 | }
|
---|
453 |
|
---|
454 | void vbvaPaint(
|
---|
455 | SURFOBJ *pso,
|
---|
456 | CLIPOBJ *pco,
|
---|
457 | BRUSHOBJ *pbo,
|
---|
458 | POINTL *pptlBrushOrg,
|
---|
459 | MIX mix
|
---|
460 | )
|
---|
461 | {
|
---|
462 | PPDEV ppdev = (PPDEV)pso->dhpdev;
|
---|
463 |
|
---|
464 | vbvaReportDirtyClip (ppdev, pco, NULL);
|
---|
465 | }
|
---|
466 |
|
---|
467 | void vbvaFillPath(
|
---|
468 | SURFOBJ *pso,
|
---|
469 | PATHOBJ *ppo,
|
---|
470 | CLIPOBJ *pco,
|
---|
471 | BRUSHOBJ *pbo,
|
---|
472 | POINTL *pptlBrushOrg,
|
---|
473 | MIX mix,
|
---|
474 | FLONG flOptions
|
---|
475 | )
|
---|
476 | {
|
---|
477 | PPDEV ppdev = (PPDEV)pso->dhpdev;
|
---|
478 |
|
---|
479 | vbvaReportDirtyPath (ppdev, ppo);
|
---|
480 | }
|
---|
481 |
|
---|
482 | void vbvaStrokePath(
|
---|
483 | SURFOBJ *pso,
|
---|
484 | PATHOBJ *ppo,
|
---|
485 | CLIPOBJ *pco,
|
---|
486 | XFORMOBJ *pxo,
|
---|
487 | BRUSHOBJ *pbo,
|
---|
488 | POINTL *pptlBrushOrg,
|
---|
489 | LINEATTRS *plineattrs,
|
---|
490 | MIX mix
|
---|
491 | )
|
---|
492 | {
|
---|
493 | PPDEV ppdev = (PPDEV)pso->dhpdev;
|
---|
494 |
|
---|
495 | vbvaReportDirtyPath (ppdev, ppo);
|
---|
496 | }
|
---|
497 |
|
---|
498 | void vbvaSaveScreenBits(
|
---|
499 | SURFOBJ *pso,
|
---|
500 | ULONG iMode,
|
---|
501 | ULONG_PTR ident,
|
---|
502 | RECTL *prcl
|
---|
503 | )
|
---|
504 | {
|
---|
505 | PPDEV ppdev = (PPDEV)pso->dhpdev;
|
---|
506 |
|
---|
507 | VBVA_ASSERT(iMode == SS_RESTORE || iMode == SS_SAVE);
|
---|
508 |
|
---|
509 | vbvaReportDirtyRect (ppdev, prcl);
|
---|
510 | }
|
---|
511 |
|
---|