1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS 4 * FILE: dll/opengl/opengl32/swimpl.c 5 * PURPOSE: OpenGL32 DLL, opengl software implementation 6 */ 7 8 #include "opengl32.h" 9 10 /* MESA includes */ 11 #include <context.h> 12 #include <matrix.h> 13 14 WINE_DEFAULT_DEBUG_CHANNEL(opengl32); 15 16 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3) 17 #define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3) 18 19 /* Flags for our pixel formats */ 20 #define SB_FLAGS (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT) 21 #define SB_FLAGS_WINDOW (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT) 22 #define SB_FLAGS_PALETTE (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT | PFD_NEED_PALETTE) 23 #define DB_FLAGS (PFD_DOUBLEBUFFER | PFD_SWAP_COPY | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT) 24 #define DB_FLAGS_PALETTE (PFD_DOUBLEBUFFER | PFD_SWAP_COPY | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT | PFD_NEED_PALETTE) 25 26 27 struct pixel_format 28 { 29 DWORD dwFlags; 30 BYTE iPixelType; 31 BYTE cColorBits; 32 BYTE cRedBits; BYTE cRedShift; 33 BYTE cGreenBits; BYTE cGreenShift; 34 BYTE cBlueBits; BYTE cBlueShift; 35 BYTE cAlphaBits; BYTE cAlphaShift; 36 BYTE cAccumBits; 37 BYTE cAccumRedBits; BYTE cAccumGreenBits; BYTE cAccumBlueBits; BYTE cAccumAlphaBits; 38 BYTE cDepthBits; 39 }; 40 41 static const struct pixel_format pixel_formats_32[] = 42 { 43 /* 32bpp */ 44 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 45 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 46 {DB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 47 {DB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 48 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 49 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 50 {DB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 51 {DB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 52 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 53 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 54 {DB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 55 {DB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 56 /* 24bpp */ 57 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 58 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 59 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 60 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 61 {SB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 62 {SB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 63 /* 16 bpp */ 64 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 32}, 65 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 16}, 66 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 32}, 67 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 16}, 68 {SB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 69 {SB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 70 /* 8bpp */ 71 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 32}, 72 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 16}, 73 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 32}, 74 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 16}, 75 {SB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 32}, 76 {SB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 16}, 77 /* 4bpp */ 78 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 32}, 79 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 16}, 80 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 32}, 81 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 16}, 82 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 32}, 83 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 16}, 84 }; 85 86 static const struct pixel_format pixel_formats_24[] = 87 { 88 /* 24bpp */ 89 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 90 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 91 {DB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 92 {DB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 93 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 94 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 95 {DB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 96 {DB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 97 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 98 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 99 {DB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 100 {DB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 101 /* 32bpp */ 102 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 103 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 104 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 105 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 106 {SB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 107 {SB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 108 /* 16 bpp */ 109 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 32}, 110 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 16}, 111 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 32}, 112 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 16}, 113 {SB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 114 {SB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 115 /* 8bpp */ 116 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 32}, 117 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 16}, 118 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 32}, 119 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 16}, 120 {SB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 32}, 121 {SB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 16}, 122 /* 4bpp */ 123 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 32}, 124 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 16}, 125 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 32}, 126 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 16}, 127 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 32}, 128 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 16}, 129 }; 130 131 static const struct pixel_format pixel_formats_16[] = 132 { 133 /* 16 bpp - 565 */ 134 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 32}, 135 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 16}, 136 {DB_FLAGS, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 32}, 137 {DB_FLAGS, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 16}, 138 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 32}, 139 {SB_FLAGS_WINDOW, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 16}, 140 {DB_FLAGS, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 32}, 141 {DB_FLAGS, PFD_TYPE_RGBA, 16, 5, 11, 6, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 16}, 142 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 143 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 144 {DB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 145 {DB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 11, 6, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 146 /* 24bpp */ 147 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 148 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 149 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 150 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 151 {SB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 152 {SB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 153 /* 32bpp */ 154 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 155 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 156 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 157 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 158 {SB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 159 {SB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 160 /* 8bpp */ 161 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 32}, 162 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 16}, 163 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 32}, 164 {SB_FLAGS, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 16}, 165 {SB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 32}, 166 {SB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 16}, 167 /* 4bpp */ 168 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 32}, 169 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 16}, 170 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 32}, 171 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 16}, 172 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 32}, 173 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 16}, 174 }; 175 176 static const struct pixel_format pixel_formats_8[] = 177 { 178 /* 8bpp */ 179 {SB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 32}, 180 {SB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 16}, 181 {DB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 32}, 182 {DB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 0, 0, 32, 11, 11, 10, 0, 16}, 183 {SB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 32}, 184 {SB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 16}, 185 {DB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 32}, 186 {DB_FLAGS_PALETTE, PFD_TYPE_RGBA, 8, 3, 0, 3, 3, 2, 6, 8, 0, 32, 8, 8, 8, 8, 16}, 187 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 32}, 188 {SB_FLAGS_WINDOW, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 16}, 189 {DB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 32}, 190 {DB_FLAGS, PFD_TYPE_COLORINDEX, 8, 3, 0, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, 0, 16}, 191 /* 24bpp */ 192 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 193 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 194 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 195 {SB_FLAGS, PFD_TYPE_RGBA, 24, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 196 {SB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 197 {SB_FLAGS, PFD_TYPE_COLORINDEX, 24, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 198 /* 32bpp */ 199 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 32}, 200 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 0, 0, 64, 16, 16, 16, 0, 16}, 201 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 32}, 202 {SB_FLAGS, PFD_TYPE_RGBA, 32, 8, 16, 8, 8, 8, 0, 8, 0, 64, 16, 16, 16, 16, 16}, 203 {SB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 204 {SB_FLAGS, PFD_TYPE_COLORINDEX, 32, 8, 16, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 205 /* 16 bpp */ 206 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 32}, 207 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 0, 0, 32, 11, 11, 10, 0, 16}, 208 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 32}, 209 {SB_FLAGS, PFD_TYPE_RGBA, 16, 5, 10, 5, 5, 5, 0, 8, 0, 32, 8, 8, 8, 8, 16}, 210 {SB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 32}, 211 {SB_FLAGS, PFD_TYPE_COLORINDEX, 16, 5, 10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 16}, 212 /* 4bpp */ 213 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 32}, 214 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 0, 0, 16, 5, 6, 5, 0, 16}, 215 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 32}, 216 {SB_FLAGS, PFD_TYPE_RGBA, 4, 1, 0, 1, 1, 1, 2, 8, 0, 16, 4, 4, 4, 4, 16}, 217 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 32}, 218 {SB_FLAGS, PFD_TYPE_COLORINDEX, 4, 1, 0, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 16}, 219 }; 220 221 struct sw_framebuffer 222 { 223 GLvisual *gl_visual; /* Describes the buffers */ 224 GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers */ 225 226 const struct pixel_format* pixel_format; 227 HDC Hdc; 228 229 /* Current width/height */ 230 GLuint width; GLuint height; 231 232 /* BackBuffer, if any */ 233 BYTE* BackBuffer; 234 }; 235 236 struct sw_context 237 { 238 GLcontext *gl_ctx; /* The core GL/Mesa context */ 239 240 /* This is to keep track of the size of the front buffer */ 241 HHOOK hook; 242 243 /* Our frame buffer*/ 244 struct sw_framebuffer* fb; 245 246 /* State variables */ 247 union 248 { 249 struct 250 { 251 BYTE ClearColor; 252 BYTE CurrentColor; 253 } u8; 254 struct 255 { 256 USHORT ClearColor; 257 USHORT CurrentColor; 258 } u16; 259 struct 260 { 261 ULONG ClearColor; 262 ULONG CurrentColor; 263 } u24; 264 struct 265 { 266 ULONG ClearColor; 267 ULONG CurrentColor; 268 } u32; 269 }; 270 GLenum Mode; 271 }; 272 273 /* WGL <-> mesa glue */ 274 static const struct pixel_format* get_format(INT pf_index, INT* pf_count) 275 { 276 HDC hdc; 277 INT bpp, nb_format; 278 const struct pixel_format* ret; 279 280 hdc = GetDC(NULL); 281 bpp = GetDeviceCaps(hdc, BITSPIXEL); 282 ReleaseDC(NULL, hdc); 283 284 switch (bpp) 285 { 286 #define HANDLE_BPP(__x__) \ 287 case __x__: \ 288 nb_format = ARRAYSIZE(pixel_formats_##__x__); \ 289 if ((pf_index > nb_format) || (pf_index <= 0)) \ 290 ret = NULL; \ 291 else \ 292 ret = &pixel_formats_##__x__[pf_index - 1]; \ 293 break 294 295 HANDLE_BPP(32); 296 HANDLE_BPP(24); 297 HANDLE_BPP(16); 298 HANDLE_BPP(8); 299 #undef HANDLE_BPP 300 default: 301 FIXME("Unhandled bit depth %u, defaulting to 32bpp\n", bpp); 302 nb_format = ARRAYSIZE(pixel_formats_32); 303 if ((pf_index > nb_format) || (pf_index == 0)) 304 ret = NULL; 305 else 306 ret = &pixel_formats_32[pf_index - 1]; 307 } 308 309 if (pf_count) 310 *pf_count = nb_format; 311 312 return ret; 313 } 314 315 INT sw_DescribePixelFormat(HDC hdc, INT format, UINT size, PIXELFORMATDESCRIPTOR* descr) 316 { 317 INT ret; 318 const struct pixel_format *pixel_format; 319 320 TRACE("Describing format %i.\n", format); 321 322 pixel_format = get_format(format, &ret); 323 if(!descr) 324 return ret; 325 if((format > ret) || (size != sizeof(*descr))) 326 return 0; 327 328 /* Fill the structure */ 329 descr->nSize = sizeof(*descr); 330 descr->nVersion = 1; 331 descr->dwFlags = pixel_format->dwFlags; 332 descr->iPixelType = pixel_format->iPixelType; 333 descr->cColorBits = pixel_format->cColorBits; 334 descr->cRedBits = pixel_format->cRedBits; 335 descr->cRedShift = pixel_format->cRedShift; 336 descr->cGreenBits = pixel_format->cGreenBits; 337 descr->cGreenShift = pixel_format->cGreenShift; 338 descr->cBlueBits = pixel_format->cBlueBits; 339 descr->cBlueShift = pixel_format->cBlueShift; 340 descr->cAlphaBits = pixel_format->cAlphaBits; 341 descr->cAlphaShift = pixel_format->cAlphaShift; 342 descr->cAccumBits = pixel_format->cAccumBits; 343 descr->cAccumRedBits = pixel_format->cAccumRedBits; 344 descr->cAccumGreenBits = pixel_format->cAccumGreenBits; 345 descr->cAccumBlueBits = pixel_format->cAccumBlueBits; 346 descr->cAccumAlphaBits = pixel_format->cAccumAlphaBits; 347 descr->cDepthBits = pixel_format->cDepthBits; 348 descr->cStencilBits = STENCIL_BITS; 349 descr->cAuxBuffers = 0; 350 descr->iLayerType = PFD_MAIN_PLANE; 351 descr->bReserved = 0; 352 descr->dwLayerMask = 0; 353 descr->dwVisibleMask = 0; 354 descr->dwDamageMask = 0; 355 356 return ret; 357 } 358 359 BOOL sw_SetPixelFormat(HDC hdc, struct wgl_dc_data* dc_data, INT format) 360 { 361 struct sw_framebuffer* fb; 362 const struct pixel_format *pixel_format; 363 364 /* So, someone is crazy enough to ask for sw implementation. Announce it. */ 365 TRACE("OpenGL software implementation START for hdc %p, format %i!\n", hdc, format); 366 367 pixel_format = get_format(format, NULL); 368 if (!pixel_format) 369 return FALSE; 370 371 /* allocate our structure */ 372 fb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*fb)); 373 if(!fb) 374 { 375 ERR("HeapAlloc FAILED!\n"); 376 return FALSE; 377 } 378 /* Set the format */ 379 fb->pixel_format = pixel_format; 380 381 fb->gl_visual = gl_create_visual( 382 pixel_format->iPixelType == PFD_TYPE_RGBA, 383 pixel_format->cAlphaBits != 0, 384 (pixel_format->dwFlags & PFD_DOUBLEBUFFER) != 0, 385 pixel_format->cDepthBits, 386 STENCIL_BITS, 387 max(max(max(pixel_format->cAccumRedBits, pixel_format->cAccumGreenBits), pixel_format->cAccumBlueBits), pixel_format->cAccumAlphaBits), 388 pixel_format->iPixelType == PFD_TYPE_COLORINDEX ? pixel_format->cColorBits : 0, 389 ((1ul << pixel_format->cRedBits) - 1), 390 ((1ul << pixel_format->cGreenBits) - 1), 391 ((1ul << pixel_format->cBlueBits) - 1), 392 pixel_format->cAlphaBits != 0 ? ((1ul << pixel_format->cAlphaBits) - 1) : 255.0f, 393 pixel_format->cRedBits, 394 pixel_format->cGreenBits, 395 pixel_format->cBlueBits, 396 pixel_format->cAlphaBits); 397 398 if(!fb->gl_visual) 399 { 400 ERR("Failed to allocate a GL visual.\n"); 401 HeapFree(GetProcessHeap(), 0, fb); 402 return FALSE; 403 } 404 405 /* Allocate the framebuffer structure */ 406 fb->gl_buffer = gl_create_framebuffer(fb->gl_visual); 407 if (!fb->gl_buffer) { 408 ERR("Failed to allocate the mesa framebuffer structure.\n"); 409 gl_destroy_visual( fb->gl_visual ); 410 HeapFree(GetProcessHeap(), 0, fb); 411 return FALSE; 412 } 413 414 /* Save our DC */ 415 fb->Hdc = hdc; 416 417 /* Everything went fine */ 418 dc_data->sw_data = fb; 419 return TRUE; 420 } 421 422 DHGLRC sw_CreateContext(struct wgl_dc_data* dc_data) 423 { 424 struct sw_context* sw_ctx; 425 struct sw_framebuffer* fb = dc_data->sw_data; 426 427 sw_ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sw_ctx)); 428 if(!sw_ctx) 429 return NULL; 430 431 /* Initialize the context */ 432 sw_ctx->gl_ctx = gl_create_context(fb->gl_visual, NULL, sw_ctx); 433 if(!sw_ctx->gl_ctx) 434 { 435 ERR("Failed to initialize the mesa context.\n"); 436 HeapFree(GetProcessHeap(), 0, sw_ctx); 437 return NULL; 438 } 439 440 sw_ctx->fb = fb; 441 442 /* Choose relevant default */ 443 sw_ctx->Mode = fb->gl_visual->DBflag ? GL_BACK : GL_FRONT; 444 445 return (DHGLRC)sw_ctx; 446 } 447 448 BOOL sw_DeleteContext(DHGLRC dhglrc) 449 { 450 struct sw_context* sw_ctx = (struct sw_context*)dhglrc; 451 /* Those get clobbered by _mesa_free_context_data via _glapi_set{context,dispath_table} */ 452 void* icd_save = IntGetCurrentICDPrivate(); 453 const GLDISPATCHTABLE* table_save = IntGetCurrentDispatchTable(); 454 455 /* Destroy everything */ 456 gl_destroy_context(sw_ctx->gl_ctx); 457 458 HeapFree(GetProcessHeap(), 0, sw_ctx); 459 460 /* Restore this */ 461 IntSetCurrentDispatchTable(table_save); 462 IntSetCurrentICDPrivate(icd_save); 463 464 return TRUE; 465 } 466 467 extern void APIENTRY _mesa_ColorTableEXT(GLenum, GLenum, GLsizei, GLenum, GLenum, const void*); 468 extern void APIENTRY _mesa_ColorSubTableEXT(GLenum, GLsizei, GLsizei, GLenum, GLenum, const void*); 469 extern void APIENTRY _mesa_GetColorTableEXT(GLenum, GLenum, GLenum, void*); 470 extern void APIENTRY _mesa_GetColorTableParameterivEXT(GLenum, GLenum, GLfloat*); 471 extern void APIENTRY _mesa_GetColorTableParameterfvEXT(GLenum, GLenum, GLint*); 472 473 static void APIENTRY _swimpl_AddSwapHintRectWIN(GLint x, GLint y, GLsizei width, GLsizei height) 474 { 475 UNIMPLEMENTED; 476 } 477 478 PROC sw_GetProcAddress(LPCSTR name) 479 { 480 /* GL_EXT_paletted_texture */ 481 if (strcmp(name, "glColorTableEXT") == 0) 482 return (PROC)_mesa_ColorTableEXT; 483 if (strcmp(name, "glColorSubTableEXT") == 0) 484 return (PROC)_mesa_ColorSubTableEXT; 485 if (strcmp(name, "glColorGetTableEXT") == 0) 486 return (PROC)_mesa_GetColorTableEXT; 487 if (strcmp(name, "glGetColorTableParameterivEXT") == 0) 488 return (PROC)_mesa_GetColorTableParameterivEXT; 489 if (strcmp(name, "glGetColorTableParameterfvEXT") == 0) 490 return (PROC)_mesa_GetColorTableParameterfvEXT; 491 if (strcmp(name, "glAddSwapHintRectWIN") == 0) 492 return (PROC)_swimpl_AddSwapHintRectWIN; 493 494 WARN("Asking for proc address %s, returning NULL.\n", name); 495 return NULL; 496 } 497 498 BOOL sw_CopyContext(DHGLRC dhglrcSrc, DHGLRC dhglrcDst, UINT mask) 499 { 500 FIXME("Software wglCopyContext is UNIMPLEMENTED, mask %lx.\n", mask); 501 return FALSE; 502 } 503 504 BOOL sw_ShareLists(DHGLRC dhglrcSrc, DHGLRC dhglrcDst) 505 { 506 #if 0 507 struct sw_context* sw_ctx_src = (struct sw_context*)dhglrcSrc; 508 struct sw_context* sw_ctx_dst = (struct sw_context*)dhglrcDst; 509 510 /* See if it was already shared */ 511 if(sw_ctx_dst->gl_ctx->Shared->RefCount > 1) 512 return FALSE; 513 514 /* Unreference the old, share the new */ 515 gl_reference_shared_state(sw_ctx_dst->gl_ctx, 516 &sw_ctx_dst->gl_ctx->Shared, 517 sw_ctx_src->gl_ctx->Shared); 518 #endif 519 FIXME("Unimplemented!\n"); 520 return TRUE; 521 } 522 523 static 524 LRESULT CALLBACK 525 sw_call_window_proc( 526 int nCode, 527 WPARAM wParam, 528 LPARAM lParam ) 529 { 530 struct wgl_dc_data* dc_data = IntGetCurrentDcData(); 531 struct sw_context* ctx = (struct sw_context*)IntGetCurrentDHGLRC(); 532 PCWPSTRUCT pParams = (PCWPSTRUCT)lParam; 533 534 if((!dc_data) || (!ctx)) 535 return 0; 536 537 if(!(dc_data->flags & WGL_DC_OBJ_DC)) 538 return 0; 539 540 if((nCode < 0) || (dc_data->owner.hwnd != pParams->hwnd) || (dc_data->sw_data == NULL)) 541 return CallNextHookEx(ctx->hook, nCode, wParam, lParam); 542 543 if (pParams->message == WM_WINDOWPOSCHANGED) 544 { 545 /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to 546 * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx 547 * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it 548 * can be masked out by the application. */ 549 LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam; 550 if((lpWindowPos->flags & SWP_SHOWWINDOW) || 551 !(lpWindowPos->flags & SWP_NOMOVE) || 552 !(lpWindowPos->flags & SWP_NOSIZE)) 553 { 554 /* Size in WINDOWPOS includes the window frame, so get the size 555 * of the client area via GetClientRect. */ 556 RECT client_rect; 557 UINT width, height; 558 559 TRACE("Got WM_WINDOWPOSCHANGED\n"); 560 561 GetClientRect(pParams->hwnd, &client_rect); 562 width = client_rect.right - client_rect.left; 563 height = client_rect.bottom - client_rect.top; 564 /* Do not reallocate for minimized windows */ 565 if(width <= 0 || height <= 0) 566 goto end; 567 /* Propagate to mesa */ 568 gl_ResizeBuffersMESA(ctx->gl_ctx); 569 } 570 } 571 572 end: 573 return CallNextHookEx(ctx->hook, nCode, wParam, lParam); 574 } 575 576 static const char* renderer_string(void) 577 { 578 return "ReactOS SW Implementation"; 579 } 580 581 static inline void PUT_PIXEL_8(BYTE* Buffer, BYTE Value) 582 { 583 *Buffer = Value; 584 } 585 static inline void PUT_PIXEL_16(USHORT* Buffer, USHORT Value) 586 { 587 *Buffer = Value; 588 } 589 static inline void PUT_PIXEL_24(ULONG* Buffer, ULONG Value) 590 { 591 *Buffer &= 0xFF000000ul; 592 *Buffer |= Value & 0x00FFFFFF; 593 } 594 static inline void PUT_PIXEL_32(ULONG* Buffer, ULONG Value) 595 { 596 *Buffer = Value; 597 } 598 599 static inline BYTE GET_PIXEL_8(BYTE* Buffer) 600 { 601 return *Buffer; 602 } 603 604 static inline USHORT GET_PIXEL_16(USHORT* Buffer) 605 { 606 return *Buffer; 607 } 608 609 static inline ULONG GET_PIXEL_24(ULONG* Buffer) 610 { 611 return *Buffer & 0x00FFFFFF; 612 } 613 614 static inline ULONG GET_PIXEL_32(ULONG* Buffer) 615 { 616 return *Buffer; 617 } 618 619 static inline COLORREF MAKE_COLORREF_8(const struct pixel_format *format, BYTE Color) 620 { 621 BYTE R,G,B; 622 623 if (format->iPixelType == PFD_TYPE_COLORINDEX) 624 return PALETTEINDEX(Color); 625 626 R = (Color & 0x7) << 5; 627 G = (Color & 0x38) << 2; 628 B = Color & 0xC; 629 630 return RGB(R, G, B); 631 } 632 633 static inline COLORREF MAKE_COLORREF_16(const struct pixel_format *format, USHORT Color) 634 { 635 BYTE R,G,B; 636 637 if (format->iPixelType == PFD_TYPE_COLORINDEX) 638 return PALETTEINDEX(Color); 639 640 R = (Color & 0x7) << 5; 641 G = (Color & 0x38) << 2; 642 B = Color & 0xC; 643 644 return RGB(R, G, B); 645 } 646 647 static inline COLORREF MAKE_COLORREF_24(const struct pixel_format *format, ULONG Color) 648 { 649 BYTE R,G,B; 650 651 if (format->iPixelType == PFD_TYPE_COLORINDEX) 652 return PALETTEINDEX(Color); 653 654 R = (Color & 0xFF0000) >> 16; 655 G = (Color & 0x00FF00) >> 8; 656 B = Color & 0xFF; 657 658 return RGB(R, G, B); 659 } 660 661 static inline COLORREF MAKE_COLORREF_32(const struct pixel_format *format, ULONG Color) 662 { 663 BYTE R,G,B; 664 665 if (format->iPixelType == PFD_TYPE_COLORINDEX) 666 return PALETTEINDEX(Color); 667 668 R = (Color & 0xFF0000) >> 16; 669 G = (Color & 0x00FF00) >> 8; 670 B = Color & 0xFF; 671 672 return RGB(R, G, B); 673 } 674 675 676 static inline BYTE PACK_COLOR_8(GLubyte r, GLubyte g, GLubyte b) 677 { 678 return (r & 0x7) | ((g & 0x7) << 3) | ((b & 0x3) << 6); 679 } 680 681 static inline USHORT PACK_COLOR_16(GLubyte r, GLubyte g, GLubyte b) 682 { 683 return ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F); 684 } 685 686 static inline ULONG PACK_COLOR_24(GLubyte r, GLubyte g, GLubyte b) 687 { 688 return (r << 16) | (g << 8) | (b); 689 } 690 691 static inline ULONG PACK_COLOR_32(GLubyte r, GLubyte g, GLubyte b) 692 { 693 return (r << 16) | (g << 8) | (b); 694 } 695 696 static inline COLORREF PACK_COLORREF_8(GLubyte r, GLubyte g, GLubyte b) 697 { 698 return RGB(r << 5, g << 5, b << 6); 699 } 700 701 static inline COLORREF PACK_COLORREF_16(GLubyte r, GLubyte g, GLubyte b) 702 { 703 return RGB(r << 3, g << 2, b << 3); 704 } 705 706 static inline COLORREF PACK_COLORREF_24(GLubyte r, GLubyte g, GLubyte b) 707 { 708 return RGB(r, g, b); 709 } 710 711 static inline COLORREF PACK_COLORREF_32(GLubyte r, GLubyte g, GLubyte b) 712 { 713 return RGB(r, g, b); 714 } 715 716 static inline void UNPACK_COLOR_8(BYTE Color, GLubyte* r, GLubyte* g, GLubyte* b) 717 { 718 *r = Color & 0x7; 719 *g = (Color >> 3) & 0x7; 720 *b = (Color >> 6) & 0x3; 721 } 722 723 static inline void UNPACK_COLOR_16(USHORT Color, GLubyte* r, GLubyte* g, GLubyte* b) 724 { 725 *r = (Color >> 11) & 0x1F; 726 *g = (Color >> 5) & 0x3F; 727 *b = Color & 0x1F; 728 } 729 730 static inline void UNPACK_COLOR_24(ULONG Color, GLubyte* r, GLubyte* g, GLubyte* b) 731 { 732 *r = (Color >> 16) & 0xFF; 733 *g = (Color >> 8) & 0xFF; 734 *b = Color & 0xFF; 735 } 736 737 static inline void UNPACK_COLOR_32(ULONG Color, GLubyte* r, GLubyte* g, GLubyte* b) 738 { 739 *r = (Color >> 16) & 0xFF; 740 *g = (Color >> 8) & 0xFF; 741 *b = Color & 0xFF; 742 } 743 744 static inline void UNPACK_COLORREF_8(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 745 { 746 *r = GetRValue(Color) >> 5; 747 *g = GetGValue(Color) >> 5; 748 *b = GetBValue(Color) >> 6; 749 } 750 751 static inline void UNPACK_COLORREF_16(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 752 { 753 *r = GetRValue(Color) >> 3; 754 *g = GetGValue(Color) >> 2; 755 *b = GetBValue(Color) >> 3; 756 } 757 758 static inline void UNPACK_COLORREF_24(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 759 { 760 *r = GetRValue(Color); 761 *g = GetGValue(Color); 762 *b = GetBValue(Color); 763 } 764 765 static inline void UNPACK_COLORREF_32(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 766 { 767 *r = GetRValue(Color); 768 *g = GetGValue(Color); 769 *b = GetBValue(Color); 770 } 771 772 /* 773 * Set the color index used to clear the color buffer. 774 */ 775 #define CLEAR_INDEX(__bpp, __type) \ 776 static void clear_index_##__bpp(GLcontext* ctx, GLuint index) \ 777 { \ 778 struct sw_context* sw_ctx = ctx->DriverCtx; \ 779 \ 780 sw_ctx->u##__bpp.ClearColor = (__type)index; \ 781 } 782 CLEAR_INDEX(8, BYTE) 783 CLEAR_INDEX(16, USHORT) 784 CLEAR_INDEX(24, ULONG) 785 CLEAR_INDEX(32, ULONG) 786 #undef CLEAR_INDEX 787 788 /* 789 * Set the color used to clear the color buffer. 790 */ 791 #define CLEAR_COLOR(__bpp) \ 792 static void clear_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) \ 793 { \ 794 struct sw_context* sw_ctx = ctx->DriverCtx; \ 795 \ 796 sw_ctx->u##__bpp.ClearColor = PACK_COLOR_##__bpp(r, g, b); \ 797 \ 798 TRACE("Set Clear color %u, %u, %u.\n", r, g, b); \ 799 } 800 CLEAR_COLOR(8) 801 CLEAR_COLOR(16) 802 CLEAR_COLOR(24) 803 CLEAR_COLOR(32) 804 #undef CLEAR_COLOR 805 806 /* 807 * Clear the specified region of the color buffer using the clear color 808 * or index as specified by one of the two functions above. 809 */ 810 static void clear_frontbuffer( 811 struct sw_context* sw_ctx, 812 struct sw_framebuffer* fb, 813 GLint x, 814 GLint y, 815 GLint width, 816 GLint height, 817 COLORREF ClearColor) 818 { 819 HBRUSH Brush; 820 BOOL ret; 821 822 TRACE("Clearing front buffer (%u, %u, %u, %u), color 0x%08x.\n", x, y, width, height, ClearColor); 823 824 Brush = CreateSolidBrush(ClearColor); 825 Brush = SelectObject(fb->Hdc, Brush); 826 827 ret = PatBlt(fb->Hdc, x, fb->height - (y + height), width, height, PATCOPY); 828 if (!ret) 829 { 830 ERR("PatBlt failed. last Error %d.\n", GetLastError()); 831 } 832 833 Brush = SelectObject(fb->Hdc, Brush); 834 DeleteObject(Brush); 835 } 836 837 #define CLEAR(__bpp, __type, __pixel_size) \ 838 static void clear_##__bpp(GLcontext* ctx, GLboolean all,GLint x, GLint y, GLint width, GLint height)\ 839 { \ 840 struct sw_context* sw_ctx = ctx->DriverCtx; \ 841 struct sw_framebuffer* fb = sw_ctx->fb; \ 842 BYTE* ScanLine; \ 843 \ 844 if (all) \ 845 { \ 846 x = y = 0; \ 847 width = fb->width; \ 848 height = fb->height; \ 849 } \ 850 \ 851 if (sw_ctx->Mode == GL_FRONT) \ 852 { \ 853 clear_frontbuffer(sw_ctx, fb, x, y, width, height, \ 854 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.ClearColor)); \ 855 return; \ 856 } \ 857 \ 858 ScanLine = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp); \ 859 while (height--) \ 860 { \ 861 BYTE* Buffer = ScanLine + x * __pixel_size; \ 862 UINT n = width; \ 863 \ 864 while (n--) \ 865 { \ 866 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.ClearColor); \ 867 Buffer += __pixel_size; \ 868 } \ 869 \ 870 ScanLine += WIDTH_BYTES_ALIGN32(fb->width, __bpp); \ 871 } \ 872 } 873 CLEAR(8, BYTE, 1) 874 CLEAR(16, USHORT, 2) 875 CLEAR(24, ULONG, 3) 876 CLEAR(32, ULONG, 4) 877 #undef CLEAR 878 879 /* Set the current color index. */ 880 #define SET_INDEX(__bpp) \ 881 static void set_index_##__bpp(GLcontext* ctx, GLuint index) \ 882 { \ 883 struct sw_context* sw_ctx = ctx->DriverCtx; \ 884 \ 885 sw_ctx->u##__bpp.CurrentColor = index; \ 886 } 887 SET_INDEX(8) 888 SET_INDEX(16) 889 SET_INDEX(24) 890 SET_INDEX(32) 891 #undef SET_INDEX 892 893 /* Set the current RGBA color. */ 894 #define SET_COLOR(__bpp) \ 895 static void set_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) \ 896 { \ 897 struct sw_context* sw_ctx = ctx->DriverCtx; \ 898 \ 899 sw_ctx->u##__bpp.CurrentColor = PACK_COLOR_##__bpp(r, g, b); \ 900 } 901 SET_COLOR(8) 902 SET_COLOR(16) 903 SET_COLOR(24) 904 SET_COLOR(32) 905 #undef SET_COLOR 906 907 /* 908 * Selects either the front or back color buffer for reading and writing. 909 * mode is either GL_FRONT or GL_BACK. 910 */ 911 static GLboolean set_buffer( GLcontext* ctx, GLenum mode ) 912 { 913 struct sw_context* sw_ctx = ctx->DriverCtx; 914 struct sw_framebuffer* fb = sw_ctx->fb; 915 916 if (!fb->gl_visual->DBflag) 917 return GL_FALSE; 918 919 if ((mode != GL_FRONT) && (mode != GL_BACK)) 920 return GL_FALSE; 921 922 sw_ctx->Mode = mode; 923 return GL_TRUE; 924 } 925 926 /* Return characteristics of the output buffer. */ 927 static void buffer_size(GLcontext* ctx, GLuint *width, GLuint *height) 928 { 929 struct sw_context* sw_ctx = ctx->DriverCtx; 930 struct sw_framebuffer* fb = sw_ctx->fb; 931 HWND Window = WindowFromDC(fb->Hdc); 932 933 if (Window) 934 { 935 RECT client_rect; 936 GetClientRect(Window, &client_rect); 937 *width = client_rect.right - client_rect.left; 938 *height = client_rect.bottom - client_rect.top; 939 } 940 else 941 { 942 /* We are drawing to a bitmap */ 943 BITMAP bm; 944 HBITMAP Hbm; 945 946 Hbm = GetCurrentObject(fb->Hdc, OBJ_BITMAP); 947 948 if (!GetObjectW(Hbm, sizeof(bm), &bm)) 949 return; 950 951 TRACE("Framebuffer size : %i, %i\n", bm.bmWidth, bm.bmHeight); 952 953 *width = bm.bmWidth; 954 *height = bm.bmHeight; 955 } 956 957 if ((*width != fb->width) || (*height != fb->height)) 958 { 959 const struct pixel_format* pixel_format = fb->pixel_format; 960 961 if (pixel_format->dwFlags & PFD_DOUBLEBUFFER) 962 { 963 /* Allocate a new backbuffer */ 964 size_t BufferSize = *height * WIDTH_BYTES_ALIGN32(*width, pixel_format->cColorBits); 965 if (!fb->BackBuffer) 966 { 967 fb->BackBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); 968 } 969 else 970 { 971 fb->BackBuffer = HeapReAlloc(GetProcessHeap(), 0, fb->BackBuffer, BufferSize); 972 } 973 if (!fb->BackBuffer) 974 { 975 ERR("Failed allocating back buffer !.\n"); 976 return; 977 } 978 } 979 980 fb->width = *width; 981 fb->height = *height; 982 } 983 } 984 985 /* Write a horizontal span of color pixels with a boolean mask. */ 986 #define WRITE_COLOR_SPAN_FRONTBUFFER(__bpp) \ 987 static void write_color_span_frontbuffer_##__bpp(struct sw_framebuffer* fb, \ 988 GLuint n, GLint x, GLint y, \ 989 const GLubyte red[], const GLubyte green[], \ 990 const GLubyte blue[], const GLubyte mask[] ) \ 991 { \ 992 TRACE("Writing color span at %u, %u (%u)\n", x, y, n); \ 993 \ 994 if (mask) \ 995 { \ 996 while (n--) \ 997 { \ 998 if (mask[n]) \ 999 { \ 1000 SetPixel(fb->Hdc, x + n, fb->height - y, \ 1001 PACK_COLORREF_##__bpp(red[n], green[n], blue[n])); \ 1002 } \ 1003 } \ 1004 } \ 1005 else \ 1006 { \ 1007 while (n--) \ 1008 { \ 1009 SetPixel(fb->Hdc, x + n, fb->height - y, \ 1010 PACK_COLORREF_##__bpp(red[n], green[n], blue[n])); \ 1011 } \ 1012 } \ 1013 } 1014 WRITE_COLOR_SPAN_FRONTBUFFER(8) 1015 WRITE_COLOR_SPAN_FRONTBUFFER(16) 1016 WRITE_COLOR_SPAN_FRONTBUFFER(24) 1017 WRITE_COLOR_SPAN_FRONTBUFFER(32) 1018 #undef WRITE_COLOR_SPAN_FRONTBUFFER 1019 1020 #define WRITE_COLOR_SPAN(__bpp, __type, __pixel_size) \ 1021 static void write_color_span_##__bpp(GLcontext* ctx, \ 1022 GLuint n, GLint x, GLint y, \ 1023 const GLubyte red[], const GLubyte green[], \ 1024 const GLubyte blue[], const GLubyte alpha[], \ 1025 const GLubyte mask[] ) \ 1026 { \ 1027 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1028 struct sw_framebuffer* fb = sw_ctx->fb; \ 1029 BYTE* Buffer; \ 1030 \ 1031 if (sw_ctx->Mode == GL_FRONT) \ 1032 { \ 1033 write_color_span_frontbuffer_##__bpp(fb, n, x, y, red, green, blue, mask); \ 1034 return; \ 1035 } \ 1036 \ 1037 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1038 + (x + n) * __pixel_size; \ 1039 if (mask) \ 1040 { \ 1041 while (n--) \ 1042 { \ 1043 Buffer -= __pixel_size; \ 1044 if (mask[n]) \ 1045 { \ 1046 PUT_PIXEL_##__bpp((__type*)Buffer, \ 1047 PACK_COLOR_##__bpp(red[n], green[n], blue[n])); \ 1048 } \ 1049 } \ 1050 } \ 1051 else \ 1052 { \ 1053 while (n--) \ 1054 { \ 1055 Buffer -= __pixel_size; \ 1056 PUT_PIXEL_##__bpp((__type*)Buffer, \ 1057 PACK_COLOR_##__bpp(red[n], green[n], blue[n])); \ 1058 } \ 1059 } \ 1060 } 1061 WRITE_COLOR_SPAN(8, BYTE, 1) 1062 WRITE_COLOR_SPAN(16, USHORT, 2) 1063 WRITE_COLOR_SPAN(24, ULONG, 3) 1064 WRITE_COLOR_SPAN(32, ULONG, 4) 1065 #undef WRITE_COLOR_SPAN 1066 1067 static void write_monocolor_span_frontbuffer(struct sw_framebuffer* fb, GLuint n, GLint x, GLint y, 1068 const GLubyte mask[], COLORREF Color) 1069 { 1070 TRACE("Writing monocolor span at %u %u (%u), Color 0x%08x", x, y, n, Color); 1071 1072 if (mask) 1073 { 1074 while (n--) 1075 { 1076 if (mask[n]) 1077 SetPixel(fb->Hdc, x + n, y, Color); 1078 } 1079 } 1080 else 1081 { 1082 HBRUSH Brush = CreateSolidBrush(Color); 1083 Brush = SelectObject(fb->Hdc, Brush); 1084 1085 PatBlt(fb->Hdc, x, fb->height - y, n, 1, PATCOPY); 1086 1087 Brush = SelectObject(fb->Hdc, Brush); 1088 DeleteObject(Brush); 1089 } 1090 } 1091 1092 #define WRITE_MONOCOLOR_SPAN(__bpp, __type, __pixel_size) \ 1093 static void write_monocolor_span_##__bpp(GLcontext* ctx, \ 1094 GLuint n, GLint x, GLint y, \ 1095 const GLubyte mask[]) \ 1096 { \ 1097 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1098 struct sw_framebuffer* fb = sw_ctx->fb; \ 1099 BYTE* Buffer; \ 1100 \ 1101 if (sw_ctx->Mode == GL_FRONT) \ 1102 { \ 1103 write_monocolor_span_frontbuffer(fb, n, x, y, mask, \ 1104 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor)); \ 1105 return; \ 1106 } \ 1107 \ 1108 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) + (x + n) * __pixel_size; \ 1109 if (mask) \ 1110 { \ 1111 while (n--) \ 1112 { \ 1113 Buffer -= __pixel_size; \ 1114 if (mask[n]) \ 1115 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \ 1116 } \ 1117 } \ 1118 else \ 1119 { \ 1120 while(n--) \ 1121 { \ 1122 Buffer -= __pixel_size; \ 1123 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \ 1124 } \ 1125 } \ 1126 } 1127 WRITE_MONOCOLOR_SPAN(8, BYTE, 1) 1128 WRITE_MONOCOLOR_SPAN(16, USHORT, 2) 1129 WRITE_MONOCOLOR_SPAN(24, ULONG, 3) 1130 WRITE_MONOCOLOR_SPAN(32, ULONG, 4) 1131 #undef WRITE_MONOCOLOR_SPAN 1132 1133 /* Write an array of pixels with a boolean mask. */ 1134 #define WRITE_COLOR_PIXELS(__bpp, __type, __pixel_size) \ 1135 static void write_color_pixels_##__bpp(GLcontext* ctx, \ 1136 GLuint n, const GLint x[], const GLint y[], \ 1137 const GLubyte r[], const GLubyte g[], \ 1138 const GLubyte b[], const GLubyte a[], \ 1139 const GLubyte mask[]) \ 1140 { \ 1141 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1142 struct sw_framebuffer* fb = sw_ctx->fb; \ 1143 \ 1144 TRACE("Writing color pixels\n"); \ 1145 \ 1146 if (sw_ctx->Mode == GL_FRONT) \ 1147 { \ 1148 while (n--) \ 1149 { \ 1150 if (mask[n]) \ 1151 { \ 1152 TRACE("Setting pixel %u, %u to 0x%08x.\n", x[n], fb->height - y[n], \ 1153 PACK_COLORREF_##__bpp(r[n], g[n], b[n])); \ 1154 SetPixel(fb->Hdc, x[n], fb->height - y[n], \ 1155 PACK_COLORREF_##__bpp(r[n], g[n], b[n])); \ 1156 } \ 1157 } \ 1158 \ 1159 return; \ 1160 } \ 1161 \ 1162 while (n--) \ 1163 { \ 1164 if (mask[n]) \ 1165 { \ 1166 BYTE* Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1167 + x[n] * __pixel_size; \ 1168 PUT_PIXEL_##__bpp((__type*)Buffer, PACK_COLOR_##__bpp(r[n], g[n], b[n])); \ 1169 } \ 1170 } \ 1171 } 1172 WRITE_COLOR_PIXELS(8, BYTE, 1) 1173 WRITE_COLOR_PIXELS(16, USHORT, 2) 1174 WRITE_COLOR_PIXELS(24, ULONG, 3) 1175 WRITE_COLOR_PIXELS(32, ULONG, 4) 1176 #undef WRITE_COLOR_PIXELS 1177 1178 static void write_monocolor_pixels_frontbuffer( 1179 struct sw_framebuffer* fb, GLuint n, 1180 const GLint x[], const GLint y[], 1181 const GLubyte mask[], COLORREF Color) 1182 { 1183 TRACE("Writing monocolor pixels to front buffer.\n"); 1184 1185 while (n--) 1186 { 1187 if (mask[n]) 1188 { 1189 SetPixel(fb->Hdc, x[n], fb->height - y[n], Color); 1190 } 1191 } 1192 } 1193 1194 /* 1195 * Write an array of pixels with a boolean mask. The current color 1196 * is used for all pixels. 1197 */ 1198 #define WRITE_MONOCOLOR_PIXELS(__bpp, __type, __pixel_size) \ 1199 static void write_monocolor_pixels_##__bpp(GLcontext* ctx, GLuint n, \ 1200 const GLint x[], const GLint y[], \ 1201 const GLubyte mask[] ) \ 1202 { \ 1203 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1204 struct sw_framebuffer* fb = sw_ctx->fb; \ 1205 \ 1206 if (sw_ctx->Mode == GL_FRONT) \ 1207 { \ 1208 write_monocolor_pixels_frontbuffer(fb, n, x, y, mask, \ 1209 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor)); \ 1210 \ 1211 return; \ 1212 } \ 1213 \ 1214 while (n--) \ 1215 { \ 1216 if (mask[n]) \ 1217 { \ 1218 BYTE* Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, 32) \ 1219 + x[n] * __pixel_size; \ 1220 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \ 1221 } \ 1222 } \ 1223 } 1224 WRITE_MONOCOLOR_PIXELS(8, BYTE, 1) 1225 WRITE_MONOCOLOR_PIXELS(16, USHORT, 2) 1226 WRITE_MONOCOLOR_PIXELS(24, ULONG, 3) 1227 WRITE_MONOCOLOR_PIXELS(32, ULONG, 4) 1228 #undef WRITE_MONOCOLOR_PIXELS 1229 1230 /* Write a horizontal span of color pixels with a boolean mask. */ 1231 static void write_index_span( GLcontext* ctx, 1232 GLuint n, GLint x, GLint y, 1233 const GLuint index[], 1234 const GLubyte mask[] ) 1235 { 1236 ERR("Not implemented yet !\n"); 1237 } 1238 1239 /* Write an array of pixels with a boolean mask. */ 1240 static void write_index_pixels( GLcontext* ctx, 1241 GLuint n, const GLint x[], const GLint y[], 1242 const GLuint index[], const GLubyte mask[] ) 1243 { 1244 ERR("Not implemented yet !\n"); 1245 } 1246 1247 /* Read a horizontal span of color-index pixels. */ 1248 static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[]) 1249 { 1250 ERR("Not implemented yet !\n"); 1251 } 1252 1253 /* Read a horizontal span of color pixels. */ 1254 #define READ_COLOR_SPAN(__bpp, __type, __pixel_size) \ 1255 static void read_color_span_##__bpp(GLcontext* ctx, \ 1256 GLuint n, GLint x, GLint y, \ 1257 GLubyte red[], GLubyte green[], \ 1258 GLubyte blue[], GLubyte alpha[] ) \ 1259 { \ 1260 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1261 struct sw_framebuffer* fb = sw_ctx->fb; \ 1262 BYTE* Buffer; \ 1263 \ 1264 if (sw_ctx->Mode == GL_FRONT) \ 1265 { \ 1266 COLORREF Color; \ 1267 while (n--) \ 1268 { \ 1269 Color = GetPixel(fb->Hdc, x + n, fb->height - y); \ 1270 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]); \ 1271 alpha[n] = 0; \ 1272 } \ 1273 \ 1274 return; \ 1275 } \ 1276 \ 1277 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1278 + (x + n) * __pixel_size; \ 1279 while (n--) \ 1280 { \ 1281 Buffer -= __pixel_size; \ 1282 UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer), \ 1283 &blue[n], &green[n], &red[n]); \ 1284 alpha[n] = 0; \ 1285 } \ 1286 } 1287 READ_COLOR_SPAN(8, BYTE, 1) 1288 READ_COLOR_SPAN(16, USHORT, 2) 1289 READ_COLOR_SPAN(24, ULONG, 3) 1290 READ_COLOR_SPAN(32, ULONG, 4) 1291 #undef READ_COLOR_SPAN 1292 1293 /* Read an array of color index pixels. */ 1294 static void read_index_pixels(GLcontext* ctx, 1295 GLuint n, const GLint x[], const GLint y[], 1296 GLuint index[], const GLubyte mask[]) 1297 { 1298 1299 ERR("Not implemented yet !\n"); 1300 } 1301 1302 /* Read an array of color pixels. */ 1303 #define READ_COLOR_PIXELS(__bpp, __type, __pixel_size) \ 1304 static void read_color_pixels_##__bpp(GLcontext* ctx, \ 1305 GLuint n, const GLint x[], const GLint y[], \ 1306 GLubyte red[], GLubyte green[], \ 1307 GLubyte blue[], GLubyte alpha[], \ 1308 const GLubyte mask[] ) \ 1309 { \ 1310 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1311 struct sw_framebuffer* fb = sw_ctx->fb; \ 1312 \ 1313 if (sw_ctx->Mode == GL_FRONT) \ 1314 { \ 1315 COLORREF Color; \ 1316 while (n--) \ 1317 { \ 1318 if (mask[n]) \ 1319 { \ 1320 Color = GetPixel(fb->Hdc, x[n], fb->height - y[n]); \ 1321 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]); \ 1322 alpha[n] = 0; \ 1323 } \ 1324 } \ 1325 \ 1326 return; \ 1327 } \ 1328 \ 1329 while (n--) \ 1330 { \ 1331 if (mask[n]) \ 1332 { \ 1333 BYTE *Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1334 + x[n] * __pixel_size; \ 1335 UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer), \ 1336 &blue[n], &green[n], &red[n]); \ 1337 alpha[n] = 0; \ 1338 } \ 1339 } \ 1340 } 1341 READ_COLOR_PIXELS(8, BYTE, 1) 1342 READ_COLOR_PIXELS(16, USHORT, 2) 1343 READ_COLOR_PIXELS(24, ULONG, 3) 1344 READ_COLOR_PIXELS(32, ULONG, 4) 1345 #undef READ_COLOR_PIXELS 1346 1347 static void setup_DD_pointers( GLcontext* ctx ) 1348 { 1349 struct sw_context* sw_ctx = ctx->DriverCtx; 1350 1351 ctx->Driver.RendererString = renderer_string; 1352 ctx->Driver.UpdateState = setup_DD_pointers; 1353 1354 switch (sw_ctx->fb->pixel_format->cColorBits) 1355 { 1356 #define HANDLE_BPP(__bpp) \ 1357 case __bpp: \ 1358 ctx->Driver.ClearIndex = clear_index_##__bpp; \ 1359 ctx->Driver.ClearColor = clear_color_##__bpp; \ 1360 ctx->Driver.Clear = clear_##__bpp; \ 1361 ctx->Driver.Index = set_index_##__bpp; \ 1362 ctx->Driver.Color = set_color_##__bpp; \ 1363 ctx->Driver.WriteColorSpan = write_color_span_##__bpp; \ 1364 ctx->Driver.WriteMonocolorSpan = write_monocolor_span_##__bpp; \ 1365 ctx->Driver.WriteMonoindexSpan = write_monocolor_span_##__bpp; \ 1366 ctx->Driver.WriteColorPixels = write_color_pixels_##__bpp; \ 1367 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels_##__bpp; \ 1368 ctx->Driver.WriteMonoindexPixels = write_monocolor_pixels_##__bpp; \ 1369 ctx->Driver.ReadColorSpan = read_color_span_##__bpp; \ 1370 ctx->Driver.ReadColorPixels = read_color_pixels_##__bpp; \ 1371 break 1372 HANDLE_BPP(8); 1373 HANDLE_BPP(16); 1374 HANDLE_BPP(24); 1375 HANDLE_BPP(32); 1376 #undef HANDLE_BPP 1377 default: 1378 ERR("Unhandled bit depth %u, defaulting to 32bpp.\n", sw_ctx->fb->pixel_format->cColorBits); 1379 ctx->Driver.ClearIndex = clear_index_32; 1380 ctx->Driver.ClearColor = clear_color_32; 1381 ctx->Driver.Clear = clear_32; 1382 ctx->Driver.Index = set_index_32; 1383 ctx->Driver.Color = set_color_32; 1384 ctx->Driver.WriteColorSpan = write_color_span_32; 1385 ctx->Driver.WriteMonocolorSpan = write_monocolor_span_32; 1386 ctx->Driver.WriteMonoindexSpan = write_monocolor_span_32; 1387 ctx->Driver.WriteColorPixels = write_color_pixels_32; 1388 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels_32; 1389 ctx->Driver.WriteMonoindexPixels = write_monocolor_pixels_32; 1390 ctx->Driver.ReadColorSpan = read_color_span_32; 1391 ctx->Driver.ReadColorPixels = read_color_pixels_32; 1392 break; 1393 } 1394 1395 ctx->Driver.SetBuffer = set_buffer; 1396 ctx->Driver.GetBufferSize = buffer_size; 1397 1398 /* Pixel/span writing functions: */ 1399 ctx->Driver.WriteIndexSpan = write_index_span; 1400 ctx->Driver.WriteIndexPixels = write_index_pixels; 1401 1402 /* Pixel/span reading functions: */ 1403 ctx->Driver.ReadIndexSpan = read_index_span; 1404 ctx->Driver.ReadIndexPixels = read_index_pixels; 1405 } 1406 1407 /* Declare API table */ 1408 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) extern void WINAPI _mesa_##name proto_args ; 1409 #define USE_GL_FUNC_RET(name, ret_type, proto_args, call_args, offset, stack) extern ret_type WINAPI _mesa_##name proto_args ; 1410 #include "glfuncs.h" 1411 1412 static GLCLTPROCTABLE sw_api_table = 1413 { 1414 OPENGL_VERSION_110_ENTRIES, 1415 { 1416 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) _mesa_##name, 1417 #include "glfuncs.h" 1418 } 1419 }; 1420 1421 /* Glue code */ 1422 GLcontext* gl_get_thread_context(void) 1423 { 1424 struct sw_context* sw_ctx = (struct sw_context*)IntGetCurrentDHGLRC(); 1425 return sw_ctx->gl_ctx; 1426 } 1427 1428 1429 BOOL sw_SetContext(struct wgl_dc_data* dc_data, DHGLRC dhglrc) 1430 { 1431 struct sw_context* sw_ctx = (struct sw_context*)dhglrc; 1432 struct sw_framebuffer* fb = dc_data->sw_data; 1433 UINT width, height; 1434 1435 /* Get framebuffer size */ 1436 if(dc_data->flags & WGL_DC_OBJ_DC) 1437 { 1438 HWND hwnd = dc_data->owner.hwnd; 1439 RECT client_rect; 1440 if(!hwnd) 1441 { 1442 ERR("Physical DC without a window!\n"); 1443 return FALSE; 1444 } 1445 if(!GetClientRect(hwnd, &client_rect)) 1446 { 1447 ERR("GetClientRect failed!\n"); 1448 return FALSE; 1449 } 1450 1451 /* This is a physical DC. Setup the hook */ 1452 sw_ctx->hook = SetWindowsHookEx(WH_CALLWNDPROC, 1453 sw_call_window_proc, 1454 NULL, 1455 GetCurrentThreadId()); 1456 1457 /* Calculate width & height */ 1458 width = client_rect.right - client_rect.left; 1459 height = client_rect.bottom - client_rect.top; 1460 } 1461 else /* OBJ_MEMDC */ 1462 { 1463 BITMAP bm; 1464 HBITMAP hbmp; 1465 HDC hdc = dc_data->owner.hdc; 1466 1467 if(fb->gl_visual->DBflag) 1468 { 1469 ERR("Memory DC called with a double buffered format.\n"); 1470 return FALSE; 1471 } 1472 1473 hbmp = GetCurrentObject( hdc, OBJ_BITMAP ); 1474 if(!hbmp) 1475 { 1476 ERR("No Bitmap!\n"); 1477 return FALSE; 1478 } 1479 if(GetObject(hbmp, sizeof(bm), &bm) == 0) 1480 { 1481 ERR("GetObject failed!\n"); 1482 return FALSE; 1483 } 1484 width = bm.bmWidth; 1485 height = bm.bmHeight; 1486 } 1487 1488 if(!width) width = 1; 1489 if(!height) height = 1; 1490 1491 /* Also make the mesa context current to mesa */ 1492 gl_make_current(sw_ctx->gl_ctx, fb->gl_buffer); 1493 1494 /* Setup our functions */ 1495 setup_DD_pointers(sw_ctx->gl_ctx); 1496 1497 /* Set the viewport if this is the first time we initialize this context */ 1498 if(sw_ctx->gl_ctx->Viewport.X == 0 && 1499 sw_ctx->gl_ctx->Viewport.Y == 0 && 1500 sw_ctx->gl_ctx->Viewport.Width == 0 && 1501 sw_ctx->gl_ctx->Viewport.Height == 0) 1502 { 1503 gl_Viewport(sw_ctx->gl_ctx, 0, 0, width, height); 1504 } 1505 1506 /* update the framebuffer size */ 1507 gl_ResizeBuffersMESA(sw_ctx->gl_ctx); 1508 1509 /* Use our API table */ 1510 IntSetCurrentDispatchTable(&sw_api_table.glDispatchTable); 1511 1512 /* We're good */ 1513 return TRUE; 1514 } 1515 1516 void sw_ReleaseContext(DHGLRC dhglrc) 1517 { 1518 struct sw_context* sw_ctx = (struct sw_context*)dhglrc; 1519 1520 /* Forward to mesa */ 1521 gl_make_current(NULL, NULL); 1522 1523 /* Unhook */ 1524 if(sw_ctx->hook) 1525 { 1526 UnhookWindowsHookEx(sw_ctx->hook); 1527 sw_ctx->hook = NULL; 1528 } 1529 } 1530 1531 BOOL sw_SwapBuffers(HDC hdc, struct wgl_dc_data* dc_data) 1532 { 1533 struct sw_framebuffer* fb = dc_data->sw_data; 1534 char Buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD)]; 1535 BITMAPINFO *bmi = (BITMAPINFO*)Buffer; 1536 BYTE Bpp = fb->pixel_format->cColorBits; 1537 1538 if (!fb->gl_visual->DBflag) 1539 return TRUE; 1540 1541 if (!fb->BackBuffer) 1542 return FALSE; 1543 1544 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader); 1545 bmi->bmiHeader.biBitCount = Bpp; 1546 bmi->bmiHeader.biClrImportant = 0; 1547 bmi->bmiHeader.biClrUsed = 0; 1548 bmi->bmiHeader.biPlanes = 1; 1549 bmi->bmiHeader.biSizeImage = WIDTH_BYTES_ALIGN32(fb->width, Bpp) * fb->height; 1550 bmi->bmiHeader.biXPelsPerMeter = 0; 1551 bmi->bmiHeader.biYPelsPerMeter = 0; 1552 bmi->bmiHeader.biHeight = fb->height; 1553 bmi->bmiHeader.biWidth = fb->width; 1554 bmi->bmiHeader.biCompression = Bpp == 16 ? BI_BITFIELDS : BI_RGB; 1555 1556 if (Bpp == 16) 1557 { 1558 DWORD* BitMasks = (DWORD*)(&bmi->bmiColors[0]); 1559 BitMasks[0] = 0x0000F800; 1560 BitMasks[1] = 0x000007E0; 1561 BitMasks[2] = 0x0000001F; 1562 } 1563 1564 return SetDIBitsToDevice(fb->Hdc, 0, 0, fb->width, fb->height, 0, 0, 0, fb->height, fb->BackBuffer, bmi, 1565 fb->pixel_format->iPixelType == PFD_TYPE_COLORINDEX ? DIB_PAL_COLORS : DIB_RGB_COLORS) != 0; 1566 } 1567