ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

gendib.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2005 Ge van Geldorp (gvg@reactos.com).
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017  */
00018 /*
00019  * This is a code generator. It outputs C code which can be compiled using the
00020  * standard build tools. It is used to generate code for the DIB Blt routines.
00021  * There are a lot of possible Blt routines (256 rop codes, for 6 different
00022  * bit depths). It is possible to use a generic Blt routine which handles all
00023  * rop codes and all depths. The drawback is that it will be relatively slow.
00024  * The other extreme is to write (generate) a separate Blt routine for each
00025  * rop code/depth combination. This will result in a extremely large amount
00026  * of code. So, we opt for something in between: named rops get their own
00027  * routine, unnamed rops are handled by a generic routine.
00028  * Basically, what happens is that generic code which looks like:
00029  *
00030  * for (...)
00031  * {
00032  *     if (CondA)
00033  *     {
00034  *         doSomethingA;
00035  *     }
00036  *     for (...)
00037  *     {
00038  *         if (CondB)
00039  *         {
00040  *             doSomethingB;
00041  *         }
00042  *         else
00043  *         {
00044  *             doSomethingElseB;
00045  *         }
00046  *     }
00047  * }
00048  *
00049  * is specialized for named rops to look like:
00050  *
00051  * if (condC)
00052  * {
00053  *     if (condD)
00054  *     {
00055  *         for (...)
00056  *         {
00057  *             for (...)
00058  *             {
00059  *                 pumpSomeBytes;
00060  *             }
00061  *         }
00062  *     }
00063  *     else
00064  *     {
00065  *         for (...)
00066  *         {
00067  *             for (...)
00068  *             {
00069  *                 pumpSomeBytesSlightlyDifferentE;
00070  *             }
00071  *         }
00072  *     }
00073  * }
00074  *
00075  * i.e. we make the inner loops as tight as possible.
00076  * Another optimization is to try to load/store 32 alligned bits at a time from
00077  * video memory. Accessing video memory from the CPU is slooooooow, so let's
00078  * try to do this as little as possible, even if that means we have to do some
00079  * extra operations using main memory.
00080  */
00081 
00082 #include <stdarg.h>
00083 #include <stdio.h>
00084 #include <stdlib.h>
00085 #include <string.h>
00086 
00087 #define NDEBUG
00088 
00089 #define USES_DEST(RopCode)    ((((RopCode) & 0xaa) >> 1) != ((RopCode) & 0x55))
00090 #define USES_SOURCE(RopCode)  ((((RopCode) & 0xcc) >> 2) != ((RopCode) & 0x33))
00091 #define USES_PATTERN(RopCode) ((((RopCode) & 0xf0) >> 4) != ((RopCode) & 0x0f))
00092 
00093 #ifdef NDEBUG
00094 #define MARK(Out)
00095 #else
00096 #define MARK(Out) Output((Out), "/* Generated by %s line %d*/\n", \
00097                          __FUNCTION__, __LINE__);
00098 #endif
00099 
00100 #define ROPCODE_BLACKNESS   0x00
00101 #define ROPCODE_NOTSRCERASE 0x11
00102 #define ROPCODE_NOTSRCCOPY  0x33
00103 #define ROPCODE_SRCERASE    0x44
00104 #define ROPCODE_DSTINVERT   0x55
00105 #define ROPCODE_PATINVERT   0x5a
00106 #define ROPCODE_SRCINVERT   0x66
00107 #define ROPCODE_SRCAND      0x88
00108 #define ROPCODE_NOOP        0xaa
00109 #define ROPCODE_MERGEPAINT  0xbb
00110 #define ROPCODE_MERGECOPY   0xc0
00111 #define ROPCODE_SRCCOPY     0xcc
00112 #define ROPCODE_SRCPAINT    0xee
00113 #define ROPCODE_PATCOPY     0xf0
00114 #define ROPCODE_PATPAINT    0xfb
00115 #define ROPCODE_WHITENESS   0xff
00116 
00117 #define ROPCODE_GENERIC     256 /* Special case */
00118 
00119 typedef struct _ROPINFO
00120 {
00121     unsigned RopCode;
00122     const char *Name;
00123     const char *Operation;
00124     int UsesDest;
00125     int UsesSource;
00126     int UsesPattern;
00127 }
00128 ROPINFO, *PROPINFO;
00129 
00130 #define FLAG_PATTERNSURFACE      0x01
00131 #define FLAG_TRIVIALXLATE        0x02
00132 #define FLAG_BOTTOMUP            0x04
00133 #define FLAG_FORCENOUSESSOURCE   0x08
00134 #define FLAG_FORCERAWSOURCEAVAIL 0x10
00135 
00136 static PROPINFO
00137 FindRopInfo(unsigned RopCode)
00138 {
00139     static ROPINFO KnownCodes[] =
00140     {
00141         { ROPCODE_BLACKNESS,   "BLACKNESS",  "0",            0, 0, 0 },
00142         { ROPCODE_NOTSRCERASE, "NOTSRCERASE","~(D | S)",     1, 1, 0 },
00143         { ROPCODE_NOTSRCCOPY,  "NOTSRCCOPY", "~S",           0, 1, 0 },
00144         { ROPCODE_SRCERASE,    "SRCERASE",   "(~D) & S",     1, 1, 0 },
00145         { ROPCODE_DSTINVERT,   "DSTINVERT",  "~D",           1, 0, 0 },
00146         { ROPCODE_PATINVERT,   "PATINVERT",  "D ^ P",        1, 0, 1 },
00147         { ROPCODE_SRCINVERT,   "SRCINVERT",  "D ^ S",        1, 1, 0 },
00148         { ROPCODE_SRCAND,      "SRCAND",     "D & S",        1, 1, 0 },
00149         { ROPCODE_NOOP,        "NOOP",       "D",            1, 0, 0 },
00150         { ROPCODE_MERGEPAINT,  "MERGEPAINT", "D | (~S)",     1, 1, 0 },
00151         { ROPCODE_MERGECOPY,   "MERGECOPY",  "S & P",        0, 1, 1 },
00152         { ROPCODE_SRCCOPY,     "SRCCOPY",    "S",            0, 1, 0 },
00153         { ROPCODE_SRCPAINT,    "SRCPAINT",   "D | S",        1, 1, 0 },
00154         { ROPCODE_PATCOPY,     "PATCOPY",    "P",            0, 0, 1 },
00155         { ROPCODE_PATPAINT,    "PATPAINT",   "D | (~S) | P", 1, 1, 1 },
00156         { ROPCODE_WHITENESS,   "WHITENESS",  "0xffffffff",   0, 0, 0 },
00157         { ROPCODE_GENERIC,     NULL,         NULL,           1, 1, 1 }
00158     };
00159     unsigned Index;
00160 
00161     for (Index = 0; Index < sizeof(KnownCodes) / sizeof(KnownCodes[0]); Index++)
00162     {
00163         if (RopCode == KnownCodes[Index].RopCode)
00164         {
00165             return KnownCodes + Index;
00166         }
00167     }
00168 
00169     return NULL;
00170 }
00171 
00172 static void
00173 Output(FILE *Out, const char *Fmt, ...)
00174 {
00175     static unsigned Indent = 0;
00176     static int AtBOL = 1;
00177     unsigned n;
00178     va_list Args;
00179 
00180     if (strchr(Fmt, '}'))
00181     {
00182         Indent -= 4;
00183     }
00184 
00185     if (AtBOL)
00186     {
00187         for (n = 0; n < Indent; n++)
00188         {
00189             putc(' ', Out);
00190         }
00191         AtBOL = 0;
00192     }
00193 
00194     va_start(Args, Fmt);
00195     vfprintf(Out, Fmt, Args);
00196     va_end(Args);
00197 
00198     if (strchr(Fmt, '{'))
00199     {
00200         Indent += 4;
00201     }
00202 
00203     AtBOL = '\n' == Fmt[strlen(Fmt) - 1];
00204 }
00205 
00206 static void
00207 PrintRoutineName(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
00208 {
00209     if (NULL != RopInfo && ROPCODE_GENERIC != RopInfo->RopCode)
00210     {
00211         Output(Out, "DIB_%uBPP_BitBlt_%s", Bpp, RopInfo->Name);
00212     }
00213     else
00214     {
00215         Output(Out, "DIB_%uBPP_BitBlt_Generic", Bpp);
00216     }
00217 }
00218 
00219 static void
00220 CreateShiftTables(FILE *Out)
00221 {
00222     Output(Out, "\n");
00223     Output(Out, "static unsigned Shift1Bpp[] =\n");
00224     Output(Out, "{\n");
00225     Output(Out, "0,\n");
00226     Output(Out, "24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23,\n");
00227     Output(Out, "8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7\n");
00228     Output(Out, "};\n");
00229     Output(Out, "static unsigned Shift4Bpp[] =\n");
00230     Output(Out, "{\n");
00231     Output(Out, "0,\n");
00232     Output(Out, "24, 28, 16, 20, 8, 12, 0, 4\n");
00233     Output(Out, "};\n");
00234     Output(Out, "static unsigned Shift8Bpp[] =\n");
00235     Output(Out, "{\n");
00236     Output(Out, "0,\n");
00237     Output(Out, "24, 16, 8, 0\n");
00238     Output(Out, "};\n");
00239     Output(Out, "static unsigned Shift16Bpp[] =\n");
00240     Output(Out, "{\n");
00241     Output(Out, "0,\n");
00242     Output(Out, "16, 0\n");
00243     Output(Out, "};\n");
00244 }
00245 
00246 static void
00247 CreateOperation(FILE *Out, unsigned Bpp, PROPINFO RopInfo, unsigned SourceBpp,
00248                 unsigned Bits)
00249 {
00250     const char *Cast;
00251     const char *Dest;
00252     const char *Template;
00253 
00254     MARK(Out);
00255     if (32 == Bits)
00256     {
00257         Cast = "";
00258         Dest = "*DestPtr";
00259     }
00260     else if (16 == Bpp)
00261     {
00262         Cast = "(USHORT) ";
00263         Dest = "*((PUSHORT) DestPtr)";
00264     }
00265     else
00266     {
00267         Cast = "(UCHAR) ";
00268         Dest = "*((PUCHAR) DestPtr)";
00269     }
00270     Output(Out, "%s = ", Dest);
00271     if (ROPCODE_GENERIC == RopInfo->RopCode)
00272     {
00273         Output(Out, "%sDIB_DoRop(BltInfo->Rop4, %s, Source, Pattern)",
00274                Cast, Dest);
00275     }
00276     else
00277     {
00278         Template = RopInfo->Operation;
00279         while ('\0' != *Template)
00280         {
00281             switch(*Template)
00282             {
00283             case 'S':
00284                 Output(Out, "%sSource", Cast);
00285                 break;
00286             case 'P':
00287                 Output(Out, "%sPattern", Cast);
00288                 break;
00289             case 'D':
00290                 Output(Out, "%s", Dest);
00291                 break;
00292             default:
00293                 Output(Out, "%c", *Template);
00294                 break;
00295             }
00296             Template++;
00297         }
00298     }
00299 }
00300 
00301 static void
00302 CreateBase(FILE *Out, int Source, int Flags, unsigned Bpp)
00303 {
00304     const char *What = (Source ? "Source" : "Dest");
00305 
00306     MARK(Out);
00307     Output(Out, "%sBase = (char *) BltInfo->%sSurface->pvScan0 +\n", What, What);
00308     if (0 == (Flags & FLAG_BOTTOMUP))
00309     {
00310         if (Source)
00311         {
00312             Output(Out, "             BltInfo->SourcePoint.y *\n");
00313         }
00314         else
00315         {
00316             Output(Out, "           BltInfo->DestRect.top *\n");
00317         }
00318     }
00319     else
00320     {
00321         if (Source)
00322         {
00323             Output(Out, "             (BltInfo->SourcePoint.y +\n");
00324             Output(Out, "              BltInfo->DestRect.bottom -\n");
00325             Output(Out, "              BltInfo->DestRect.top - 1) *\n");
00326         }
00327         else
00328         {
00329             Output(Out, "           (BltInfo->DestRect.bottom - 1) *\n");
00330         }
00331     }
00332     Output(Out, "           %sBltInfo->%sSurface->lDelta +\n",
00333            Source ? "  " : "", What);
00334     if (Source)
00335     {
00336         Output(Out, "             %sBltInfo->SourcePoint.x",
00337                16 < Bpp ? "" : "((");
00338     }
00339     else
00340     {
00341         Output(Out, "           BltInfo->DestRect.left");
00342     }
00343     if (Bpp < 8)
00344     {
00345         Output(Out, " / %u", 8 / Bpp);
00346     }
00347     else if (8 < Bpp)
00348     {
00349         Output(Out, " * %u", Bpp / 8);
00350     }
00351     if (Source && Bpp <= 16)
00352     {
00353         Output(Out, ") & ~ 0x3)");
00354     }
00355     Output(Out, ";\n", Bpp / 8);
00356     if (Source && Bpp <= 16)
00357     {
00358         Output(Out, "BaseSourcePixels = %u - (BltInfo->SourcePoint.x & 0x%x);\n",
00359                32 / Bpp, 32 / Bpp - 1);
00360     }
00361 }
00362 
00363 static void
00364 CreateGetSource(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
00365                 unsigned SourceBpp, unsigned Shift)
00366 {
00367     const char *AssignOp;
00368     const char *Before;
00369     char After[8];
00370 
00371     MARK(Out);
00372     if (0 == Shift)
00373     {
00374         AssignOp = "=";
00375         Before = "";
00376         After[0] = '\0';
00377     }
00378     else
00379     {
00380         AssignOp = "|=";
00381         Before = "(";
00382         sprintf(After, ") << %u", Shift);
00383     }
00384 
00385     if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
00386             0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
00387     {
00388         if (0 == (Flags & FLAG_FORCERAWSOURCEAVAIL) && SourceBpp <= 16)
00389         {
00390             Output(Out, "if (0 == SourcePixels)\n");
00391             Output(Out, "{\n");
00392             Output(Out, "RawSource = *SourcePtr++;\n");
00393             Output(Out, "SourcePixels = %u;\n", 32 / SourceBpp);
00394             Output(Out, "}\n");
00395         }
00396         Output(Out, "Source %s (%s", AssignOp, Before);
00397         if (0 == (Flags & FLAG_TRIVIALXLATE))
00398         {
00399             Output(Out, "XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, %s",
00400                    16 < SourceBpp ? "" : "(");
00401         }
00402         if (32 == SourceBpp)
00403         {
00404             Output(Out, "*SourcePtr++");
00405         }
00406         else if (24 == SourceBpp)
00407         {
00408             Output(Out, "*(PUSHORT) SourcePtr + (*((PBYTE) SourcePtr + 2) << 16)");
00409         }
00410         else
00411         {
00412             Output(Out, "RawSource >> Shift%uBpp[SourcePixels]", SourceBpp);
00413         }
00414         if (0 == (Flags & FLAG_TRIVIALXLATE))
00415         {
00416             if (16 < SourceBpp)
00417             {
00418                 Output(Out, ")");
00419             }
00420             else
00421             {
00422                 Output(Out, ") & 0x%x)", (1 << SourceBpp) - 1);
00423             }
00424         }
00425         if (32 == Bpp)
00426         {
00427             Output(Out, ")%s;\n", After);
00428         }
00429         else
00430         {
00431             Output(Out, " & 0x%x)%s;\n", (1 << Bpp) - 1, After);
00432         }
00433         if (SourceBpp <= 16)
00434         {
00435             Output(Out, "SourcePixels--;\n");
00436         }
00437         else if (24 == SourceBpp)
00438         {
00439             Output(Out, "SourcePtr = (PULONG)((char *) SourcePtr + 3);\n");
00440         }
00441     }
00442 }
00443 
00444 static void
00445 CreateCounts(FILE *Out, unsigned Bpp)
00446 {
00447     MARK(Out);
00448     if (32 != Bpp)
00449     {
00450         if (8 < Bpp)
00451         {
00452             Output(Out, "LeftCount = ((ULONG_PTR) DestBase >> 1) & 0x01;\n");
00453         }
00454         else
00455         {
00456             Output(Out, "LeftCount = (ULONG_PTR) DestBase & 0x03;\n");
00457             Output(Out, "if ((ULONG)(BltInfo->DestRect.right - BltInfo->DestRect.left) < "
00458                    "LeftCount)\n");
00459             Output(Out, "{\n");
00460             Output(Out, "LeftCount = BltInfo->DestRect.right - "
00461                    "BltInfo->DestRect.left;\n");
00462             Output(Out, "}\n");
00463         }
00464         Output(Out, "CenterCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
00465         Output(Out, "               LeftCount) / %u;\n", 32 / Bpp);
00466         Output(Out, "RightCount = (BltInfo->DestRect.right - BltInfo->DestRect.left -\n");
00467         Output(Out, "              LeftCount - %u * CenterCount);\n", 32 / Bpp);
00468     }
00469     else
00470     {
00471         Output(Out, "CenterCount = BltInfo->DestRect.right - BltInfo->DestRect.left;\n");
00472     }
00473 }
00474 
00475 static void
00476 CreateSetSinglePixel(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
00477                      unsigned SourceBpp)
00478 {
00479     if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
00480     {
00481         CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp, 0);
00482         MARK(Out);
00483     }
00484     if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
00485     {
00486         Output(Out, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n");
00487         Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
00488         Output(Out, "{\n");
00489         Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
00490         Output(Out, "}\n");
00491     }
00492     if ((RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE) &&
00493             Bpp != SourceBpp) ||
00494             (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE)))
00495     {
00496         Output(Out, "\n");
00497     }
00498     CreateOperation(Out, Bpp, RopInfo, SourceBpp, 16);
00499     Output(Out, ";\n");
00500     MARK(Out);
00501     Output(Out, "\n");
00502     Output(Out, "DestPtr = (PULONG)((char *) DestPtr + %u);\n", Bpp / 8);
00503 }
00504 
00505 static void
00506 CreateBitCase(FILE *Out, unsigned Bpp, PROPINFO RopInfo, int Flags,
00507               unsigned SourceBpp)
00508 {
00509     unsigned Partial;
00510 
00511     MARK(Out);
00512     if (RopInfo->UsesSource)
00513     {
00514         if (0 == (Flags & FLAG_FORCENOUSESSOURCE))
00515         {
00516             CreateBase(Out, 1, Flags, SourceBpp);
00517         }
00518         CreateBase(Out, 0, Flags, Bpp);
00519         CreateCounts(Out, Bpp);
00520         MARK(Out);
00521     }
00522     if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
00523     {
00524         if (0 == (Flags & FLAG_BOTTOMUP))
00525         {
00526             Output(Out, "PatternY = (BltInfo->DestRect.top - BltInfo->BrushOrigin.y) %%\n");
00527             Output(Out, "           BltInfo->PatternSurface->sizlBitmap.cy;\n");
00528         }
00529         else
00530         {
00531             Output(Out, "PatternY = (BltInfo->DestRect.bottom - 1 -\n");
00532             Output(Out, "            BltInfo->BrushOrigin.y) %%\n");
00533             Output(Out, "           BltInfo->PatternSurface->sizlBitmap.cy;\n");
00534         }
00535     }
00536     if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
00537             0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
00538     {
00539         Output(Out, "CenterCount = %u * (BltInfo->DestRect.right -\n", Bpp >> 3);
00540         Output(Out, "                   BltInfo->DestRect.left);\n");
00541     }
00542     if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
00543     {
00544         Output(Out, "BasePatternX = (BltInfo->DestRect.left - BltInfo->BrushOrigin.x) %%\n");
00545         Output(Out, "           BltInfo->PatternSurface->sizlBitmap.cx;\n");
00546     }
00547 
00548     Output(Out, "for (LineIndex = 0; LineIndex < LineCount; LineIndex++)\n");
00549     Output(Out, "{\n");
00550     if (ROPCODE_SRCCOPY != RopInfo->RopCode ||
00551             0 == (Flags & FLAG_TRIVIALXLATE) || Bpp != SourceBpp)
00552     {
00553         if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
00554         {
00555             Output(Out, "SourcePtr = (PULONG) SourceBase;\n");
00556             if (SourceBpp <= 16)
00557             {
00558                 Output(Out, "RawSource = *SourcePtr++;\n");
00559                 Output(Out, "SourcePixels = BaseSourcePixels;\n");
00560             }
00561         }
00562         Output(Out, "DestPtr = (PULONG) DestBase;\n");
00563     }
00564 
00565     if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
00566     {
00567         Output(Out, "PatternX = BasePatternX;\n");
00568     }
00569 
00570     if (ROPCODE_SRCCOPY == RopInfo->RopCode &&
00571             0 != (Flags & FLAG_TRIVIALXLATE) && Bpp == SourceBpp)
00572     {
00573         Output(Out, "RtlMoveMemory(DestBase, SourceBase, CenterCount);\n");
00574         Output(Out, "\n");
00575     }
00576     else
00577     {
00578         Output(Out, "\n");
00579         if (32 != Bpp)
00580         {
00581             if (16 == Bpp)
00582             {
00583                 Output(Out, "if (0 != LeftCount)\n");
00584             }
00585             else
00586             {
00587                 Output(Out, "for (i = 0; i < LeftCount; i++)\n");
00588             }
00589             Output(Out, "{\n");
00590             CreateSetSinglePixel(Out, Bpp, RopInfo,
00591                                  (16 == Bpp ? Flags | FLAG_FORCERAWSOURCEAVAIL :
00592                                   Flags), SourceBpp);
00593             MARK(Out);
00594             Output(Out, "}\n");
00595             Output(Out, "\n");
00596         }
00597         Output(Out, "for (i = 0; i < CenterCount; i++)\n");
00598         Output(Out, "{\n");
00599         if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
00600         {
00601             for (Partial = 0; Partial < 32 / Bpp; Partial++)
00602             {
00603                 CreateGetSource(Out, Bpp, RopInfo, Flags, SourceBpp,
00604                                 Partial * Bpp);
00605                 MARK(Out);
00606             }
00607             Output(Out, "\n");
00608         }
00609         if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
00610         {
00611             for (Partial = 0; Partial < 32 / Bpp; Partial++)
00612             {
00613                 if (0 == Partial)
00614                 {
00615                     Output(Out, "Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY);\n");
00616                 }
00617                 else
00618                 {
00619                     Output(Out, "Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, PatternX, PatternY) << %u;\n", Partial * Bpp);
00620                 }
00621                 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cx <= ++PatternX)\n");
00622                 Output(Out, "{\n");
00623                 Output(Out, "PatternX -= BltInfo->PatternSurface->sizlBitmap.cx;\n");
00624                 Output(Out, "}\n");
00625             }
00626             Output(Out, "\n");
00627         }
00628         CreateOperation(Out, Bpp, RopInfo, SourceBpp, 32);
00629         Output(Out, ";\n");
00630         MARK(Out);
00631         Output(Out, "\n");
00632         Output(Out, "DestPtr++;\n");
00633         Output(Out, "}\n");
00634         Output(Out, "\n");
00635         if (32 != Bpp)
00636         {
00637             if (16 == Bpp)
00638             {
00639                 Output(Out, "if (0 != RightCount)\n");
00640             }
00641             else
00642             {
00643                 Output(Out, "for (i = 0; i < RightCount; i++)\n");
00644             }
00645             Output(Out, "{\n");
00646             CreateSetSinglePixel(Out, Bpp, RopInfo, Flags, SourceBpp);
00647             MARK(Out);
00648             Output(Out, "}\n");
00649             Output(Out, "\n");
00650         }
00651         if (RopInfo->UsesPattern && 0 != (Flags & FLAG_PATTERNSURFACE))
00652         {
00653             if (0 == (Flags & FLAG_BOTTOMUP))
00654             {
00655                 Output(Out, "if (BltInfo->PatternSurface->sizlBitmap.cy <= ++PatternY)\n");
00656                 Output(Out, "{\n");
00657                 Output(Out, "PatternY -= BltInfo->PatternSurface->sizlBitmap.cy;\n");
00658                 Output(Out, "}\n");
00659             }
00660             else
00661             {
00662                 Output(Out, "if (0 == PatternY--)\n");
00663                 Output(Out, "{\n");
00664                 Output(Out, "PatternY = BltInfo->PatternSurface->sizlBitmap.cy - 1;\n");
00665                 Output(Out, "}\n");
00666             }
00667         }
00668     }
00669     if (RopInfo->UsesSource && 0 == (Flags & FLAG_FORCENOUSESSOURCE))
00670     {
00671         Output(Out, "SourceBase %c= BltInfo->SourceSurface->lDelta;\n",
00672                0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
00673     }
00674     Output(Out, "DestBase %c= BltInfo->DestSurface->lDelta;\n",
00675            0 == (Flags & FLAG_BOTTOMUP) ? '+' : '-');
00676     Output(Out, "}\n");
00677 }
00678 
00679 static void
00680 CreateActionBlock(FILE *Out, unsigned Bpp, PROPINFO RopInfo,
00681                   int Flags)
00682 {
00683     static unsigned SourceBpp[ ] =
00684     { 1, 4, 8, 16, 24, 32 };
00685     unsigned BppIndex;
00686 
00687     MARK(Out);
00688     if (RopInfo->UsesSource)
00689     {
00690         if (ROPCODE_GENERIC == RopInfo->RopCode)
00691         {
00692             Output(Out, "if (UsesSource)\n");
00693             Output(Out, "{\n");
00694         }
00695         Output(Out, "switch (BltInfo->SourceSurface->iBitmapFormat)\n");
00696         Output(Out, "{\n");
00697         for (BppIndex = 0;
00698                 BppIndex < sizeof(SourceBpp) / sizeof(unsigned);
00699                 BppIndex++)
00700         {
00701             Output(Out, "case BMF_%uBPP:\n", SourceBpp[BppIndex]);
00702             Output(Out, "{\n");
00703             if (Bpp == SourceBpp[BppIndex])
00704             {
00705                 Output(Out, "if (NULL == BltInfo->XlateSourceToDest ||\n");
00706                 Output(Out, "    0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))\n");
00707                 Output(Out, "{\n");
00708                 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
00709                 Output(Out, "{\n");
00710                 CreateBitCase(Out, Bpp, RopInfo,
00711                               Flags | FLAG_TRIVIALXLATE,
00712                               SourceBpp[BppIndex]);
00713                 MARK(Out);
00714                 Output(Out, "}\n");
00715                 Output(Out, "else\n");
00716                 Output(Out, "{\n");
00717                 CreateBitCase(Out, Bpp, RopInfo,
00718                               Flags | FLAG_BOTTOMUP | FLAG_TRIVIALXLATE,
00719                               SourceBpp[BppIndex]);
00720                 MARK(Out);
00721                 Output(Out, "}\n");
00722                 Output(Out, "}\n");
00723                 Output(Out, "else\n");
00724                 Output(Out, "{\n");
00725                 Output(Out, "if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)\n");
00726                 Output(Out, "{\n");
00727                 CreateBitCase(Out, Bpp, RopInfo, Flags, SourceBpp[BppIndex]);
00728                 MARK(Out);
00729                 Output(Out, "}\n");
00730                 Output(Out, "else\n");
00731                 Output(Out, "{\n");
00732                 CreateBitCase(Out, Bpp, RopInfo,
00733                               Flags | FLAG_BOTTOMUP,
00734                               SourceBpp[BppIndex]);
00735                 MARK(Out);
00736                 Output(Out, "}\n");
00737                 Output(Out, "}\n");
00738             }
00739             else
00740             {
00741                 CreateBitCase(Out, Bpp, RopInfo, Flags,
00742                               SourceBpp[BppIndex]);
00743                 MARK(Out);
00744             }
00745             Output(Out, "break;\n");
00746             Output(Out, "}\n");
00747         }
00748         Output(Out, "}\n");
00749         if (ROPCODE_GENERIC == RopInfo->RopCode)
00750         {
00751             Output(Out, "}\n");
00752             Output(Out, "else\n");
00753             Output(Out, "{\n");
00754             CreateBitCase(Out, Bpp, RopInfo, Flags | FLAG_FORCENOUSESSOURCE, 0);
00755             MARK(Out);
00756             Output(Out, "}\n");
00757         }
00758     }
00759     else
00760     {
00761         CreateBitCase(Out, Bpp, RopInfo, Flags, 0);
00762     }
00763 }
00764 
00765 static void
00766 CreatePrimitive(FILE *Out, unsigned Bpp, PROPINFO RopInfo)
00767 {
00768     int First;
00769     unsigned Partial;
00770 
00771     MARK(Out);
00772     Output(Out, "\n");
00773     Output(Out, "static void\n");
00774     PrintRoutineName(Out, Bpp, RopInfo);
00775     Output(Out, "(PBLTINFO BltInfo)\n");
00776     Output(Out, "{\n");
00777     if (ROPCODE_BLACKNESS == RopInfo->RopCode)
00778     {
00779         Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
00780                "&BltInfo->DestRect, 0x0);\n", Bpp);
00781     }
00782     else if (ROPCODE_WHITENESS == RopInfo->RopCode)
00783     {
00784         Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
00785                "&BltInfo->DestRect, ~0);\n", Bpp);
00786     }
00787     else if (ROPCODE_NOOP == RopInfo->RopCode)
00788     {
00789         Output(Out, "return;\n");
00790     }
00791     else
00792     {
00793         Output(Out, "ULONG LineIndex, LineCount;\n");
00794         Output(Out, "ULONG i;\n");
00795         if (RopInfo->UsesPattern)
00796         {
00797             Output(Out, "LONG PatternX =0, PatternY = 0, BasePatternX = 0;\n");
00798         }
00799         First = 1;
00800         if (RopInfo->UsesSource)
00801         {
00802             Output(Out, "ULONG Source = 0");
00803             First = 0;
00804         }
00805         if (RopInfo->UsesPattern)
00806         {
00807             Output(Out, "%s Pattern = 0", First ? "ULONG" : ",");
00808             First = 0;
00809         }
00810         if (! First)
00811         {
00812             Output(Out, ";\n");
00813         }
00814         Output(Out, "char *DestBase;\n");
00815         Output(Out, "PULONG DestPtr;\n");
00816         if (RopInfo->UsesSource)
00817         {
00818             Output(Out, "char *SourceBase;\n");
00819             Output(Out, "PULONG SourcePtr;\n");
00820             Output(Out, "ULONG RawSource;\n");
00821             Output(Out, "unsigned SourcePixels, BaseSourcePixels;\n");
00822         }
00823         if (32 == Bpp)
00824         {
00825             Output(Out, "ULONG CenterCount;\n");
00826         }
00827         else
00828         {
00829             Output(Out, "ULONG LeftCount, CenterCount, RightCount;\n");
00830         }
00831         if (ROPCODE_GENERIC == RopInfo->RopCode)
00832         {
00833             Output(Out, "BOOLEAN UsesSource, UsesPattern;\n");
00834             Output(Out, "\n");
00835             Output(Out, "UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);\n");
00836             Output(Out, "UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);\n");
00837         }
00838         Output(Out, "\n");
00839         if (! RopInfo->UsesSource)
00840         {
00841             CreateBase(Out, 0, 0, Bpp);
00842             CreateCounts(Out, Bpp);
00843             MARK(Out);
00844         }
00845         Output(Out, "LineCount = BltInfo->DestRect.bottom - BltInfo->DestRect.top;\n");
00846 
00847         Output(Out, "\n");
00848         if (RopInfo->UsesPattern)
00849         {
00850             if (ROPCODE_GENERIC == RopInfo->RopCode)
00851             {
00852                 Output(Out, "if (UsesPattern && NULL != BltInfo->PatternSurface)\n");
00853             }
00854             else
00855             {
00856                 Output(Out, "if (NULL != BltInfo->PatternSurface)\n");
00857             }
00858             Output(Out, "{\n");
00859             CreateActionBlock(Out, Bpp, RopInfo, FLAG_PATTERNSURFACE);
00860             MARK(Out);
00861             Output(Out, "}\n");
00862             Output(Out, "else\n");
00863             Output(Out, "{\n");
00864             if (ROPCODE_GENERIC == RopInfo->RopCode)
00865             {
00866                 Output(Out, "if (UsesPattern)\n");
00867                 Output(Out, "{\n");
00868             }
00869             for (Partial = 0; Partial < 32 / Bpp; Partial++)
00870             {
00871                 if (0 == Partial)
00872                 {
00873                     Output(Out, "if (!BltInfo->Brush)\n");
00874                     Output(Out, "{\n");
00875                     Output(Out, "Pattern = 0;\n");
00876                     Output(Out, "}\n");
00877                     Output(Out, "else\n");
00878                     Output(Out, "{\n");
00879                     Output(Out, "Pattern = BltInfo->Brush->iSolidColor");
00880                 }
00881                 else
00882                 {
00883                     Output(Out, "          (BltInfo->Brush->iSolidColor << %d)",
00884                            Partial * Bpp);
00885                 }
00886                 if (32 / Bpp <= Partial + 1)
00887                 {
00888                     Output(Out, ";\n");
00889                     Output(Out, "}\n");
00890                 }
00891                 else
00892                 {
00893                     Output(Out, " |\n");
00894                 }
00895             }
00896             if (ROPCODE_PATINVERT == RopInfo->RopCode ||
00897                     ROPCODE_MERGECOPY == RopInfo->RopCode)
00898             {
00899                 Output(Out, "if (0 == Pattern)\n");
00900                 Output(Out, "{\n");
00901                 if (ROPCODE_MERGECOPY == RopInfo->RopCode)
00902                 {
00903                     Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
00904                            "&BltInfo->DestRect, 0x0);\n", Bpp);
00905                 }
00906                 Output(Out, "return;\n");
00907                 Output(Out, "}\n");
00908             }
00909             else if (ROPCODE_PATPAINT == RopInfo->RopCode)
00910             {
00911                 Output(Out, "if ((~0) == Pattern)\n");
00912                 Output(Out, "{\n");
00913                 Output(Out, "DIB_%uBPP_ColorFill(BltInfo->DestSurface, "
00914                        "&BltInfo->DestRect, ~0);\n", Bpp);
00915                 Output(Out, "return;\n");
00916                 Output(Out, "}\n");
00917             }
00918             if (ROPCODE_GENERIC == RopInfo->RopCode)
00919             {
00920                 Output(Out, "}\n");
00921             }
00922             CreateActionBlock(Out, Bpp, RopInfo, 0);
00923             MARK(Out);
00924             Output(Out, "}\n");
00925         }
00926         else
00927         {
00928             CreateActionBlock(Out, Bpp, RopInfo, 0);
00929             MARK(Out);
00930         }
00931     }
00932     Output(Out, "}\n");
00933 }
00934 
00935 static void
00936 CreateTable(FILE *Out, unsigned Bpp)
00937 {
00938     unsigned RopCode;
00939 
00940     MARK(Out);
00941     Output(Out, "\n");
00942     Output(Out, "static void (*PrimitivesTable[256])(PBLTINFO) =\n");
00943     Output(Out, "{\n");
00944     for (RopCode = 0; RopCode < 256; RopCode++)
00945     {
00946         PrintRoutineName(Out, Bpp, FindRopInfo(RopCode));
00947         if (RopCode < 255)
00948         {
00949             Output(Out, ",");
00950         }
00951         Output(Out, "\n");
00952     }
00953     Output(Out, "};\n");
00954 }
00955 
00956 static void
00957 CreateBitBlt(FILE *Out, unsigned Bpp)
00958 {
00959     MARK(Out);
00960     Output(Out, "\n");
00961     Output(Out, "BOOLEAN\n");
00962     Output(Out, "DIB_%uBPP_BitBlt(PBLTINFO BltInfo)\n", Bpp);
00963     Output(Out, "{\n");
00964     Output(Out, "PrimitivesTable[BltInfo->Rop4 & 0xff](BltInfo);\n");
00965     Output(Out, "\n");
00966     Output(Out, "return TRUE;\n");
00967     Output(Out, "}\n");
00968 }
00969 
00970 static void
00971 Generate(char *OutputDir, unsigned Bpp)
00972 {
00973     FILE *Out;
00974     unsigned RopCode;
00975     PROPINFO RopInfo;
00976     char *FileName;
00977 
00978     FileName = malloc(strlen(OutputDir) + 12);
00979     if (NULL == FileName)
00980     {
00981         fprintf(stderr, "Out of memory\n");
00982         exit(1);
00983     }
00984     strcpy(FileName, OutputDir);
00985     if ('/' != FileName[strlen(FileName) - 1])
00986     {
00987         strcat(FileName, "/");
00988     }
00989     sprintf(FileName + strlen(FileName), "dib%ugen.c", Bpp);
00990 
00991     Out = fopen(FileName, "w");
00992     free(FileName);
00993     if (NULL == Out)
00994     {
00995         perror("Error opening output file");
00996         exit(1);
00997     }
00998 
00999     MARK(Out);
01000     Output(Out, "/* This is a generated file. Please do not edit */\n");
01001     Output(Out, "\n");
01002     Output(Out, "#include <win32k.h>\n");
01003     CreateShiftTables(Out);
01004 
01005     RopInfo = FindRopInfo(ROPCODE_GENERIC);
01006     CreatePrimitive(Out, Bpp, RopInfo);
01007     for (RopCode = 0; RopCode < 256; RopCode++)
01008     {
01009         RopInfo = FindRopInfo(RopCode);
01010         if (NULL != RopInfo)
01011         {
01012             CreatePrimitive(Out, Bpp, RopInfo);
01013         }
01014     }
01015     CreateTable(Out, Bpp);
01016     CreateBitBlt(Out, Bpp);
01017 
01018     fclose(Out);
01019 }
01020 
01021 int
01022 main(int argc, char *argv[])
01023 {
01024     unsigned Index;
01025     static unsigned DestBpp[] =
01026     { 8, 16, 32 };
01027 
01028     if (argc < 2)
01029         return 0;
01030 
01031     for (Index = 0; Index < sizeof(DestBpp) / sizeof(DestBpp[0]); Index++)
01032     {
01033         Generate(argv[1], DestBpp[Index]);
01034     }
01035 
01036     return 0;
01037 }

Generated on Sun May 27 2012 04:37:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.