|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: BitBlt.c
8:
9: Abstract:
10:
11: This module hooks DrvBitBlt and DrvCopyBits for the Jaguar VXL board.
12:
13: The following operations are supported for DrvBitBlt:
14: SRCCOPY from screen to screen
15: BLACKNESS
16: WHITNESS
17: PATCOPY when the Brush pattern is a solid color
18: NOTPATCOPY when the Brush pattern is a solid color
19:
20: DrvCopyBits copies the data if source and dest surfaces are the
21: frame buffer.
22:
23: Environment:
24:
25: User mode.
26:
27: Revision History:
28:
29: --*/
30:
31: #include "driver.h"
32: #include "jzvxl484.h"
33:
34: //
35: //Tmp savescreenbits vars
36: //
37:
38:
39: BOOL
40: DrvpIntersectRect(
41: IN PRECTL Rectl1,
42: IN PRECTL Rectl2,
43: OUT PRECTL DestRectl
44: )
45:
46: /*++
47:
48: Routine Description:
49:
50: This routine checks to see if the two specified retangles intersect.
51:
52: N.B. This routine is adopted from a routine written by darrinm.
53:
54: Arguments:
55:
56: Rectl1 - Supplies the coordinates of the first rectangle.
57:
58: Rectl2 - Supplies the coordinates of the second rectangle.
59:
60: DestRectl - Supplies the coordinates of the utput rectangle.
61:
62: Return Value:
63:
64: A value of TRUE is returned if the rectangles intersect. Otherwise,
65: a value of FALSE is returned.
66:
67: --*/
68:
69:
70: {
71:
72: //
73: // Compute the maximum left edge and the minimum right edge.
74: //
75:
76: DestRectl->left = max(Rectl1->left, Rectl2->left);
77: DestRectl->right = min(Rectl1->right, Rectl2->right);
78:
79: //
80: // If the minimum right edge is greater than the maximum left edge,
81: // then the rectanges may intersect. Otherwise, they do not intersect.
82: //
83:
84: if (DestRectl->left < DestRectl->right) {
85:
86: //
87: // Compute the maximum top edge and the minimum bottom edge.
88: //
89:
90: DestRectl->top = max(Rectl1->top, Rectl2->top);
91: DestRectl->bottom = min(Rectl1->bottom, Rectl2->bottom);
92:
93: //
94: // If the minimum bottom edge is greater than the maximum top
95: // edge, then the rectanges intersect. Otherwise, they do not
96: // intersect.
97: //
98:
99: if (DestRectl->top < DestRectl->bottom) {
100: return TRUE;
101: }
102: }
103:
104: return FALSE;
105: }
106:
107: VOID
108: DrvpFillRectangle(
109: IN PRECTL DstRect,
110: IN ULONG Color
111: )
112: /*++
113:
114: Routine Description:
115:
116: Place a solid color fill command into the FIFO
117:
118: Arguments:
119:
120: DestRect - Rectangle to fill
121: Color - Fill color
122:
123: Return Value:
124:
125: Status of operation.
126:
127: --*/
128: {
129:
130: ULONG X,Y;
131: ULONG XYCmd;
132: ULONG DstAdr;
133:
134: //
135: // calculate size of the fill.
136: //
137:
138: X = (ULONG)(DstRect->right - DstRect->left);
139: Y = (ULONG)(DstRect->bottom - DstRect->top);
140: Y &= 0x3FF;
141:
142: XYCmd=(JAGUAR_SOLID_FILL << XYCMD_CMD_SHIFT) | (Y << XYCMD_Y_SHIFT) | X;
143:
144: DstAdr= Vxl.JaguarScreenX*DstRect->top + (DstRect->left << Vxl.ColorModeShift);
145:
146: //
147: // Write command to the FIFO.
148: //
149:
150: FifoWrite(DstAdr,Color,XYCmd);
151:
152: }
153:
154: VOID
155: DrvpSolidFill(
156: IN PRECTL DstRect,
157: IN CLIPOBJ *pco,
158: IN ULONG Color
159: )
160: /*++
161:
162: Routine Description:
163:
164: This routine fills the unclipped areas of the destination rectangle with
165: the given color.
166:
167: Arguments:
168:
169: DstRect - Destination Rectangle
170: pco - Clipping area.
171: Color - Color to fill with.
172:
173: Return Value:
174:
175: None.
176:
177: --*/
178: {
179: RECTL BltRectl;
180: ENUMRECTLIST ClipEnum;
181: BOOL MoreClipRects;
182: ULONG ClipRegions;
183: BYTE FixedComplexity;
184:
185: //
186: // Figure out the real clipping complexity
187: //
188: if (pco == (CLIPOBJ *)NULL) {
189: FixedComplexity = DC_TRIVIAL;
190: } else {
191: FixedComplexity = pco->iDComplexity;
192: }
193: switch (FixedComplexity) {
194:
195: //
196: // Entire destination is to be updated.
197: // Proceed with the Solid Fill.
198: //
199: case DC_TRIVIAL:
200:
201: DrvpFillRectangle(DstRect, // Target rectangle
202: Color); // Color
203:
204: break;
205:
206: //
207: // Only one clip region.
208: //
209:
210: case DC_RECT:
211: //
212: // only do the Fill if there is an intersection
213: //
214:
215: if (DrvpIntersectRect(DstRect,&pco->rclBounds,&BltRectl)) {
216:
217: DrvpFillRectangle(&BltRectl, // Target rectangle
218: Color); // Color
219: }
220: break;
221:
222: //
223: // Multiple clip regions.
224: //
225:
226: case DC_COMPLEX:
227:
228: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,CD_ANY,BB_RECT_LIMIT);
229: do {
230:
231: //
232: // Get list of clip rectangles.
233: //
234:
235: MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum);
236:
237: for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) {
238:
239: //
240: // If the rectangles intersect do the fill
241: //
242: if (DrvpIntersectRect(DstRect,
243: &ClipEnum.arcl[ClipRegions],
244: &BltRectl)) {
245: DrvpFillRectangle(&BltRectl, // Target rectangle
246: Color); // Color
247:
248: }
249: }
250: } while (MoreClipRects);
251: break;
252:
253: } // end switch complexity
254: }
255:
256: VOID
257: DrvpBitBlt(
258: IN PRECTL DstRect,
259: IN PPOINTL SrcPoint,
260: IN BOOL BltDir
261: )
262: /*++
263:
264: Routine Description:
265:
266: Place a BitBlt command into the FIFO
267:
268: Arguments:
269:
270: DstRect - Destination Rectangle
271: SrcPoint - Source Point
272: BltDir - FALSE = Left to Right Top to Bottom.
273: TRUE = Right to Left Bottom to Top
274:
275: Return Value:
276:
277: None.
278:
279: --*/
280: {
281:
282: ULONG X,Y;
283: ULONG XYCmd;
284: ULONG SrcAdr;
285: ULONG DstAdr;
286:
287: X = DstRect->right - DstRect->left;
288: Y = DstRect->bottom - DstRect->top;
289: if (BltDir) {
290:
291: //
292: // This is a Right To Left Bottom to Top BitBlt
293: // Src and Dest adr are the first byte of the pixel to
294: // be moved. That is the most significant byte of the pixel.
295: // The Rectangle excludes the bottom right corner which
296: // is the start address for these sort of bitblts.
297: // One is substracted from the Y to exclude the last line.
298: // One is substracted from the X after addjusting it to the
299: // size of the pixel. So the address of the next pixel is computed
300: // and then one is substracted which gives the address of the
301: // most significant byte of the previous pixel.
302: //
303:
304: DstAdr=Vxl.JaguarScreenX*(DstRect->bottom-1) + ((DstRect->right) << Vxl.ColorModeShift) -1;
305: SrcAdr=Vxl.JaguarScreenX*(SrcPoint->y+Y-1) + ((SrcPoint->x+X) << Vxl.ColorModeShift) -1;
306: XYCmd=JAGUAR_BITBLT_RIGHTLEFT << XYCMD_CMD_SHIFT;
307:
308: } else {
309:
310: //
311: // This is a Left To Right Top to Bottom.
312: //
313:
314: DstAdr=Vxl.JaguarScreenX*DstRect->top + (DstRect->left << Vxl.ColorModeShift);
315: SrcAdr=Vxl.JaguarScreenX*SrcPoint->y + (SrcPoint->x << Vxl.ColorModeShift);
316: XYCmd=JAGUAR_BITBLT_LEFTRIGHT << XYCMD_CMD_SHIFT;
317:
318: }
319: Y &= 0x3FF;
320:
321: XYCmd = XYCmd | (Y << XYCMD_Y_SHIFT) | X;
322: FifoWrite(DstAdr,SrcAdr,XYCmd);
323: }
324:
325: BOOL
326: DrvBitBlt(
327: IN SURFOBJ *psoDst, // Target surface
328: IN SURFOBJ *psoSrc, // Source surface
329: IN SURFOBJ *psoMask, // Mask
330: IN CLIPOBJ *pco, // Clip through this
331: IN XLATEOBJ *pxlo, // Color translation
332: IN PRECTL prclDst, // Target offset and extent
333: IN PPOINTL pptlSrc, // Source offset
334: IN PPOINTL pptlMask, // Mask offset
335: IN BRUSHOBJ *pdbrush, // Brush data (from cbRealizeBrush)
336: IN PPOINTL pptlBrush, // Brush offset (origin)
337: IN ROP4 rop4 // Raster operation
338: )
339:
340: /*++
341:
342: Routine Description:
343:
344: Code for "hooking" Bit Blt functions for Jaguar VXL.
345:
346: Arguments:
347:
348:
349: Return Value:
350:
351:
352: --*/
353:
354: {
355:
356: FLONG BltDir;
357: BOOL JaguarDir;
358: RECTL BltRectl;
359: ENUMRECTLIST ClipEnum;
360: BOOL MoreClipRects;
361: ULONG ClipRegions;
362: POINTL SrcPoint;
363: PPDEV ppdev = (PPDEV) psoDst->dhpdev;
364: BYTE FixedComplexity;
365:
366: //
367: // Check that there is no color translation.
368: //
369:
370: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) {
371:
372: //
373: // Check that the blt operation has the screen as target surface.
374: //
375:
376: if (psoDst->pvBits == (PVOID)Vxl.ScreenBase) {
377:
378: //
379: // Check for rops that Jaguar handles.
380: // Solid Fills,
381: // SRCCOPPY
382: //
383:
384: switch(rop4) {
385: case 0x00000000: // DDx (BLACKNESS)
386: DrvpSolidFill(prclDst,pco,0);
387: return(TRUE);
388:
389: case 0x0000FFFF: // DDxn (WHITENESS)
390: DrvpSolidFill(prclDst,pco,0xFFFFFF);
391: return(TRUE);
392:
393: case 0x0000F0F0: // P (PATCOPY)
394: case 0x00000F0F: // Pn (NOTPATCOPY)
395:
396: //
397: // This is a pattern fill. Check if the brush pattern
398: // is just a plain color, in this case procede with the
399: // Solid Color Fill.
400: //
401:
402: if (pdbrush->iSolidColor != 0xFFFFFFFF) {
403: DrvpSolidFill(prclDst,
404: pco,
405: (rop4 == 0xF0F) ? ~(pdbrush->iSolidColor) : pdbrush->iSolidColor);
406: return(TRUE);
407: }
408:
409: break;
410:
411: //
412: // Source copy
413: //
414:
415: case 0x0000CCCC:
416:
417: //
418: // Check that Source and Destination Surfaces are the same.
419: // This is enough as we already checked that the dst is the frame buffer
420: //
421:
422: if (psoDst->pvBits == psoSrc->pvBits) {
423:
424: //
425: // check BLT direction for setting up clip regions
426: // And for Jaguar BitBlt Commands as follows:
427: // - If BltDir is UPWARDS do the BitBlt RightToLeft Bottom
428: // to Top except when Src & Dst are in the same scan line
429: // and BltDir is not LEFTWARDS
430: //
431:
432: BltDir = 0;
433: JaguarDir = FALSE;
434: if (pptlSrc->y <= prclDst->top) {
435: BltDir = CD_UPWARDS;
436: JaguarDir = TRUE;
437: }
438:
439: if (pptlSrc->x <= prclDst->left) {
440: BltDir |= CD_LEFTWARDS;
441: } else {
442: if ((JaguarDir) && (pptlSrc->y == prclDst->top)) {
443: JaguarDir = FALSE;
444: }
445: }
446:
447: //
448: // Figure out the real clipping complexity
449: //
450:
451: if (pco == (CLIPOBJ *)NULL) {
452: FixedComplexity = DC_TRIVIAL;
453: } else {
454: FixedComplexity = pco->iDComplexity;
455: }
456:
457: switch (FixedComplexity) {
458:
459: //
460: // Entire destination is to be updated.
461: // Proceed with the BitBlt.
462: //
463:
464: case DC_TRIVIAL:
465:
466: DrvpBitBlt(prclDst, // Target rectangle
467: pptlSrc, // Source offset
468: JaguarDir // Direction
469: );
470: return(TRUE);
471:
472: //
473: // Only one clip region.
474: //
475:
476: case DC_RECT:
477:
478: //
479: // only do the BLT if there is an intersection
480: //
481:
482: if (DrvpIntersectRect(prclDst,&pco->rclBounds,&BltRectl)) {
483:
484: //
485: // Adjust the Source for the intersection rectangle.
486: //
487:
488: pptlSrc->x += BltRectl.left - prclDst->left;
489: pptlSrc->y += BltRectl.top - prclDst->top;
490:
491: DrvpBitBlt(&BltRectl, // Target rectangle
492: pptlSrc, // Source offset
493: JaguarDir // Direction
494: );
495: }
496:
497: return(TRUE);
498:
499: //
500: // Multiple clip regions.
501: //
502:
503: case DC_COMPLEX:
504:
505: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,BltDir,BB_RECT_LIMIT);
506: do {
507:
508: //
509: // Get list of clip rectangles.
510: //
511:
512: MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum);
513:
514: for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) {
515:
516: //
517: // If the rectangles intersect calculate the offset to the
518: // source start location to match and do the BitBlt.
519: //
520: if (DrvpIntersectRect(prclDst,
521: &ClipEnum.arcl[ClipRegions],
522: &BltRectl)) {
523: SrcPoint.x = pptlSrc->x + BltRectl.left - prclDst->left;
524: SrcPoint.y = pptlSrc->y + BltRectl.top - prclDst->top;
525: DrvpBitBlt(&BltRectl, // Target rectangle
526: &SrcPoint, // Source offset
527: JaguarDir // Direction
528: );
529: }
530: }
531: } while (MoreClipRects);
532:
533: return(TRUE);
534:
535: //
536: // Unknown Clip complexity
537: //
538:
539: default:
540: break;
541: } // end switch complexity
542: } // end if Src surface = Dst surface
543: } // end switch rop4
544: }
545: }
546:
547: //
548: // Call GDI to do the Blt for us. No need to syncrhonize here since
549: // EngXXX routines call DrvSynchronize.
550: //
551:
552: return(EngBitBlt(psoDst, // Target surface
553: psoSrc, // Source surface
554: psoMask, // Mask
555: pco, // Clip through this
556: pxlo, // Color translation
557: prclDst, // Target offset and extent
558: pptlSrc, // Source offset
559: pptlMask, // Mask offset
560: pdbrush, // Brush data (from cbRealizeBrush)
561: pptlBrush, // Brush offset (origin)
562: rop4 // Raster operation
563: )
564: );
565: }
566:
567: BOOL
568: DrvCopyBits(
569: SURFOBJ *psoDst,
570: SURFOBJ *psoSrc,
571: CLIPOBJ *pco,
572: XLATEOBJ *pxlo,
573: RECTL *prclDst,
574: POINTL *pptlSrc)
575:
576: /*++
577:
578: Routine Description:
579:
580: Code for "hooking" CopyBits function for Jaguar VXL.
581:
582: Arguments:
583:
584:
585: Return Value:
586:
587:
588: --*/
589:
590: {
591: RECTL BltRectl;
592: ENUMRECTLIST ClipEnum;
593: BYTE FixedComplexity;
594: BOOL MoreClipRects;
595: FLONG BltDir;
596: BOOL JaguarDir;
597: ULONG ClipRegions;
598: POINTL SrcPoint;
599:
600:
601:
602: //
603: // Check that there is no color translation.
604: //
605:
606: if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) {
607:
608: //
609: // Check that source and destination surfaces are the frame buffer.
610: //
611:
612: if ((psoSrc->pvBits == (PVOID)Vxl.ScreenBase) &&
613: (psoDst->pvBits == (PVOID)Vxl.ScreenBase)) {
614:
615: //
616: // check BLT direction for setting up clip regions
617: // And for Jaguar BitBlt Commands as follows:
618: // - If BltDir is UPWARDS do the BitBlt RightToLeft Bottom
619: // to Top except when Src & Dst are in the same scan line
620: // and BltDir is not LEFTWARDS
621: //
622:
623: BltDir = 0;
624: JaguarDir = FALSE;
625: if (pptlSrc->y <= prclDst->top) {
626: BltDir = CD_UPWARDS;
627: JaguarDir = TRUE;
628: }
629:
630: if (pptlSrc->x <= prclDst->left) {
631: BltDir |= CD_LEFTWARDS;
632: } else {
633: if ((JaguarDir) && (pptlSrc->y == prclDst->top)) {
634: JaguarDir = FALSE;
635: }
636: }
637:
638: //
639: // Figure out the real clipping complexity
640: //
641:
642: if (pco == (CLIPOBJ *)NULL) {
643: FixedComplexity = DC_TRIVIAL;
644: } else {
645: FixedComplexity = pco->iDComplexity;
646: }
647:
648: switch (FixedComplexity) {
649:
650: //
651: // Entire destination is to be updated.
652: // Proceed with the BitBlt.
653: //
654:
655: case DC_TRIVIAL:
656:
657: DrvpBitBlt(prclDst, // Target rectangle
658: pptlSrc, // Source offset
659: JaguarDir // Direction
660: );
661: return(TRUE);
662:
663: //
664: // Only one clip region.
665: //
666:
667: case DC_RECT:
668:
669: //
670: // only do the BLT if there is an intersection
671: //
672:
673: if (DrvpIntersectRect(prclDst,&pco->rclBounds,&BltRectl)) {
674:
675: //
676: // Adjust the Source for the intersection rectangle.
677: //
678:
679: pptlSrc->x += BltRectl.left - prclDst->left;
680: pptlSrc->y += BltRectl.top - prclDst->top;
681:
682: DrvpBitBlt(&BltRectl, // Target rectangle
683: pptlSrc, // Source offset
684: JaguarDir // Direction
685: );
686: }
687:
688: return(TRUE);
689:
690: //
691: // Multiple clip regions.
692: //
693:
694: case DC_COMPLEX:
695:
696: CLIPOBJ_cEnumStart(pco,FALSE,CT_RECTANGLES,BltDir,BB_RECT_LIMIT);
697: do {
698:
699: //
700: // Get list of clip rectangles.
701: //
702:
703: MoreClipRects = CLIPOBJ_bEnum(pco,sizeof(ClipEnum),(PVOID)&ClipEnum);
704:
705: for (ClipRegions=0;ClipRegions<ClipEnum.c;ClipRegions++) {
706:
707: //
708: // If the rectangles intersect calculate the offset to the
709: // source start location to match and do the BitBlt.
710: //
711: if (DrvpIntersectRect(prclDst,
712: &ClipEnum.arcl[ClipRegions],
713: &BltRectl)) {
714: SrcPoint.x = pptlSrc->x + BltRectl.left - prclDst->left;
715: SrcPoint.y = pptlSrc->y + BltRectl.top - prclDst->top;
716: DrvpBitBlt(&BltRectl, // Target rectangle
717: &SrcPoint, // Source offset
718: JaguarDir // Direction
719: );
720: }
721: }
722: } while (MoreClipRects);
723:
724: return(TRUE);
725:
726: //
727: // Unknown Clip complexity
728: //
729:
730: default:
731: break;
732: } // end switch complexity
733: }
734:
735: }
736:
737: //
738: // If the copy operation could be performed by the accelerator,
739: // this routine has already returned.
740: // If execution falls here, call the Engine routine.
741: // No need to Synchronize here since the Eng routine will call DrvSyncrhonize.
742: //
743:
744: return EngCopyBits(psoDst,
745: psoSrc,
746: pco,
747: pxlo,
748: prclDst,
749: pptlSrc);
750: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.