2 * Copyright 2005 Ge van Geldorp (gvg@reactos.com).
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * This is a code generator. It outputs C code which can be compiled using the
20 * standard build tools. It is used to generate code for the DIB Blt routines.
21 * There are a lot of possible Blt routines (256 rop codes, for 6 different
22 * bit depths). It is possible to use a generic Blt routine which handles all
23 * rop codes and all depths. The drawback is that it will be relatively slow.
24 * The other extreme is to write (generate) a separate Blt routine for each
25 * rop code/depth combination. This will result in a extremely large amount
26 * of code. So, we opt for something in between: named rops get their own
27 * routine, unnamed rops are handled by a generic routine.
28 * Basically, what happens is that generic code which looks like:
49 * is specialized for named rops to look like:
69 * pumpSomeBytesSlightlyDifferentE;
75 * i.e. we make the inner loops as tight as possible.
76 * Another optimization is to try to load/store 32 alligned bits at a time from
77 * video memory. Accessing video memory from the CPU is slooooooow, so let's
78 * try to do this as little as possible, even if that means we have to do some
79 * extra operations using main memory.
89 #define USES_DEST(RopCode) ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55))
90 #define USES_SOURCE(RopCode) ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33))
91 #define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f))
96 #define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \
97 __FUNCTION__, __LINE__);
100 #define ROPCODE_BLACKNESS 0x00
101 #define ROPCODE_NOTSRCERASE 0x11
102 #define ROPCODE_NOTSRCCOPY 0x33
103 #define ROPCODE_SRCERASE 0x44
104 #define ROPCODE_DSTINVERT 0x55
105 #define ROPCODE_PATINVERT 0x5a
106 #define ROPCODE_SRCINVERT 0x66
107 #define ROPCODE_SRCAND 0x88
108 #define ROPCODE_NOOP 0xaa
109 #define ROPCODE_MERGEPAINT 0xbb
110 #define ROPCODE_MERGECOPY 0xc0
111 #define ROPCODE_SRCCOPY 0xcc
112 #define ROPCODE_SRCPAINT 0xee
113 #define ROPCODE_PATCOPY 0xf0
114 #define ROPCODE_PATPAINT 0xfb
115 #define ROPCODE_WHITENESS 0xff
117 #define ROPCODE_GENERIC 256 /* Special case */
119 typedef struct _ROPINFO
123 const char *Operation
;
130 #define FLAG_PATTERNSURFACE 0x01
131 #define FLAG_TRIVIALXLATE 0x02
132 #define FLAG_BOTTOMUP 0x04
133 #define FLAG_FORCENOUSESSOURCE 0x08
134 #define FLAG_FORCERAWSOURCEAVAIL 0x10
137 FindRopInfo(unsigned RopCode
)
139 static ROPINFO KnownCodes
[] =
141 { ROPCODE_BLACKNESS
, "BLACKNESS", "0", 0, 0, 0 },
142 { ROPCODE_NOTSRCERASE
, "NOTSRCERASE","~(D | S)", 1, 1, 0 },
143 { ROPCODE_NOTSRCCOPY
, "NOTSRCCOPY", "~S", 0, 1, 0 },
144 { ROPCODE_SRCERASE
, "SRCERASE", "(~D) & S", 1, 1, 0 },
145 { ROPCODE_DSTINVERT
, "DSTINVERT", "~D", 1, 0, 0 },
146 { ROPCODE_PATINVERT
, "PATINVERT", "D ^ P", 1, 0, 1 },
147 { ROPCODE_SRCINVERT
, "SRCINVERT", "D ^ S", 1, 1, 0 },
148 { ROPCODE_SRCAND
, "SRCAND", "D & S", 1, 1, 0 },
149 { ROPCODE_NOOP
, "NOOP", "D", 1, 0, 0 },
150 { ROPCODE_MERGEPAINT
, "MERGEPAINT", "D | (~S)", 1, 1, 0 },
151 { ROPCODE_MERGECOPY
, "MERGECOPY", "S & P", 0, 1, 1 },
152 { ROPCODE_SRCCOPY
, "SRCCOPY", "S", 0, 1, 0 },
153 { ROPCODE_SRCPAINT
, "SRCPAINT", "D | S", 1, 1, 0 },
154 { ROPCODE_PATCOPY
, "PATCOPY", "P", 0, 0, 1 },
155 { ROPCODE_PATPAINT
, "PATPAINT", "D | (~S) | P", 1, 1, 1 },
156 { ROPCODE_WHITENESS
, "WHITENESS", "0xffffffff", 0, 0, 0 },
157 { ROPCODE_GENERIC
, NULL
, NULL
, 1, 1, 1 }
161 for (Index
= 0; Index
< sizeof(KnownCodes
) / sizeof(KnownCodes
[0]); Index
++)
163 if (RopCode
== KnownCodes
[Index
].RopCode
)
165 return KnownCodes
+ Index
;
173 Output(FILE *Out
, const char *Fmt
, ...)
175 static unsigned Indent
= 0;
176 static int AtBOL
= 1;
180 if (strchr(Fmt
, '}'))
187 for (n
= 0; n
< Indent
; n
++)
195 vfprintf(Out
, Fmt
, Args
);
198 if (strchr(Fmt
, '{'))
203 AtBOL
= '\n' == Fmt
[strlen(Fmt
) - 1];
207 PrintRoutineName(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
)
209 if (NULL
!= RopInfo
&& ROPCODE_GENERIC
!= RopInfo
->RopCode
)
211 Output(Out
, "DIB_%uBPP_BitBlt_%s", Bpp
, RopInfo
->Name
);
215 Output(Out
, "DIB_%uBPP_BitBlt_Generic", Bpp
);
220 CreateShiftTables(FILE *Out
)
223 Output(Out
, "static unsigned Shift1Bpp[] =\n");
226 Output(Out
, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n");
227 Output(Out
, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n");
229 Output(Out
, "static unsigned Shift4Bpp[] =\n");
232 Output(Out
, "24, 28, 16, 20, 8, 12, 0, 4\n");
234 Output(Out
, "static unsigned Shift8Bpp[] =\n");
237 Output(Out
, "24, 16, 8, 0\n");
239 Output(Out
, "static unsigned Shift16Bpp[] =\n");
242 Output(Out
, "16, 0\n");
247 CreateOperation(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, unsigned SourceBpp
,
252 const char *Template
;
263 Dest
= "*((PUSHORT) DestPtr)";
268 Dest
= "*((PUCHAR) DestPtr)";
270 Output(Out
, "%s = ", Dest
);
271 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
273 Output(Out
, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)",
278 Template
= RopInfo
->Operation
;
279 while ('\0' != *Template
)
284 Output(Out
, "%sSource", Cast
);
287 Output(Out
, "%sPattern", Cast
);
290 Output(Out
, "%s", Dest
);
293 Output(Out
, "%c", *Template
);
302 CreateBase(FILE *Out
, int Source
, int Flags
, unsigned Bpp
)
304 const char *What
= (Source
? "Source" : "Dest");
307 Output(Out
, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What
, What
);
308 if (0 == (Flags
& FLAG_BOTTOMUP
))
312 Output(Out
, " BltInfo->SourcePoint.y *\n");
316 Output(Out
, " BltInfo->DestRect.top *\n");
323 Output(Out
, " (BltInfo->SourcePoint.y +\n");
324 Output(Out
, " BltInfo->DestRect.bottom -\n");
325 Output(Out
, " BltInfo->DestRect.top - 1) *\n");
329 Output(Out
, " (BltInfo->DestRect.bottom - 1) *\n");
332 Output(Out
, " %sBltInfo->%sSurface->lDelta +\n",
333 Source
? " " : "", What
);
336 Output(Out
, " %sBltInfo->SourcePoint.x",
337 16 < Bpp
? "" : "((");
341 Output(Out
, " BltInfo->DestRect.left");
345 Output(Out
, " / %u", 8 / Bpp
);
349 Output(Out
, " * %u", Bpp
/ 8);
351 if (Source
&& Bpp
<= 16)
353 Output(Out
, ") & ~ 0x3)");
355 Output(Out
, ";\n", Bpp
/ 8);
356 if (Source
&& Bpp
<= 16)
358 Output(Out
, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n",
359 32 / Bpp
, 32 / Bpp
- 1);
364 CreateGetSource(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, int Flags
,
365 unsigned SourceBpp
, unsigned Shift
)
367 const char *AssignOp
;
382 sprintf(After
, ") << %u", Shift
);
385 if (ROPCODE_SRCCOPY
!= RopInfo
->RopCode
||
386 0 == (Flags
& FLAG_TRIVIALXLATE
) || Bpp
!= SourceBpp
)
388 if (0 == (Flags
& FLAG_FORCERAWSOURCEAVAIL
) && SourceBpp
<= 16)
390 Output(Out
, "if (0 == SourcePixels)\n");
392 Output(Out
, "RawSource = *SourcePtr++;\n");
393 Output(Out
, "SourcePixels = %u;\n", 32 / SourceBpp
);
396 Output(Out
, "Source %s (%s", AssignOp
, Before
);
397 if (0 == (Flags
& FLAG_TRIVIALXLATE
))
399 Output(Out
, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s",
400 16 < SourceBpp
? "" : "(");
404 Output(Out
, "*SourcePtr++");
406 else if (24 == SourceBpp
)
408 Output(Out
, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)");
412 Output(Out
, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp
);
414 if (0 == (Flags
& FLAG_TRIVIALXLATE
))
422 Output(Out
, ") & 0x%x)", (1 << SourceBpp
) - 1);
427 Output(Out
, ")%s;\n", After
);
431 Output(Out
, " & 0x%x)%s;\n", (1 << Bpp
) - 1, After
);
435 Output(Out
, "SourcePixels--;\n");
437 else if (24 == SourceBpp
)
439 Output(Out
, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n");
445 CreateCounts(FILE *Out
, unsigned Bpp
)
452 Output(Out
, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n");
456 Output(Out
, "LeftCount = (ULONG_PTR) DestBase & 0x03;\n");
457 Output(Out
, "if ((ULONG)(BltInfo->DestRect.right - BltInfo->DestRect.left) < "
460 Output(Out
, "LeftCount = BltInfo->DestRect.right - "
461 "BltInfo->DestRect.left;\n");
464 Output(Out
, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
465 Output(Out
, " LeftCount) / %u;\n", 32 / Bpp
);
466 Output(Out
, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
467 Output(Out
, " LeftCount - %u * CenterCount);\n", 32 / Bpp
);
471 Output(Out
, "CenterCount = BltInfo->DestRect.right - BltInfo->DestRect.left;\n");
476 CreateSetSinglePixel(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, int Flags
,
479 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
481 CreateGetSource(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
, 0);
484 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
486 Output(Out
, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n");
487 Output(Out
, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
489 Output(Out
, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
492 if ((RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
) &&
494 (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
)))
498 CreateOperation(Out
, Bpp
, RopInfo
, SourceBpp
, 16);
502 Output(Out
, "DestPtr = (PULONG)((char *) DestPtr + %u);\n", Bpp
/ 8);
506 CreateBitCase(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, int Flags
,
512 if (RopInfo
->UsesSource
)
514 if (0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
516 CreateBase(Out
, 1, Flags
, SourceBpp
);
518 CreateBase(Out
, 0, Flags
, Bpp
);
519 CreateCounts(Out
, Bpp
);
522 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
524 if (0 == (Flags
& FLAG_BOTTOMUP
))
526 Output(Out
, "PatternY = (BltInfo->DestRect.top - BltInfo->BrushOrigin.y) %%\n");
527 Output(Out
, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
531 Output(Out
, "PatternY = (BltInfo->DestRect.bottom - 1 -\n");
532 Output(Out
, " BltInfo->BrushOrigin.y) %%\n");
533 Output(Out
, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
536 if (ROPCODE_SRCCOPY
== RopInfo
->RopCode
&&
537 0 != (Flags
& FLAG_TRIVIALXLATE
) && Bpp
== SourceBpp
)
539 Output(Out
, "CenterCount = %u * (BltInfo->DestRect.right -\n", Bpp
>> 3);
540 Output(Out
, " BltInfo->DestRect.left);\n");
542 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
544 Output(Out
, "BasePatternX = (BltInfo->DestRect.left - BltInfo->BrushOrigin.x) %%\n");
545 Output(Out
, " BltInfo->PatternSurface->sizlBitmap.cx;\n");
548 Output(Out
, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n");
550 if (ROPCODE_SRCCOPY
!= RopInfo
->RopCode
||
551 0 == (Flags
& FLAG_TRIVIALXLATE
) || Bpp
!= SourceBpp
)
553 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
555 Output(Out
, "SourcePtr = (PULONG) SourceBase;\n");
558 Output(Out
, "RawSource = *SourcePtr++;\n");
559 Output(Out
, "SourcePixels = BaseSourcePixels;\n");
562 Output(Out
, "DestPtr = (PULONG) DestBase;\n");
565 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
567 Output(Out
, "PatternX = BasePatternX;\n");
570 if (ROPCODE_SRCCOPY
== RopInfo
->RopCode
&&
571 0 != (Flags
& FLAG_TRIVIALXLATE
) && Bpp
== SourceBpp
)
573 Output(Out
, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n");
583 Output(Out
, "if (0 != LeftCount)\n");
587 Output(Out
, "for (i = 0; i < LeftCount; i++)\n");
590 CreateSetSinglePixel(Out
, Bpp
, RopInfo
,
591 (16 == Bpp
? Flags
| FLAG_FORCERAWSOURCEAVAIL
:
597 Output(Out
, "for (i = 0; i < CenterCount; i++)\n");
599 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
601 for (Partial
= 0; Partial
< 32 / Bpp
; Partial
++)
603 CreateGetSource(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
,
609 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
611 for (Partial
= 0; Partial
< 32 / Bpp
; Partial
++)
615 Output(Out
, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n");
619 Output(Out
, "Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY) << %u;\n", Partial
* Bpp
);
621 Output(Out
, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
623 Output(Out
, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
628 CreateOperation(Out
, Bpp
, RopInfo
, SourceBpp
, 32);
632 Output(Out
, "DestPtr++;\n");
639 Output(Out
, "if (0 != RightCount)\n");
643 Output(Out
, "for (i = 0; i < RightCount; i++)\n");
646 CreateSetSinglePixel(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
);
651 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
653 if (0 == (Flags
& FLAG_BOTTOMUP
))
655 Output(Out
, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n");
657 Output(Out
, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n");
662 Output(Out
, "if (0 == PatternY--)\n");
664 Output(Out
, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n");
669 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
671 Output(Out
, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n",
672 0 == (Flags
& FLAG_BOTTOMUP
) ? '+' : '-');
674 Output(Out
, "DestBase %c= BltInfo->DestSurface->lDelta;\n",
675 0 == (Flags
& FLAG_BOTTOMUP
) ? '+' : '-');
680 CreateActionBlock(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
,
683 static unsigned SourceBpp
[ ] =
684 { 1, 4, 8, 16, 24, 32 };
688 if (RopInfo
->UsesSource
)
690 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
692 Output(Out
, "if (UsesSource)\n");
695 Output(Out
, "switch (BltInfo->SourceSurface->iBitmapFormat)\n");
698 BppIndex
< sizeof(SourceBpp
) / sizeof(unsigned);
701 Output(Out
, "case BMF_%uBPP:\n", SourceBpp
[BppIndex
]);
703 if (Bpp
== SourceBpp
[BppIndex
])
705 Output(Out
, "if (NULL == BltInfo->XlateSourceToDest ||\n");
706 Output(Out
, " 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n");
708 Output(Out
, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
710 CreateBitCase(Out
, Bpp
, RopInfo
,
711 Flags
| FLAG_TRIVIALXLATE
,
712 SourceBpp
[BppIndex
]);
715 Output(Out
, "else\n");
717 CreateBitCase(Out
, Bpp
, RopInfo
,
718 Flags
| FLAG_BOTTOMUP
| FLAG_TRIVIALXLATE
,
719 SourceBpp
[BppIndex
]);
723 Output(Out
, "else\n");
725 Output(Out
, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
727 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
[BppIndex
]);
730 Output(Out
, "else\n");
732 CreateBitCase(Out
, Bpp
, RopInfo
,
733 Flags
| FLAG_BOTTOMUP
,
734 SourceBpp
[BppIndex
]);
741 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
,
742 SourceBpp
[BppIndex
]);
745 Output(Out
, "break;\n");
749 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
752 Output(Out
, "else\n");
754 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
| FLAG_FORCENOUSESSOURCE
, 0);
761 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
, 0);
766 CreatePrimitive(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
)
773 Output(Out
, "static void\n");
774 PrintRoutineName(Out
, Bpp
, RopInfo
);
775 Output(Out
, "(PBLTINFO BltInfo)\n");
777 if (ROPCODE_BLACKNESS
== RopInfo
->RopCode
)
779 Output(Out
, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
780 "&BltInfo->DestRect, 0x0);\n", Bpp
);
782 else if (ROPCODE_WHITENESS
== RopInfo
->RopCode
)
784 Output(Out
, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
785 "&BltInfo->DestRect, ~0);\n", Bpp
);
787 else if (ROPCODE_NOOP
== RopInfo
->RopCode
)
789 Output(Out
, "return;\n");
793 Output(Out
, "ULONG LineIndex, LineCount;\n");
794 Output(Out
, "ULONG i;\n");
795 if (RopInfo
->UsesPattern
)
797 Output(Out
, "LONG PatternX =0, PatternY = 0, BasePatternX = 0;\n");
800 if (RopInfo
->UsesSource
)
802 Output(Out
, "ULONG Source = 0");
805 if (RopInfo
->UsesPattern
)
807 Output(Out
, "%s Pattern = 0", First
? "ULONG" : ",");
814 Output(Out
, "char *DestBase;\n");
815 Output(Out
, "PULONG DestPtr;\n");
816 if (RopInfo
->UsesSource
)
818 Output(Out
, "char *SourceBase;\n");
819 Output(Out
, "PULONG SourcePtr;\n");
820 Output(Out
, "ULONG RawSource;\n");
821 Output(Out
, "unsigned SourcePixels, BaseSourcePixels;\n");
825 Output(Out
, "ULONG CenterCount;\n");
829 Output(Out
, "ULONG LeftCount, CenterCount, RightCount;\n");
831 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
833 Output(Out
, "BOOLEAN UsesSource, UsesPattern;\n");
835 Output(Out
, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n");
836 Output(Out
, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n");
839 if (! RopInfo
->UsesSource
)
841 CreateBase(Out
, 0, 0, Bpp
);
842 CreateCounts(Out
, Bpp
);
845 Output(Out
, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n");
848 if (RopInfo
->UsesPattern
)
850 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
852 Output(Out
, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n");
856 Output(Out
, "if (NULL != BltInfo->PatternSurface)\n");
859 CreateActionBlock(Out
, Bpp
, RopInfo
, FLAG_PATTERNSURFACE
);
862 Output(Out
, "else\n");
864 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
866 Output(Out
, "if (UsesPattern)\n");
869 for (Partial
= 0; Partial
< 32 / Bpp
; Partial
++)
873 Output(Out
, "if (!BltInfo->Brush)\n");
875 Output(Out
, "Pattern = 0;\n");
877 Output(Out
, "else\n");
879 Output(Out
, "Pattern = BltInfo->Brush->iSolidColor");
883 Output(Out
, " (BltInfo->Brush->iSolidColor << %d)",
886 if (32 / Bpp
<= Partial
+ 1)
896 if (ROPCODE_PATINVERT
== RopInfo
->RopCode
||
897 ROPCODE_MERGECOPY
== RopInfo
->RopCode
)
899 Output(Out
, "if (0 == Pattern)\n");
901 if (ROPCODE_MERGECOPY
== RopInfo
->RopCode
)
903 Output(Out
, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
904 "&BltInfo->DestRect, 0x0);\n", Bpp
);
906 Output(Out
, "return;\n");
909 else if (ROPCODE_PATPAINT
== RopInfo
->RopCode
)
911 Output(Out
, "if ((~0) == Pattern)\n");
913 Output(Out
, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
914 "&BltInfo->DestRect, ~0);\n", Bpp
);
915 Output(Out
, "return;\n");
918 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
922 CreateActionBlock(Out
, Bpp
, RopInfo
, 0);
928 CreateActionBlock(Out
, Bpp
, RopInfo
, 0);
936 CreateTable(FILE *Out
, unsigned Bpp
)
942 Output(Out
, "static void (*PrimitivesTable[256])(PBLTINFO) =\n");
944 for (RopCode
= 0; RopCode
< 256; RopCode
++)
946 PrintRoutineName(Out
, Bpp
, FindRopInfo(RopCode
));
957 CreateBitBlt(FILE *Out
, unsigned Bpp
)
961 Output(Out
, "BOOLEAN\n");
962 Output(Out
, "DIB_%uBPP_BitBlt(PBLTINFO BltInfo)\n", Bpp
);
964 Output(Out
, "PrimitivesTable[BltInfo->Rop4 & 0xff](BltInfo);\n");
966 Output(Out
, "return TRUE;\n");
971 Generate(char *OutputDir
, unsigned Bpp
)
978 FileName
= malloc(strlen(OutputDir
) + 12);
979 if (NULL
== FileName
)
981 fprintf(stderr
, "Out of memory\n");
984 strcpy(FileName
, OutputDir
);
985 if ('/' != FileName
[strlen(FileName
) - 1])
987 strcat(FileName
, "/");
989 sprintf(FileName
+ strlen(FileName
), "dib%ugen.c", Bpp
);
991 Out
= fopen(FileName
, "w");
995 perror("Error opening output file");
1000 Output(Out
, "/* This is a generated file. Please do not edit */\n");
1002 Output(Out
, "#include <win32k.h>\n");
1003 CreateShiftTables(Out
);
1005 RopInfo
= FindRopInfo(ROPCODE_GENERIC
);
1006 CreatePrimitive(Out
, Bpp
, RopInfo
);
1007 for (RopCode
= 0; RopCode
< 256; RopCode
++)
1009 RopInfo
= FindRopInfo(RopCode
);
1010 if (NULL
!= RopInfo
)
1012 CreatePrimitive(Out
, Bpp
, RopInfo
);
1015 CreateTable(Out
, Bpp
);
1016 CreateBitBlt(Out
, Bpp
);
1022 main(int argc
, char *argv
[])
1025 static unsigned DestBpp
[] =
1031 for (Index
= 0; Index
< sizeof(DestBpp
) / sizeof(DestBpp
[0]); Index
++)
1033 Generate(argv
[1], DestBpp
[Index
]);