2 * Copyright 2005 Ge van Geldorp (gvg@reactos.com).
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License as published by the
6 * Free Software Foundation; either version 2.1 of the License, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * 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 License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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
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
, char *Fmt
, ...)
175 static unsigned Indent
= 0;
176 static int AtBOL
= 1;
180 if (NULL
!= strchr(Fmt
, '{') && 0 != Indent
)
184 else if (NULL
!= strchr(Fmt
, '}'))
190 for (n
= 0; n
< Indent
; n
++)
198 vfprintf(Out
, Fmt
, Args
);
201 if (NULL
!= strchr(Fmt
, '{'))
205 else if (NULL
!= strchr(Fmt
, '}') && 0 != Indent
)
209 AtBOL
= '\n' == Fmt
[strlen(Fmt
) - 1];
213 PrintRoutineName(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
)
215 if (NULL
!= RopInfo
&& ROPCODE_GENERIC
!= RopInfo
->RopCode
)
217 Output(Out
, "DIB_%uBPP_BitBlt_%s", Bpp
, RopInfo
->Name
);
221 Output(Out
, "DIB_%uBPP_BitBlt_Generic", Bpp
);
226 CreateShiftTables(FILE *Out
)
229 Output(Out
, "static unsigned Shift1Bpp[] =\n");
232 Output(Out
, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n");
233 Output(Out
, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n");
235 Output(Out
, "static unsigned Shift4Bpp[] =\n");
238 Output(Out
, "24, 28, 16, 20, 8, 12, 0, 4\n");
240 Output(Out
, "static unsigned Shift8Bpp[] =\n");
243 Output(Out
, "24, 16, 8, 0\n");
245 Output(Out
, "static unsigned Shift16Bpp[] =\n");
248 Output(Out
, "16, 0\n");
253 CreateOperation(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, unsigned SourceBpp
,
269 Dest
= "*((PUSHORT) DestPtr)";
274 Dest
= "*((PUCHAR) DestPtr)";
276 Output(Out
, "%s = ", Dest
);
277 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
279 Output(Out
, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)",
284 Template
= RopInfo
->Operation
;
285 while ('\0' != *Template
)
290 Output(Out
, "%sSource", Cast
);
293 Output(Out
, "%sPattern", Cast
);
296 Output(Out
, "%s", Dest
);
299 Output(Out
, "%c", *Template
);
308 CreateBase(FILE *Out
, int Source
, int Flags
, unsigned Bpp
)
310 char *What
= (Source
? "Source" : "Dest");
313 Output(Out
, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What
, What
);
314 if (0 == (Flags
& FLAG_BOTTOMUP
))
318 Output(Out
, " BltInfo->SourcePoint.y *\n");
322 Output(Out
, " BltInfo->DestRect.top *\n");
329 Output(Out
, " (BltInfo->SourcePoint.y +\n");
330 Output(Out
, " BltInfo->DestRect.bottom -\n");
331 Output(Out
, " BltInfo->DestRect.top - 1) *\n");
335 Output(Out
, " (BltInfo->DestRect.bottom - 1) *\n");
338 Output(Out
, " %sBltInfo->%sSurface->lDelta +\n",
339 Source
? " " : "", What
);
342 Output(Out
, " %sBltInfo->SourcePoint.x",
343 16 < Bpp
? "" : "((");
347 Output(Out
, " BltInfo->DestRect.left");
351 Output(Out
, " / %u", 8 / Bpp
);
355 Output(Out
, " * %u", Bpp
/ 8);
357 if (Source
&& Bpp
<= 16)
359 Output(Out
, ") & ~ 0x3)");
361 Output(Out
, ";\n", Bpp
/ 8);
362 if (Source
&& Bpp
<= 16)
364 Output(Out
, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n",
365 32 / Bpp
, 32 / Bpp
- 1);
370 CreateGetSource(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, int Flags
,
371 unsigned SourceBpp
, unsigned Shift
)
388 sprintf(After
, ") << %u", Shift
);
391 if (ROPCODE_SRCCOPY
!= RopInfo
->RopCode
||
392 0 == (Flags
& FLAG_TRIVIALXLATE
) || Bpp
!= SourceBpp
)
394 if (0 == (Flags
& FLAG_FORCERAWSOURCEAVAIL
) && SourceBpp
<= 16)
396 Output(Out
, "if (0 == SourcePixels)\n");
398 Output(Out
, "RawSource = *SourcePtr++;\n");
399 Output(Out
, "SourcePixels = %u;\n", 32 / SourceBpp
);
402 Output(Out
, "Source %s (%s", AssignOp
, Before
);
403 if (0 == (Flags
& FLAG_TRIVIALXLATE
))
405 Output(Out
, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s",
406 16 < SourceBpp
? "" : "(");
410 Output(Out
, "*SourcePtr++");
412 else if (24 == SourceBpp
)
414 Output(Out
, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)");
418 Output(Out
, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp
);
420 if (0 == (Flags
& FLAG_TRIVIALXLATE
))
428 Output(Out
, ") & 0x%x)", (1 << SourceBpp
) - 1);
433 Output(Out
, ")%s;\n", After
);
437 Output(Out
, " & 0x%x)%s;\n", (1 << Bpp
) - 1, After
);
441 Output(Out
, "SourcePixels--;\n");
443 else if (24 == SourceBpp
)
445 Output(Out
, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n");
451 CreateCounts(FILE *Out
, unsigned Bpp
)
458 Output(Out
, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n");
462 Output(Out
, "LeftCount = (ULONG_PTR) DestBase & 0x03;\n");
463 Output(Out
, "if (BltInfo->DestRect.right - BltInfo->DestRect.left < "
466 Output(Out
, "LeftCount = BltInfo->DestRect.right - "
467 "BltInfo->DestRect.left;\n");
470 Output(Out
, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
471 Output(Out
, " LeftCount) / %u;\n", 32 / Bpp
);
472 Output(Out
, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
473 Output(Out
, " LeftCount - %u * CenterCount);\n", 32 / Bpp
);
477 Output(Out
, "CenterCount = BltInfo->DestRect.right - BltInfo->DestRect.left;\n");
482 CreateSetSinglePixel(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, int Flags
,
485 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
487 CreateGetSource(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
, 0);
490 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
492 Output(Out
, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
493 Output(Out
, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
495 Output(Out
, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
498 if ((RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
) &&
500 (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
)))
504 CreateOperation(Out
, Bpp
, RopInfo
, SourceBpp
, 16);
508 Output(Out
, "DestPtr = (PULONG)((char *) DestPtr + %u);\n", Bpp
/ 8);
512 CreateBitCase(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
, int Flags
,
518 if (RopInfo
->UsesSource
)
520 if (0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
522 CreateBase(Out
, 1, Flags
, SourceBpp
);
524 CreateBase(Out
, 0, Flags
, Bpp
);
525 CreateCounts(Out
, Bpp
);
528 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
530 if (0 == (Flags
& FLAG_BOTTOMUP
))
532 Output(Out
, "PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %%\n");
533 Output(Out
, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
537 Output(Out
, "PatternY = (BltInfo->DestRect.bottom - 1 +\n");
538 Output(Out
, " BltInfo->BrushOrigin.y) %%\n");
539 Output(Out
, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
542 if (ROPCODE_SRCCOPY
== RopInfo
->RopCode
&&
543 0 != (Flags
& FLAG_TRIVIALXLATE
) && Bpp
== SourceBpp
)
545 Output(Out
, "CenterCount = 2 * (BltInfo->DestRect.right -\n");
546 Output(Out
, " BltInfo->DestRect.left);\n");
548 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
550 Output(Out
, "BasePatternX = (BltInfo->DestRect.left + BltInfo->BrushOrigin.x) %%\n");
551 Output(Out
, " BltInfo->PatternSurface->sizlBitmap.cx;\n");
554 Output(Out
, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n");
556 if (ROPCODE_SRCCOPY
!= RopInfo
->RopCode
||
557 0 == (Flags
& FLAG_TRIVIALXLATE
) || Bpp
!= SourceBpp
)
559 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
561 Output(Out
, "SourcePtr = (PULONG) SourceBase;\n");
564 Output(Out
, "RawSource = *SourcePtr++;\n");
565 Output(Out
, "SourcePixels = BaseSourcePixels;\n");
568 Output(Out
, "DestPtr = (PULONG) DestBase;\n");
571 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
573 Output(Out
, "PatternX = BasePatternX;\n");
576 if (ROPCODE_SRCCOPY
== RopInfo
->RopCode
&&
577 0 != (Flags
& FLAG_TRIVIALXLATE
) && Bpp
== SourceBpp
)
579 Output(Out
, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n");
589 Output(Out
, "if (0 != LeftCount)\n");
593 Output(Out
, "for (i = 0; i < LeftCount; i++)\n");
596 CreateSetSinglePixel(Out
, Bpp
, RopInfo
,
597 (16 == Bpp
? Flags
| FLAG_FORCERAWSOURCEAVAIL
:
603 Output(Out
, "for (i = 0; i < CenterCount; i++)\n");
605 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
607 for (Partial
= 0; Partial
< 32 / Bpp
; Partial
++)
609 CreateGetSource(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
,
615 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
617 for (Partial
= 0; Partial
< 32 / Bpp
; Partial
++)
621 Output(Out
, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
625 Output(Out
, "Pattern |= DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest) << %u;\n", Partial
* Bpp
);
627 Output(Out
, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
629 Output(Out
, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
634 CreateOperation(Out
, Bpp
, RopInfo
, SourceBpp
, 32);
638 Output(Out
, "DestPtr++;\n");
645 Output(Out
, "if (0 != RightCount)\n");
649 Output(Out
, "for (i = 0; i < RightCount; i++)\n");
652 CreateSetSinglePixel(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
);
657 if (RopInfo
->UsesPattern
&& 0 != (Flags
& FLAG_PATTERNSURFACE
))
659 if (0 == (Flags
& FLAG_BOTTOMUP
))
661 Output(Out
, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n");
663 Output(Out
, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n");
668 Output(Out
, "if (0 == PatternY--)\n");
670 Output(Out
, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n");
675 if (RopInfo
->UsesSource
&& 0 == (Flags
& FLAG_FORCENOUSESSOURCE
))
677 Output(Out
, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n",
678 0 == (Flags
& FLAG_BOTTOMUP
) ? '+' : '-');
680 Output(Out
, "DestBase %c= BltInfo->DestSurface->lDelta;\n",
681 0 == (Flags
& FLAG_BOTTOMUP
) ? '+' : '-');
686 CreateActionBlock(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
,
689 static unsigned SourceBpp
[ ] =
690 { 1, 4, 8, 16, 24, 32 };
694 if (RopInfo
->UsesSource
)
696 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
698 Output(Out
, "if (UsesSource)\n");
701 Output(Out
, "switch (BltInfo->SourceSurface->iBitmapFormat)\n");
704 BppIndex
< sizeof(SourceBpp
) / sizeof(unsigned);
707 Output(Out
, "case BMF_%uBPP:\n", SourceBpp
[BppIndex
]);
709 if (Bpp
== SourceBpp
[BppIndex
])
711 Output(Out
, "if (NULL == BltInfo->XlateSourceToDest ||\n");
712 Output(Out
, " 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n");
714 Output(Out
, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
716 CreateBitCase(Out
, Bpp
, RopInfo
,
717 Flags
| FLAG_TRIVIALXLATE
,
718 SourceBpp
[BppIndex
]);
721 Output(Out
, "else\n");
723 CreateBitCase(Out
, Bpp
, RopInfo
,
724 Flags
| FLAG_BOTTOMUP
| FLAG_TRIVIALXLATE
,
725 SourceBpp
[BppIndex
]);
729 Output(Out
, "else\n");
731 Output(Out
, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
733 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
, SourceBpp
[BppIndex
]);
736 Output(Out
, "else\n");
738 CreateBitCase(Out
, Bpp
, RopInfo
,
739 Flags
| FLAG_BOTTOMUP
,
740 SourceBpp
[BppIndex
]);
747 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
,
748 SourceBpp
[BppIndex
]);
751 Output(Out
, "break;\n");
755 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
758 Output(Out
, "else\n");
760 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
| FLAG_FORCENOUSESSOURCE
, 0);
767 CreateBitCase(Out
, Bpp
, RopInfo
, Flags
, 0);
772 CreatePrimitive(FILE *Out
, unsigned Bpp
, PROPINFO RopInfo
)
779 Output(Out
, "static void\n");
780 PrintRoutineName(Out
, Bpp
, RopInfo
);
781 Output(Out
, "(PBLTINFO BltInfo)\n");
783 if (ROPCODE_BLACKNESS
== RopInfo
->RopCode
)
785 Output(Out
, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
786 "&BltInfo->DestRect, 0x0);\n", Bpp
);
788 else if (ROPCODE_WHITENESS
== RopInfo
->RopCode
)
790 Output(Out
, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
791 "&BltInfo->DestRect, ~0);\n", Bpp
);
793 else if (ROPCODE_NOOP
== RopInfo
->RopCode
)
795 Output(Out
, "return;\n");
799 Output(Out
, "ULONG LineIndex, LineCount;\n");
800 Output(Out
, "ULONG i;\n");
801 if (RopInfo
->UsesPattern
)
803 Output(Out
, "ULONG PatternX =0, PatternY = 0, BasePatternX = 0;\n");
806 if (RopInfo
->UsesSource
)
808 Output(Out
, "ULONG Source = 0");
811 if (RopInfo
->UsesPattern
)
813 Output(Out
, "%s Pattern = 0", First
? "ULONG" : ",");
820 Output(Out
, "char *DestBase;\n");
821 Output(Out
, "PULONG DestPtr;\n");
822 if (RopInfo
->UsesSource
)
824 Output(Out
, "char *SourceBase;\n");
825 Output(Out
, "PULONG SourcePtr;\n");
826 Output(Out
, "ULONG RawSource;\n");
827 Output(Out
, "unsigned SourcePixels, BaseSourcePixels;\n");
831 Output(Out
, "ULONG CenterCount;\n");
835 Output(Out
, "ULONG LeftCount, CenterCount, RightCount;\n");
837 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
839 Output(Out
, "BOOLEAN UsesDest, UsesSource, UsesPattern;\n");
841 Output(Out
, "UsesDest = ROP4_USES_DEST(BltInfo->Rop4);\n");
842 Output(Out
, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n");
843 Output(Out
, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n");
846 if (! RopInfo
->UsesSource
)
848 CreateBase(Out
, 0, 0, Bpp
);
849 CreateCounts(Out
, Bpp
);
852 Output(Out
, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n");
855 if (RopInfo
->UsesPattern
)
857 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
859 Output(Out
, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n");
863 Output(Out
, "if (NULL != BltInfo->PatternSurface)\n");
866 CreateActionBlock(Out
, Bpp
, RopInfo
, FLAG_PATTERNSURFACE
);
869 Output(Out
, "else\n");
871 if (ROPCODE_GENERIC
== RopInfo
->RopCode
)
873 Output(Out
, "if (UsesPattern)\n");
876 for (Partial
= 0; Partial
< 32 / Bpp
; Partial
++)
880 Output(Out
, "Pattern = BltInfo->Brush->iSolidColor");
884 Output(Out
, " (BltInfo->Brush->iSolidColor << %d)",
887 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 <w32k.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
[] =
1028 for (Index
= 0; Index
< sizeof(DestBpp
) / sizeof(DestBpp
[0]); Index
++)
1030 Generate(argv
[1], DestBpp
[Index
]);