--- trunk/reactos/tools/gendib/gendib.c 2005-07-05 17:08:48 UTC (rev 16429)
+++ trunk/reactos/tools/gendib/gendib.c 2005-07-05 17:08:58 UTC (rev 16430)
@@ -0,0 +1,926 @@
+/*
+ * Copyright 2005 Ge van Geldorp (gvg@reactos.com).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * This is a code generator. It outputs C code which can be compiled using the
+ * standard build tools. It is used to generate code for the DIB Blt routines.
+ * There are a lot of possible Blt routines (256 rop codes, for 6 different
+ * bit depths). It is possible to use a generic Blt routine which handles all
+ * rop codes and all depths. The drawback is that it will be relatively slow.
+ * The other extreme is to write (generate) a separate Blt routine for each
+ * rop code/depth combination. This will result in a extremely large amount
+ * of code. So, we opt for something in between: named rops get their own
+ * routine, unnamed rops are handled by a generic routine.
+ * Basically, what happens is that generic code which looks like:
+ *
+ * for (...)
+ * {
+ * if (CondA)
+ * {
+ * doSomethingA;
+ * }
+ * for (...)
+ * {
+ * if (CondB)
+ * {
+ * doSomethingB;
+ * }
+ * else
+ * {
+ * doSomethingElseB;
+ * }
+ * }
+ * }
+ *
+ * is specialized for named rops to look like:
+ *
+ * if (condC)
+ * {
+ * if (condD)
+ * {
+ * for (...)
+ * {
+ * for (...)
+ * {
+ * pumpSomeBytes;
+ * }
+ * }
+ * }
+ * else
+ * {
+ * for (...)
+ * {
+ * for (...)
+ * {
+ * pumpSomeBytesSlightlyDifferentE;
+ * }
+ * }
+ * }
+ * }
+ *
+ * i.e. we make the inner loops as tight as possible.
+ * Another optimization is to try to load/store 32 alligned bits at a time from
+ * video memory. Accessing video memory from the CPU is slooooooow, so let's
+ * try to do this as little as possible, even if that means we have to do some
+ * extra operations using main memory.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NDEBUG
+
+#define USES_DEST(RopCode) ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55))
+#define USES_SOURCE(RopCode) ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33))
+#define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f))
+
+#ifdef NDEBUG
+#define MARK(Out)
+#else
+#define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \
+ __FUNCTION__, __LINE__);
+#endif
+
+#define ROPCODE_BLACKNESS 0x00
+#define ROPCODE_NOTSRCERASE 0x11
+#define ROPCODE_NOTSRCCOPY 0x33
+#define ROPCODE_SRCERASE 0x44
+#define ROPCODE_DSTINVERT 0x55
+#define ROPCODE_PATINVERT 0x5a
+#define ROPCODE_SRCINVERT 0x66
+#define ROPCODE_SRCAND 0x88
+#define ROPCODE_NOOP 0xaa
+#define ROPCODE_MERGEPAINT 0xbb
+#define ROPCODE_MERGECOPY 0xc0
+#define ROPCODE_SRCCOPY 0xcc
+#define ROPCODE_SRCPAINT 0xee
+#define ROPCODE_PATCOPY 0xf0
+#define ROPCODE_PATPAINT 0xfb
+#define ROPCODE_WHITENESS 0xff
+
+#define ROPCODE_GENERIC 256 /* Special case */
+
+typedef struct _ROPINFO
+ {
+ unsigned RopCode;
+ char *Name;
+ char *Operation;
+ int UsesDest;
+ int UsesSource;
+ int UsesPattern;
+ }
+ROPINFO, *PROPINFO;
+
+#define FLAG_PATTERNSURFACE 0x01
+#define FLAG_TRIVIALXLATE 0x02
+#define FLAG_BOTTOMUP 0x04
+#define FLAG_FORCENOUSESSOURCE 0x08
+#define FLAG_FORCERAWSOURCEAVAIL 0x10
+
+static PROPINFO
+FindRopInfo(unsigned RopCode)
+{
+ static ROPINFO KnownCodes[] =
+ {
+ { ROPCODE_BLACKNESS, "BLACKNESS", "0", 0, 0, 0 },
+ { ROPCODE_NOTSRCERASE, "NOTSRCERASE","~(D | S)", 1, 1, 0 },
+ { ROPCODE_NOTSRCCOPY, "NOTSRCCOPY", "~S", 0, 1, 0 },
+ { ROPCODE_SRCERASE, "SRCERASE", "(~D) & S", 1, 1, 0 },
+ { ROPCODE_DSTINVERT, "DSTINVERT", "~D", 1, 0, 0 },
+ { ROPCODE_PATINVERT, "PATINVERT", "D ^ P", 1, 0, 1 },
+ { ROPCODE_SRCINVERT, "SRCINVERT", "D ^ S", 1, 1, 0 },
+ { ROPCODE_SRCAND, "SRCAND", "D & S", 1, 1, 0 },
+ { ROPCODE_NOOP, "NOOP", "D", 1, 0, 0 },
+ { ROPCODE_MERGEPAINT, "MERGEPAINT", "D & (~S)", 1, 1, 0 },
+ { ROPCODE_MERGECOPY, "MERGECOPY", "S & P", 0, 1, 1 },
+ { ROPCODE_SRCCOPY, "SRCCOPY", "S", 0, 1, 0 },
+ { ROPCODE_SRCPAINT, "SRCPAINT", "D | S", 1, 1, 0 },
+ { ROPCODE_PATCOPY, "PATCOPY", "P", 0, 0, 1 },
+ { ROPCODE_PATPAINT, "PATPAINT", "D | (~S) | P", 1, 1, 1 },
+ { ROPCODE_WHITENESS, "WHITENESS", "0xffffffff", 0, 0, 0 },
+ { ROPCODE_GENERIC, NULL, NULL, 1, 1, 1 }
+ };
+ unsigned Index;
+
+ for (Index = 0; Index < sizeof(KnownCodes) / sizeof(KnownCodes[0]); Index++)
+ {
+ if (RopCode == KnownCodes[Index].RopCode)
+ {
+ return KnownCodes + Index;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+Output(FILE *Out, char *Fmt, ...)
+{
+ static unsigned Indent = 0;
+ static int AtBOL = 1;
+ unsigned n;
+ va_list Args;
+
+ if (NULL != strchr(Fmt, '{') && 0 != Indent)
+ {
+ Indent += 2;
+ }
+ else if (NULL != strchr(Fmt, '}'))
+ {
+ Indent -= 2;
+ }
+ if (AtBOL)
+ {
+ for (n = 0; n < Indent; n++)
+ {
+ putc(' ', Out);
+ }
+ AtBOL = 0;
+ }
+
+ va_start(Args, Fmt);
+ vfprintf(Out, Fmt, Args);
+ va_end(Args);
+
+ if (NULL != strchr(Fmt, '{'))
+ {
+ Indent += 2;
+ }
+ else if (NULL != strchr(Fmt, '}') && 0 != Indent)
+ {
+ Indent -= 2;
+ }
+ AtBOL = '\n' == Fmt[strlen(Fmt) - 1];
+}
+
+static void
+PrintRoutineName(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
+{
+ if (NULL != RopInfo && ROPCODE_GENERIC != RopInfo->RopCode)
+ {
+ Output(Out, "DIB_%uBPP_BitBlt_%s", Bpp, RopInfo->Name);
+ }
+ else
+ {
+ Output(Out, "DIB_%uBPP_BitBlt_Generic", Bpp);
+ }
+}
+
+static void
+CreateShiftTables(FILE *Out)
+{
+ Output(Out, "\n");
+ Output(Out, "static unsigned Shift1Bpp[] =\n");
+ Output(Out, "{\n");
+ Output(Out, "0,\n");
+ Output(Out, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n");
+ Output(Out, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n");
+ Output(Out, "};\n");
+ Output(Out, "static unsigned Shift4Bpp[] =\n");
+ Output(Out, "{\n");
+ Output(Out, "0,\n");
+ Output(Out, "24, 28, 16, 20, 8, 12, 0, 4\n");
+ Output(Out, "};\n");
+ Output(Out, "static unsigned Shift8Bpp[] =\n");
+ Output(Out, "{\n");
+ Output(Out, "0,\n");
+ Output(Out, "24, 16, 8, 0\n");
+ Output(Out, "};\n");
+ Output(Out, "static unsigned Shift16Bpp[] =\n");
+ Output(Out, "{\n");
+ Output(Out, "0,\n");
+ Output(Out, "16, 0\n");
+ Output(Out, "};\n");
+}
+
+static void
+CreateOperation(FILE *Out, unsigned Bpp, PROPINFO RopInfo, unsigned SourceBpp,
+ unsigned Bits)
+{
+ char *Cast;
+ char *Dest;
+ char *Template;
+
+ MARK(Out);
+ if (32 == Bits)
+ {
+ Cast = "";
+ Dest = "*DestPtr";
+ }
+ else
+ {
+ Cast = "(USHORT) ";
+ Dest = "*((PUSHORT) DestPtr)";
+ }
+ Output(Out, "%s = ", Dest);
+ if (ROPCODE_GENERIC == RopInfo->RopCode)
+ {
+ Output(Out, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)",
+ Cast, Dest);
+ }
+ else
+ {
+ Template = RopInfo->Operation;
+ while ('\0' != *Template)
+ {
+ switch(*Template)
+ {
+ case 'S':
+ Output(Out, "%sSource", Cast);
+ break;
+ case 'P':
+ Output(Out, "%sPattern", Cast);
+ break;
+ case 'D':
+ Output(Out, "%s", Dest);
+ break;
+ default:
+ Output(Out, "%c", *Template);
+ break;
+ }
+ Template++;
+ }
+ }
+}
+
+static void
+CreateBase(FILE *Out, int Source, int Flags, unsigned Bpp)
+{
+ char *What = (Source ? "Source" : "Dest");
+
+ MARK(Out);
+ Output(Out, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What, What);
+ if (0 == (Flags & FLAG_BOTTOMUP))
+ {
+ if (Source)
+ {
+ Output(Out, " BltInfo->SourcePoint.y *\n");
+ }
+ else
+ {
+ Output(Out, " BltInfo->DestRect.top *\n");
+ }
+ }
+ else
+ {
+ if (Source)
+ {
+ Output(Out, " (BltInfo->SourcePoint.y +\n");
+ Output(Out, " BltInfo->DestRect.bottom -\n");
+ Output(Out, " BltInfo->DestRect.top - 1) *\n");
+ }
+ else
+ {
+ Output(Out, " (BltInfo->DestRect.bottom - 1) *\n");
+ }
+ }
+ Output(Out, " %sBltInfo->%sSurface->lDelta +\n",
+ Source ? " " : "", What);
+ if (Source)
+ {
+ Output(Out, " %sBltInfo->SourcePoint.x",
+ 16 < Bpp ? "" : "((");
+ }
+ else
+ {
+ Output(Out, " BltInfo->DestRect.left");
+ }
+ if (Bpp < 8)
+ {
+ Output(Out, " / %u", 8 / Bpp);
+ }
+ else if (8 < Bpp)
+ {
+ Output(Out, " * %u", Bpp / 8);
+ }
+ if (Source && Bpp <= 16)
+ {
+ Output(Out, ") & ~ 0x3)");
+ }
+ Output(Out, ";\n", Bpp / 8);
+ if (Source && Bpp <= 16)
+ {
+ Output(Out, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n",
+ 32 / Bpp, 32 / Bpp - 1);
+ }
+}
+
+static void
+CreateGetSource(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
+ unsigned SourceBpp, unsigned Shift)
+{
+ char *AssignOp;
+ char *Before;
+ char After[8];
+
+ MARK(Out);
+ if (0 == Shift)
+ {
+ AssignOp = "=";
+ Before = "";
+ After[0] = '\0';
+ }
+ else
+ {
+ AssignOp = "|=";
+ Before = "(";
+ sprintf(After, ") << %u", Shift);
+ }
+
+ if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
+ 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
+ {
+ if (0 == (Flags & FLAG_FORCERAWSOURCEAVAIL) && SourceBpp <= 16)
+ {
+ Output(Out, "if (0 == SourcePixels)\n");
+ Output(Out, "{\n");
+ Output(Out, "RawSource = *SourcePtr++;\n");
+ Output(Out, "SourcePixels = %u;\n", 32 / SourceBpp);
+ Output(Out, "}\n");
+ }
+ Output(Out, "Source %s (%s", AssignOp, Before);
+ if (0 == (Flags & FLAG_TRIVIALXLATE))
+ {
+ Output(Out, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s",
+ 16 < SourceBpp ? "" : "(");
+ }
+ if (32 == SourceBpp)
+ {
+ Output(Out, "*SourcePtr++");
+ }
+ else if (24 == SourceBpp)
+ {
+ Output(Out, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)");
+ }
+ else
+ {
+ Output(Out, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp);
+ }
+ if (0 == (Flags & FLAG_TRIVIALXLATE))
+ {
+ if (16 < SourceBpp)
+ {
+ Output(Out, ")");
+ }
+ else
+ {
+ Output(Out, ") & 0x%x)", (1 << SourceBpp) - 1);
+ }
+ }
+ Output(Out, " & 0xffff)%s;\n", After);
+ if (SourceBpp <= 16)
+ {
+ Output(Out, "SourcePixels--;\n");
+ }
+ else if (24 == SourceBpp)
+ {
+ Output(Out, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n");
+ }
+ }
+}
+
+static void
+CreateCounts(FILE *Out)
+{
+ MARK(Out);
+ Output(Out, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n");
+ Output(Out, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
+ Output(Out, " LeftCount) / 2;\n");
+ Output(Out, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
+ Output(Out, " LeftCount - 2 * CenterCount);\n");
+}
+
+static void
+CreateBitCase(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
+ unsigned SourceBpp)
+{
+ MARK(Out);
+ if (RopInfo->UsesSource)
+ {
+ if (0 == (Flags & FLAG_FORCENOUSESSOURCE))
+ {
+ CreateBase(Out, 1, Flags, SourceBpp);
+ }
+ CreateBase(Out, 0, Flags, Bpp);
+ CreateCounts(Out);
+ MARK(Out);
+ }
+ if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+ {
+ if (0 == (Flags & FLAG_BOTTOMUP))
+ {
+ Output(Out, "PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %%\n");
+ Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
+ }
+ else
+ {
+ Output(Out, "PatternY = (BltInfo->DestRect.bottom - 1 +\n");
+ Output(Out, " BltInfo->BrushOrigin.y) %%\n");
+ Output(Out, " BltInfo->PatternSurface->sizlBitmap.cy;\n");
+ }
+ }
+ if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
+ 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
+ {
+ Output(Out, "CenterCount = 2 * (BltInfo->DestRect.right -\n");
+ Output(Out, " BltInfo->DestRect.left);\n");
+ }
+ Output(Out, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n");
+ Output(Out, "{\n");
+ if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
+ 0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
+ {
+ if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+ {
+ Output(Out, "SourcePtr = (PULONG) SourceBase;\n");
+ if (SourceBpp <= 16)
+ {
+ Output(Out, "RawSource = *SourcePtr++;\n");
+ Output(Out, "SourcePixels = BaseSourcePixels;\n");
+ }
+ }
+ Output(Out, "DestPtr = (PULONG) DestBase;\n");
+ }
+ if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+ {
+ Output(Out, "PatternX = (BltInfo->DestRect.left + BltInfo->BrushOrigin.x) %%\n");
+ Output(Out, " BltInfo->PatternSurface->sizlBitmap.cx;\n");
+ }
+ if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
+ 0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
+ {
+ Output(Out, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n");
+ Output(Out, "\n");
+ }
+ else
+ {
+ Output(Out, "\n");
+ Output(Out, "if (0 != LeftCount)\n");
+ Output(Out, "{\n");
+ if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+ {
+ CreateGetSource(Out, Bpp, RopInfo, Flags | FLAG_FORCERAWSOURCEAVAIL,
+ SourceBpp, 0);
+ MARK(Out);
+ }
+ if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+ {
+ Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
+ Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
+ Output(Out, "{\n");
+ Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
+ Output(Out, "}\n");
+ }
+ if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE) &&
+ Bpp != SourceBpp) ||
+ (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
+ {
+ Output(Out, "\n");
+ }
+ CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
+ Output(Out, ";\n");
+ MARK(Out);
+ Output(Out, "\n");
+ Output(Out, "DestPtr = (PULONG)((char *) DestPtr + 2);\n");
+ Output(Out, "}\n");
+ Output(Out, "\n");
+ Output(Out, "for (i = 0; i < CenterCount; i++)\n");
+ Output(Out, "{\n");
+ if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+ {
+ CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
+ CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 16);
+ MARK(Out);
+ Output(Out, "\n");
+ }
+ if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+ {
+ Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
+ Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
+ Output(Out, "{\n");
+ Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
+ Output(Out, "}\n");
+ Output(Out, "Pattern |= DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest) << 16;\n");
+ Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
+ Output(Out, "{\n");
+ Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
+ Output(Out, "}\n");
+ Output(Out, "\n");
+ }
+ CreateOperation(Out, Bpp, RopInfo, SourceBpp, 32);
+ Output(Out, ";\n");
+ MARK(Out);
+ Output(Out, "\n");
+ Output(Out, "DestPtr++;\n");
+ Output(Out, "}\n");
+ Output(Out, "\n");
+ Output(Out, "if (0 != RightCount)\n");
+ Output(Out, "{\n");
+ if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+ {
+ CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
+ MARK(Out);
+ }
+ if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+ {
+ Output(Out, "Pattern = DIB_GetSource(BltInfo->PatternSurface, PatternX, PatternY, BltInfo->XlatePatternToDest);\n");
+ }
+ if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE)) ||
+ (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
+ {
+ Output(Out, "\n");
+ }
+ CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
+ Output(Out, ";\n");
+ MARK(Out);
+ Output(Out, "}\n");
+ Output(Out, "\n");
+ if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
+ {
+ if (0 == (Flags & FLAG_BOTTOMUP))
+ {
+ Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n");
+ Output(Out, "{\n");
+ Output(Out, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n");
+ Output(Out, "}\n");
+ }
+ else
+ {
+ Output(Out, "if (0 == PatternY--)\n");
+ Output(Out, "{\n");
+ Output(Out, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n");
+ Output(Out, "}\n");
+ }
+ }
+ }
+ if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
+ {
+ Output(Out, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n",
+ 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
+ }
+ Output(Out, "DestBase %c= BltInfo->DestSurface->lDelta;\n",
+ 0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
+ Output(Out, "}\n");
+}
+
+static void
+CreateActionBlock(FILE *Out, unsigned Bpp, PROPINFO RopInfo,
+ int Flags)
+{
+ static unsigned SourceBpp[ ] =
+ { 1, 4, 8, 16, 24, 32 };
+ unsigned BppIndex;
+
+ MARK(Out);
+ if (RopInfo->UsesSource)
+ {
+ if (ROPCODE_GENERIC == RopInfo->RopCode)
+ {
+ Output(Out, "if (UsesSource)\n");
+ Output(Out, "{\n");
+ }
+ Output(Out, "switch (BltInfo->SourceSurface->iBitmapFormat)\n");
+ Output(Out, "{\n");
+ for (BppIndex = 0;
+ BppIndex < sizeof(SourceBpp) / sizeof(unsigned);
+ BppIndex++)
+ {
+ Output(Out, "case BMF_%uBPP:\n", SourceBpp[BppIndex]);
+ Output(Out, "{\n");
+ if (Bpp == SourceBpp[BppIndex])
+ {
+ Output(Out, "if (NULL == BltInfo->XlateSourceToDest ||\n");
+ Output(Out, " 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n");
+ Output(Out, "{\n");
+ Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
+ Output(Out, "{\n");
+ CreateBitCase(Out, Bpp, RopInfo,
+ Flags | FLAG_TRIVIALXLATE,
+ SourceBpp[BppIndex]);
+ MARK(Out);
+ Output(Out, "}\n");
+ Output(Out, "else\n");
+ Output(Out, "{\n");
+ CreateBitCase(Out, Bpp, RopInfo,
+ Flags | FLAG_BOTTOMUP | FLAG_TRIVIALXLATE,
+ SourceBpp[BppIndex]);
+ MARK(Out);
+ Output(Out, "}\n");
+ Output(Out, "}\n");
+ Output(Out, "else\n");
+ Output(Out, "{\n");
+ Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
+ Output(Out, "{\n");
+ CreateBitCase(Out, Bpp, RopInfo, Flags, SourceBpp[BppIndex]);
+ MARK(Out);
+ Output(Out, "}\n");
+ Output(Out, "else\n");
+ Output(Out, "{\n");
+ CreateBitCase(Out, Bpp, RopInfo,
+ Flags | FLAG_BOTTOMUP,
+ SourceBpp[BppIndex]);
+ MARK(Out);
+ Output(Out, "}\n");
+ Output(Out, "}\n");
+ }
+ else
+ {
+ CreateBitCase(Out, Bpp, RopInfo, Flags,
+ SourceBpp[BppIndex]);
+ MARK(Out);
+ }
+ Output(Out, "break;\n");
+ Output(Out, "}\n");
+ }
+ Output(Out, "}\n");
+ if (ROPCODE_GENERIC == RopInfo->RopCode)
+ {
+ Output(Out, "}\n");
+ Output(Out, "else\n");
+ Output(Out, "{\n");
+ CreateBitCase(Out, Bpp, RopInfo, Flags | FLAG_FORCENOUSESSOURCE, 0);
+ MARK(Out);
+ Output(Out, "}\n");
+ }
+ }
+ else
+ {
+ CreateBitCase(Out, Bpp, RopInfo, Flags, 0);
+ }
+}
+
+static void
+CreatePrimitive(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
+{
+ int First;
+
+ MARK(Out);
+ Output(Out, "\n");
+ Output(Out, "static void\n");
+ PrintRoutineName(Out, Bpp, RopInfo);
+ Output(Out, "(PBLTINFO BltInfo)\n");
+ Output(Out, "{\n");
+ if (ROPCODE_BLACKNESS == RopInfo->RopCode)
+ {
+ Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
+ "&BltInfo->DestRect, 0x0);\n", Bpp);
+ }
+ else if (ROPCODE_WHITENESS == RopInfo->RopCode)
+ {
+ Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
+ "&BltInfo->DestRect, ~0);\n", Bpp);
+ }
+ else if (ROPCODE_NOOP == RopInfo->RopCode)
+ {
+ Output(Out, "return;\n");
+ }
+ else
+ {
+ Output(Out, "ULONG LineIndex, LineCount;\n");
+ Output(Out, "ULONG i;\n");
+#ifdef TODO
+ if (RopInfo->UsesSource)
+ {
+ Output(Out, "ULONG SourceX, SourceY;\n");
+ }
+#endif
+ if (RopInfo->UsesPattern)
+ {
+ Output(Out, "ULONG PatternX, PatternY = 0;\n");
+ }
+ First = 1;
+ if (RopInfo->UsesSource)
+ {
+ Output(Out, "ULONG Source = 0");
+ First = 0;
+ }
+ if (RopInfo->UsesPattern)
+ {
+ Output(Out, "%s Pattern = 0", First ? "ULONG" : ",");
+ First = 0;
+ }
+ if (! First)
+ {
+ Output(Out, ";\n");
+ }
+ Output(Out, "char *DestBase;\n");
+ Output(Out, "PULONG DestPtr;\n");
+ if (RopInfo->UsesSource)
+ {
+ Output(Out, "char *SourceBase;\n");
+ Output(Out, "PULONG SourcePtr;\n");
+ Output(Out, "ULONG RawSource;\n");
+ Output(Out, "unsigned SourcePixels, BaseSourcePixels;\n");
+ }
+ Output(Out, "ULONG LeftCount, CenterCount, RightCount;\n");
+ if (ROPCODE_GENERIC == RopInfo->RopCode)
+ {
+ Output(Out, "BOOLEAN UsesDest, UsesSource, UsesPattern;\n");
+ Output(Out, "\n");
+ Output(Out, "UsesDest = ROP4_USES_DEST(BltInfo->Rop4);\n");
+ Output(Out, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n");
+ Output(Out, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n");
+ }
+ Output(Out, "\n");
+ if (! RopInfo->UsesSource)
+ {
+ CreateBase(Out, 0, 0, Bpp);
+ CreateCounts(Out);
+ MARK(Out);
+ }
+ Output(Out, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n");
+
+ Output(Out, "\n");
+ if (RopInfo->UsesPattern)
+ {
+ if (ROPCODE_GENERIC == RopInfo->RopCode)
+ {
+ Output(Out, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n");
+ }
+ else
+ {
+ Output(Out, "if (NULL != BltInfo->PatternSurface)\n");
+ }
+ Output(Out, "{\n");
+ CreateActionBlock(Out, Bpp, RopInfo, FLAG_PATTERNSURFACE);
+ MARK(Out);
+ Output(Out, "}\n");
+ Output(Out, "else\n");
+ Output(Out, "{\n");
+ if (ROPCODE_GENERIC == RopInfo->RopCode)
+ {
+ Output(Out, "if (UsesPattern)\n");
+ Output(Out, "{\n");
+ }
+ Output(Out, "Pattern = BltInfo->Brush->iSolidColor |\n");
[truncated at 1000 lines; 191 more skipped]