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 BYTE PACK_COLOR_8(GLubyte r, GLubyte g, GLubyte b) 620 { 621 return (r & 0x7) | ((g & 0x7) << 3) | ((b & 0x3) << 6); 622 } 623 624 static inline USHORT PACK_COLOR_16(GLubyte r, GLubyte g, GLubyte b) 625 { 626 return ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F); 627 } 628 629 static inline ULONG PACK_COLOR_24(GLubyte r, GLubyte g, GLubyte b) 630 { 631 return (r << 16) | (g << 8) | (b); 632 } 633 634 static inline ULONG PACK_COLOR_32(GLubyte r, GLubyte g, GLubyte b) 635 { 636 return (r << 16) | (g << 8) | (b); 637 } 638 639 static inline COLORREF PACK_COLORREF_8(GLubyte r, GLubyte g, GLubyte b) 640 { 641 return RGB(r << 5, g << 5, b << 6); 642 } 643 644 static inline COLORREF PACK_COLORREF_16(GLubyte r, GLubyte g, GLubyte b) 645 { 646 return RGB(r << 3, g << 2, b << 3); 647 } 648 649 static inline COLORREF PACK_COLORREF_24(GLubyte r, GLubyte g, GLubyte b) 650 { 651 return RGB(r, g, b); 652 } 653 654 static inline COLORREF PACK_COLORREF_32(GLubyte r, GLubyte g, GLubyte b) 655 { 656 return RGB(r, g, b); 657 } 658 659 static inline void UNPACK_COLOR_8(BYTE Color, GLubyte* r, GLubyte* g, GLubyte* b) 660 { 661 *r = Color & 0x7; 662 *g = (Color >> 3) & 0x7; 663 *b = (Color >> 6) & 0x3; 664 } 665 666 static inline void UNPACK_COLOR_16(USHORT Color, GLubyte* r, GLubyte* g, GLubyte* b) 667 { 668 *r = (Color >> 11) & 0x1F; 669 *g = (Color >> 5) & 0x3F; 670 *b = Color & 0x1F; 671 } 672 673 static inline void UNPACK_COLOR_24(ULONG Color, GLubyte* r, GLubyte* g, GLubyte* b) 674 { 675 *r = (Color >> 16) & 0xFF; 676 *g = (Color >> 8) & 0xFF; 677 *b = Color & 0xFF; 678 } 679 680 static inline void UNPACK_COLOR_32(ULONG Color, GLubyte* r, GLubyte* g, GLubyte* b) 681 { 682 *r = (Color >> 16) & 0xFF; 683 *g = (Color >> 8) & 0xFF; 684 *b = Color & 0xFF; 685 } 686 687 static inline void UNPACK_COLORREF_8(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 688 { 689 *r = GetRValue(Color) >> 5; 690 *g = GetGValue(Color) >> 5; 691 *b = GetBValue(Color) >> 6; 692 } 693 694 static inline void UNPACK_COLORREF_16(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 695 { 696 *r = GetRValue(Color) >> 3; 697 *g = GetGValue(Color) >> 2; 698 *b = GetBValue(Color) >> 3; 699 } 700 701 static inline void UNPACK_COLORREF_24(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 702 { 703 *r = GetRValue(Color); 704 *g = GetGValue(Color); 705 *b = GetBValue(Color); 706 } 707 708 static inline void UNPACK_COLORREF_32(COLORREF Color, GLubyte* r, GLubyte* g, GLubyte* b) 709 { 710 *r = GetRValue(Color); 711 *g = GetGValue(Color); 712 *b = GetBValue(Color); 713 } 714 715 #define MAKE_COLORREF(__bpp, __type) \ 716 static inline COLORREF MAKE_COLORREF_##__bpp(const struct pixel_format *format, __type Color) \ 717 { \ 718 GLubyte r,g,b; \ 719 \ 720 if (format->iPixelType == PFD_TYPE_COLORINDEX) \ 721 return PALETTEINDEX(Color); \ 722 \ 723 UNPACK_COLOR_##__bpp(Color, &r, &g, &b); \ 724 \ 725 return PACK_COLORREF_##__bpp(r, g, b); \ 726 } 727 MAKE_COLORREF(8, BYTE) 728 MAKE_COLORREF(16, USHORT) 729 MAKE_COLORREF(24, ULONG) 730 MAKE_COLORREF(32, ULONG) 731 #undef MAKE_COLORREF 732 733 /* 734 * Set the color index used to clear the color buffer. 735 */ 736 #define CLEAR_INDEX(__bpp, __type) \ 737 static void clear_index_##__bpp(GLcontext* ctx, GLuint index) \ 738 { \ 739 struct sw_context* sw_ctx = ctx->DriverCtx; \ 740 \ 741 sw_ctx->u##__bpp.ClearColor = (__type)index; \ 742 } 743 CLEAR_INDEX(8, BYTE) 744 CLEAR_INDEX(16, USHORT) 745 CLEAR_INDEX(24, ULONG) 746 CLEAR_INDEX(32, ULONG) 747 #undef CLEAR_INDEX 748 749 /* 750 * Set the color used to clear the color buffer. 751 */ 752 #define CLEAR_COLOR(__bpp) \ 753 static void clear_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) \ 754 { \ 755 struct sw_context* sw_ctx = ctx->DriverCtx; \ 756 \ 757 sw_ctx->u##__bpp.ClearColor = PACK_COLOR_##__bpp(r, g, b); \ 758 \ 759 TRACE("Set Clear color %u, %u, %u.\n", r, g, b); \ 760 } 761 CLEAR_COLOR(8) 762 CLEAR_COLOR(16) 763 CLEAR_COLOR(24) 764 CLEAR_COLOR(32) 765 #undef CLEAR_COLOR 766 767 /* 768 * Clear the specified region of the color buffer using the clear color 769 * or index as specified by one of the two functions above. 770 */ 771 static void clear_frontbuffer( 772 struct sw_context* sw_ctx, 773 struct sw_framebuffer* fb, 774 GLint x, 775 GLint y, 776 GLint width, 777 GLint height, 778 COLORREF ClearColor) 779 { 780 HBRUSH Brush; 781 BOOL ret; 782 783 TRACE("Clearing front buffer (%u, %u, %u, %u), color 0x%08x.\n", x, y, width, height, ClearColor); 784 785 Brush = CreateSolidBrush(ClearColor); 786 Brush = SelectObject(fb->Hdc, Brush); 787 788 ret = PatBlt(fb->Hdc, x, fb->height - (y + height), width, height, PATCOPY); 789 if (!ret) 790 { 791 ERR("PatBlt failed. last Error %d.\n", GetLastError()); 792 } 793 794 Brush = SelectObject(fb->Hdc, Brush); 795 DeleteObject(Brush); 796 } 797 798 #define CLEAR(__bpp, __type, __pixel_size) \ 799 static void clear_##__bpp(GLcontext* ctx, GLboolean all,GLint x, GLint y, GLint width, GLint height)\ 800 { \ 801 struct sw_context* sw_ctx = ctx->DriverCtx; \ 802 struct sw_framebuffer* fb = sw_ctx->fb; \ 803 BYTE* ScanLine; \ 804 \ 805 if (all) \ 806 { \ 807 x = y = 0; \ 808 width = fb->width; \ 809 height = fb->height; \ 810 } \ 811 \ 812 if (sw_ctx->Mode == GL_FRONT) \ 813 { \ 814 clear_frontbuffer(sw_ctx, fb, x, y, width, height, \ 815 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.ClearColor)); \ 816 return; \ 817 } \ 818 \ 819 ScanLine = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp); \ 820 while (height--) \ 821 { \ 822 BYTE* Buffer = ScanLine + x * __pixel_size; \ 823 UINT n = width; \ 824 \ 825 while (n--) \ 826 { \ 827 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.ClearColor); \ 828 Buffer += __pixel_size; \ 829 } \ 830 \ 831 ScanLine += WIDTH_BYTES_ALIGN32(fb->width, __bpp); \ 832 } \ 833 } 834 CLEAR(8, BYTE, 1) 835 CLEAR(16, USHORT, 2) 836 CLEAR(24, ULONG, 3) 837 CLEAR(32, ULONG, 4) 838 #undef CLEAR 839 840 /* Set the current color index. */ 841 #define SET_INDEX(__bpp) \ 842 static void set_index_##__bpp(GLcontext* ctx, GLuint index) \ 843 { \ 844 struct sw_context* sw_ctx = ctx->DriverCtx; \ 845 \ 846 sw_ctx->u##__bpp.CurrentColor = index; \ 847 } 848 SET_INDEX(8) 849 SET_INDEX(16) 850 SET_INDEX(24) 851 SET_INDEX(32) 852 #undef SET_INDEX 853 854 /* Set the current RGBA color. */ 855 #define SET_COLOR(__bpp) \ 856 static void set_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) \ 857 { \ 858 struct sw_context* sw_ctx = ctx->DriverCtx; \ 859 \ 860 sw_ctx->u##__bpp.CurrentColor = PACK_COLOR_##__bpp(r, g, b); \ 861 } 862 SET_COLOR(8) 863 SET_COLOR(16) 864 SET_COLOR(24) 865 SET_COLOR(32) 866 #undef SET_COLOR 867 868 /* 869 * Selects either the front or back color buffer for reading and writing. 870 * mode is either GL_FRONT or GL_BACK. 871 */ 872 static GLboolean set_buffer( GLcontext* ctx, GLenum mode ) 873 { 874 struct sw_context* sw_ctx = ctx->DriverCtx; 875 struct sw_framebuffer* fb = sw_ctx->fb; 876 877 if (!fb->gl_visual->DBflag) 878 return GL_FALSE; 879 880 if ((mode != GL_FRONT) && (mode != GL_BACK)) 881 return GL_FALSE; 882 883 sw_ctx->Mode = mode; 884 return GL_TRUE; 885 } 886 887 /* Return characteristics of the output buffer. */ 888 static void buffer_size(GLcontext* ctx, GLuint *width, GLuint *height) 889 { 890 struct sw_context* sw_ctx = ctx->DriverCtx; 891 struct sw_framebuffer* fb = sw_ctx->fb; 892 HWND Window = WindowFromDC(fb->Hdc); 893 894 if (Window) 895 { 896 RECT client_rect; 897 GetClientRect(Window, &client_rect); 898 *width = client_rect.right - client_rect.left; 899 *height = client_rect.bottom - client_rect.top; 900 } 901 else 902 { 903 /* We are drawing to a bitmap */ 904 BITMAP bm; 905 HBITMAP Hbm; 906 907 Hbm = GetCurrentObject(fb->Hdc, OBJ_BITMAP); 908 909 if (!GetObjectW(Hbm, sizeof(bm), &bm)) 910 return; 911 912 TRACE("Framebuffer size : %i, %i\n", bm.bmWidth, bm.bmHeight); 913 914 *width = bm.bmWidth; 915 *height = bm.bmHeight; 916 } 917 918 if ((*width != fb->width) || (*height != fb->height)) 919 { 920 const struct pixel_format* pixel_format = fb->pixel_format; 921 922 if (pixel_format->dwFlags & PFD_DOUBLEBUFFER) 923 { 924 /* Allocate a new backbuffer */ 925 size_t BufferSize = *height * WIDTH_BYTES_ALIGN32(*width, pixel_format->cColorBits); 926 if (!fb->BackBuffer) 927 { 928 fb->BackBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); 929 } 930 else 931 { 932 fb->BackBuffer = HeapReAlloc(GetProcessHeap(), 0, fb->BackBuffer, BufferSize); 933 } 934 if (!fb->BackBuffer) 935 { 936 ERR("Failed allocating back buffer !.\n"); 937 return; 938 } 939 } 940 941 fb->width = *width; 942 fb->height = *height; 943 } 944 } 945 946 /* Write a horizontal span of color pixels with a boolean mask. */ 947 #define WRITE_COLOR_SPAN_FRONTBUFFER(__bpp) \ 948 static void write_color_span_frontbuffer_##__bpp(struct sw_framebuffer* fb, \ 949 GLuint n, GLint x, GLint y, \ 950 const GLubyte red[], const GLubyte green[], \ 951 const GLubyte blue[], const GLubyte mask[] ) \ 952 { \ 953 TRACE("Writing color span at %u, %u (%u)\n", x, y, n); \ 954 \ 955 if (mask) \ 956 { \ 957 while (n--) \ 958 { \ 959 if (mask[n]) \ 960 { \ 961 SetPixel(fb->Hdc, x + n, fb->height - y, \ 962 PACK_COLORREF_##__bpp(red[n], green[n], blue[n])); \ 963 } \ 964 } \ 965 } \ 966 else \ 967 { \ 968 while (n--) \ 969 { \ 970 SetPixel(fb->Hdc, x + n, fb->height - y, \ 971 PACK_COLORREF_##__bpp(red[n], green[n], blue[n])); \ 972 } \ 973 } \ 974 } 975 WRITE_COLOR_SPAN_FRONTBUFFER(8) 976 WRITE_COLOR_SPAN_FRONTBUFFER(16) 977 WRITE_COLOR_SPAN_FRONTBUFFER(24) 978 WRITE_COLOR_SPAN_FRONTBUFFER(32) 979 #undef WRITE_COLOR_SPAN_FRONTBUFFER 980 981 #define WRITE_COLOR_SPAN(__bpp, __type, __pixel_size) \ 982 static void write_color_span_##__bpp(GLcontext* ctx, \ 983 GLuint n, GLint x, GLint y, \ 984 const GLubyte red[], const GLubyte green[], \ 985 const GLubyte blue[], const GLubyte alpha[], \ 986 const GLubyte mask[] ) \ 987 { \ 988 struct sw_context* sw_ctx = ctx->DriverCtx; \ 989 struct sw_framebuffer* fb = sw_ctx->fb; \ 990 BYTE* Buffer; \ 991 \ 992 if (sw_ctx->Mode == GL_FRONT) \ 993 { \ 994 write_color_span_frontbuffer_##__bpp(fb, n, x, y, red, green, blue, mask); \ 995 return; \ 996 } \ 997 \ 998 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 999 + (x + n) * __pixel_size; \ 1000 if (mask) \ 1001 { \ 1002 while (n--) \ 1003 { \ 1004 Buffer -= __pixel_size; \ 1005 if (mask[n]) \ 1006 { \ 1007 PUT_PIXEL_##__bpp((__type*)Buffer, \ 1008 PACK_COLOR_##__bpp(red[n], green[n], blue[n])); \ 1009 } \ 1010 } \ 1011 } \ 1012 else \ 1013 { \ 1014 while (n--) \ 1015 { \ 1016 Buffer -= __pixel_size; \ 1017 PUT_PIXEL_##__bpp((__type*)Buffer, \ 1018 PACK_COLOR_##__bpp(red[n], green[n], blue[n])); \ 1019 } \ 1020 } \ 1021 } 1022 WRITE_COLOR_SPAN(8, BYTE, 1) 1023 WRITE_COLOR_SPAN(16, USHORT, 2) 1024 WRITE_COLOR_SPAN(24, ULONG, 3) 1025 WRITE_COLOR_SPAN(32, ULONG, 4) 1026 #undef WRITE_COLOR_SPAN 1027 1028 static void write_monocolor_span_frontbuffer(struct sw_framebuffer* fb, GLuint n, GLint x, GLint y, 1029 const GLubyte mask[], COLORREF Color) 1030 { 1031 TRACE("Writing monocolor span at %u %u (%u), Color 0x%08x\n", x, y, n, Color); 1032 1033 if (mask) 1034 { 1035 while (n--) 1036 { 1037 if (mask[n]) 1038 SetPixel(fb->Hdc, x + n, y, Color); 1039 } 1040 } 1041 else 1042 { 1043 HBRUSH Brush = CreateSolidBrush(Color); 1044 Brush = SelectObject(fb->Hdc, Brush); 1045 1046 PatBlt(fb->Hdc, x, fb->height - y, n, 1, PATCOPY); 1047 1048 Brush = SelectObject(fb->Hdc, Brush); 1049 DeleteObject(Brush); 1050 } 1051 } 1052 1053 #define WRITE_MONOCOLOR_SPAN(__bpp, __type, __pixel_size) \ 1054 static void write_monocolor_span_##__bpp(GLcontext* ctx, \ 1055 GLuint n, GLint x, GLint y, \ 1056 const GLubyte mask[]) \ 1057 { \ 1058 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1059 struct sw_framebuffer* fb = sw_ctx->fb; \ 1060 BYTE* Buffer; \ 1061 \ 1062 if (sw_ctx->Mode == GL_FRONT) \ 1063 { \ 1064 write_monocolor_span_frontbuffer(fb, n, x, y, mask, \ 1065 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor)); \ 1066 return; \ 1067 } \ 1068 \ 1069 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) + (x + n) * __pixel_size; \ 1070 if (mask) \ 1071 { \ 1072 while (n--) \ 1073 { \ 1074 Buffer -= __pixel_size; \ 1075 if (mask[n]) \ 1076 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \ 1077 } \ 1078 } \ 1079 else \ 1080 { \ 1081 while(n--) \ 1082 { \ 1083 Buffer -= __pixel_size; \ 1084 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \ 1085 } \ 1086 } \ 1087 } 1088 WRITE_MONOCOLOR_SPAN(8, BYTE, 1) 1089 WRITE_MONOCOLOR_SPAN(16, USHORT, 2) 1090 WRITE_MONOCOLOR_SPAN(24, ULONG, 3) 1091 WRITE_MONOCOLOR_SPAN(32, ULONG, 4) 1092 #undef WRITE_MONOCOLOR_SPAN 1093 1094 /* Write an array of pixels with a boolean mask. */ 1095 #define WRITE_COLOR_PIXELS(__bpp, __type, __pixel_size) \ 1096 static void write_color_pixels_##__bpp(GLcontext* ctx, \ 1097 GLuint n, const GLint x[], const GLint y[], \ 1098 const GLubyte r[], const GLubyte g[], \ 1099 const GLubyte b[], const GLubyte a[], \ 1100 const GLubyte mask[]) \ 1101 { \ 1102 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1103 struct sw_framebuffer* fb = sw_ctx->fb; \ 1104 \ 1105 TRACE("Writing color pixels\n"); \ 1106 \ 1107 if (sw_ctx->Mode == GL_FRONT) \ 1108 { \ 1109 while (n--) \ 1110 { \ 1111 if (mask[n]) \ 1112 { \ 1113 TRACE("Setting pixel %u, %u to 0x%08x.\n", x[n], fb->height - y[n], \ 1114 PACK_COLORREF_##__bpp(r[n], g[n], b[n])); \ 1115 SetPixel(fb->Hdc, x[n], fb->height - y[n], \ 1116 PACK_COLORREF_##__bpp(r[n], g[n], b[n])); \ 1117 } \ 1118 } \ 1119 \ 1120 return; \ 1121 } \ 1122 \ 1123 while (n--) \ 1124 { \ 1125 if (mask[n]) \ 1126 { \ 1127 BYTE* Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1128 + x[n] * __pixel_size; \ 1129 PUT_PIXEL_##__bpp((__type*)Buffer, PACK_COLOR_##__bpp(r[n], g[n], b[n])); \ 1130 } \ 1131 } \ 1132 } 1133 WRITE_COLOR_PIXELS(8, BYTE, 1) 1134 WRITE_COLOR_PIXELS(16, USHORT, 2) 1135 WRITE_COLOR_PIXELS(24, ULONG, 3) 1136 WRITE_COLOR_PIXELS(32, ULONG, 4) 1137 #undef WRITE_COLOR_PIXELS 1138 1139 static void write_monocolor_pixels_frontbuffer( 1140 struct sw_framebuffer* fb, GLuint n, 1141 const GLint x[], const GLint y[], 1142 const GLubyte mask[], COLORREF Color) 1143 { 1144 TRACE("Writing monocolor pixels to front buffer.\n"); 1145 1146 while (n--) 1147 { 1148 if (mask[n]) 1149 { 1150 SetPixel(fb->Hdc, x[n], fb->height - y[n], Color); 1151 } 1152 } 1153 } 1154 1155 /* 1156 * Write an array of pixels with a boolean mask. The current color 1157 * is used for all pixels. 1158 */ 1159 #define WRITE_MONOCOLOR_PIXELS(__bpp, __type, __pixel_size) \ 1160 static void write_monocolor_pixels_##__bpp(GLcontext* ctx, GLuint n, \ 1161 const GLint x[], const GLint y[], \ 1162 const GLubyte mask[] ) \ 1163 { \ 1164 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1165 struct sw_framebuffer* fb = sw_ctx->fb; \ 1166 \ 1167 if (sw_ctx->Mode == GL_FRONT) \ 1168 { \ 1169 write_monocolor_pixels_frontbuffer(fb, n, x, y, mask, \ 1170 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor)); \ 1171 \ 1172 return; \ 1173 } \ 1174 \ 1175 while (n--) \ 1176 { \ 1177 if (mask[n]) \ 1178 { \ 1179 BYTE* Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, 32) \ 1180 + x[n] * __pixel_size; \ 1181 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \ 1182 } \ 1183 } \ 1184 } 1185 WRITE_MONOCOLOR_PIXELS(8, BYTE, 1) 1186 WRITE_MONOCOLOR_PIXELS(16, USHORT, 2) 1187 WRITE_MONOCOLOR_PIXELS(24, ULONG, 3) 1188 WRITE_MONOCOLOR_PIXELS(32, ULONG, 4) 1189 #undef WRITE_MONOCOLOR_PIXELS 1190 1191 /* Write a horizontal span of color pixels with a boolean mask. */ 1192 static void write_index_span( GLcontext* ctx, 1193 GLuint n, GLint x, GLint y, 1194 const GLuint index[], 1195 const GLubyte mask[] ) 1196 { 1197 ERR("Not implemented yet !\n"); 1198 } 1199 1200 /* Write an array of pixels with a boolean mask. */ 1201 static void write_index_pixels( GLcontext* ctx, 1202 GLuint n, const GLint x[], const GLint y[], 1203 const GLuint index[], const GLubyte mask[] ) 1204 { 1205 ERR("Not implemented yet !\n"); 1206 } 1207 1208 /* Read a horizontal span of color-index pixels. */ 1209 static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[]) 1210 { 1211 ERR("Not implemented yet !\n"); 1212 } 1213 1214 /* Read a horizontal span of color pixels. */ 1215 #define READ_COLOR_SPAN(__bpp, __type, __pixel_size) \ 1216 static void read_color_span_##__bpp(GLcontext* ctx, \ 1217 GLuint n, GLint x, GLint y, \ 1218 GLubyte red[], GLubyte green[], \ 1219 GLubyte blue[], GLubyte alpha[] ) \ 1220 { \ 1221 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1222 struct sw_framebuffer* fb = sw_ctx->fb; \ 1223 BYTE* Buffer; \ 1224 \ 1225 if (sw_ctx->Mode == GL_FRONT) \ 1226 { \ 1227 COLORREF Color; \ 1228 while (n--) \ 1229 { \ 1230 Color = GetPixel(fb->Hdc, x + n, fb->height - y); \ 1231 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]); \ 1232 alpha[n] = 0; \ 1233 } \ 1234 \ 1235 return; \ 1236 } \ 1237 \ 1238 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1239 + (x + n) * __pixel_size; \ 1240 while (n--) \ 1241 { \ 1242 Buffer -= __pixel_size; \ 1243 UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer), \ 1244 &red[n], &green[n], &blue[n]); \ 1245 alpha[n] = 0; \ 1246 } \ 1247 } 1248 READ_COLOR_SPAN(8, BYTE, 1) 1249 READ_COLOR_SPAN(16, USHORT, 2) 1250 READ_COLOR_SPAN(24, ULONG, 3) 1251 READ_COLOR_SPAN(32, ULONG, 4) 1252 #undef READ_COLOR_SPAN 1253 1254 /* Read an array of color index pixels. */ 1255 static void read_index_pixels(GLcontext* ctx, 1256 GLuint n, const GLint x[], const GLint y[], 1257 GLuint index[], const GLubyte mask[]) 1258 { 1259 1260 ERR("Not implemented yet !\n"); 1261 } 1262 1263 /* Read an array of color pixels. */ 1264 #define READ_COLOR_PIXELS(__bpp, __type, __pixel_size) \ 1265 static void read_color_pixels_##__bpp(GLcontext* ctx, \ 1266 GLuint n, const GLint x[], const GLint y[], \ 1267 GLubyte red[], GLubyte green[], \ 1268 GLubyte blue[], GLubyte alpha[], \ 1269 const GLubyte mask[] ) \ 1270 { \ 1271 struct sw_context* sw_ctx = ctx->DriverCtx; \ 1272 struct sw_framebuffer* fb = sw_ctx->fb; \ 1273 \ 1274 if (sw_ctx->Mode == GL_FRONT) \ 1275 { \ 1276 COLORREF Color; \ 1277 while (n--) \ 1278 { \ 1279 if (mask[n]) \ 1280 { \ 1281 Color = GetPixel(fb->Hdc, x[n], fb->height - y[n]); \ 1282 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]); \ 1283 alpha[n] = 0; \ 1284 } \ 1285 } \ 1286 \ 1287 return; \ 1288 } \ 1289 \ 1290 while (n--) \ 1291 { \ 1292 if (mask[n]) \ 1293 { \ 1294 BYTE *Buffer = fb->BackBuffer + y[n] * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \ 1295 + x[n] * __pixel_size; \ 1296 UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer), \ 1297 &red[n], &green[n], &blue[n]); \ 1298 alpha[n] = 0; \ 1299 } \ 1300 } \ 1301 } 1302 READ_COLOR_PIXELS(8, BYTE, 1) 1303 READ_COLOR_PIXELS(16, USHORT, 2) 1304 READ_COLOR_PIXELS(24, ULONG, 3) 1305 READ_COLOR_PIXELS(32, ULONG, 4) 1306 #undef READ_COLOR_PIXELS 1307 1308 static void setup_DD_pointers( GLcontext* ctx ) 1309 { 1310 struct sw_context* sw_ctx = ctx->DriverCtx; 1311 1312 ctx->Driver.RendererString = renderer_string; 1313 ctx->Driver.UpdateState = setup_DD_pointers; 1314 1315 switch (sw_ctx->fb->pixel_format->cColorBits) 1316 { 1317 #define HANDLE_BPP(__bpp) \ 1318 case __bpp: \ 1319 ctx->Driver.ClearIndex = clear_index_##__bpp; \ 1320 ctx->Driver.ClearColor = clear_color_##__bpp; \ 1321 ctx->Driver.Clear = clear_##__bpp; \ 1322 ctx->Driver.Index = set_index_##__bpp; \ 1323 ctx->Driver.Color = set_color_##__bpp; \ 1324 ctx->Driver.WriteColorSpan = write_color_span_##__bpp; \ 1325 ctx->Driver.WriteMonocolorSpan = write_monocolor_span_##__bpp; \ 1326 ctx->Driver.WriteMonoindexSpan = write_monocolor_span_##__bpp; \ 1327 ctx->Driver.WriteColorPixels = write_color_pixels_##__bpp; \ 1328 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels_##__bpp; \ 1329 ctx->Driver.WriteMonoindexPixels = write_monocolor_pixels_##__bpp; \ 1330 ctx->Driver.ReadColorSpan = read_color_span_##__bpp; \ 1331 ctx->Driver.ReadColorPixels = read_color_pixels_##__bpp; \ 1332 break 1333 HANDLE_BPP(8); 1334 HANDLE_BPP(16); 1335 HANDLE_BPP(24); 1336 HANDLE_BPP(32); 1337 #undef HANDLE_BPP 1338 default: 1339 ERR("Unhandled bit depth %u, defaulting to 32bpp.\n", sw_ctx->fb->pixel_format->cColorBits); 1340 ctx->Driver.ClearIndex = clear_index_32; 1341 ctx->Driver.ClearColor = clear_color_32; 1342 ctx->Driver.Clear = clear_32; 1343 ctx->Driver.Index = set_index_32; 1344 ctx->Driver.Color = set_color_32; 1345 ctx->Driver.WriteColorSpan = write_color_span_32; 1346 ctx->Driver.WriteMonocolorSpan = write_monocolor_span_32; 1347 ctx->Driver.WriteMonoindexSpan = write_monocolor_span_32; 1348 ctx->Driver.WriteColorPixels = write_color_pixels_32; 1349 ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels_32; 1350 ctx->Driver.WriteMonoindexPixels = write_monocolor_pixels_32; 1351 ctx->Driver.ReadColorSpan = read_color_span_32; 1352 ctx->Driver.ReadColorPixels = read_color_pixels_32; 1353 break; 1354 } 1355 1356 ctx->Driver.SetBuffer = set_buffer; 1357 ctx->Driver.GetBufferSize = buffer_size; 1358 1359 /* Pixel/span writing functions: */ 1360 ctx->Driver.WriteIndexSpan = write_index_span; 1361 ctx->Driver.WriteIndexPixels = write_index_pixels; 1362 1363 /* Pixel/span reading functions: */ 1364 ctx->Driver.ReadIndexSpan = read_index_span; 1365 ctx->Driver.ReadIndexPixels = read_index_pixels; 1366 } 1367 1368 /* Declare API table */ 1369 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) extern void WINAPI _mesa_##name proto_args ; 1370 #define USE_GL_FUNC_RET(name, ret_type, proto_args, call_args, offset, stack) extern ret_type WINAPI _mesa_##name proto_args ; 1371 #include "glfuncs.h" 1372 1373 static GLCLTPROCTABLE sw_api_table = 1374 { 1375 OPENGL_VERSION_110_ENTRIES, 1376 { 1377 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) _mesa_##name, 1378 #include "glfuncs.h" 1379 } 1380 }; 1381 1382 /* Glue code */ 1383 GLcontext* gl_get_thread_context(void) 1384 { 1385 struct sw_context* sw_ctx = (struct sw_context*)IntGetCurrentDHGLRC(); 1386 return sw_ctx->gl_ctx; 1387 } 1388 1389 1390 BOOL sw_SetContext(struct wgl_dc_data* dc_data, DHGLRC dhglrc) 1391 { 1392 struct sw_context* sw_ctx = (struct sw_context*)dhglrc; 1393 struct sw_framebuffer* fb = dc_data->sw_data; 1394 UINT width, height; 1395 1396 /* Get framebuffer size */ 1397 if(dc_data->flags & WGL_DC_OBJ_DC) 1398 { 1399 HWND hwnd = dc_data->owner.hwnd; 1400 RECT client_rect; 1401 if(!hwnd) 1402 { 1403 ERR("Physical DC without a window!\n"); 1404 return FALSE; 1405 } 1406 if(!GetClientRect(hwnd, &client_rect)) 1407 { 1408 ERR("GetClientRect failed!\n"); 1409 return FALSE; 1410 } 1411 1412 /* This is a physical DC. Setup the hook */ 1413 sw_ctx->hook = SetWindowsHookEx(WH_CALLWNDPROC, 1414 sw_call_window_proc, 1415 NULL, 1416 GetCurrentThreadId()); 1417 1418 /* Calculate width & height */ 1419 width = client_rect.right - client_rect.left; 1420 height = client_rect.bottom - client_rect.top; 1421 } 1422 else /* OBJ_MEMDC */ 1423 { 1424 BITMAP bm; 1425 HBITMAP hbmp; 1426 HDC hdc = dc_data->owner.hdc; 1427 1428 if(fb->gl_visual->DBflag) 1429 { 1430 ERR("Memory DC called with a double buffered format.\n"); 1431 return FALSE; 1432 } 1433 1434 hbmp = GetCurrentObject( hdc, OBJ_BITMAP ); 1435 if(!hbmp) 1436 { 1437 ERR("No Bitmap!\n"); 1438 return FALSE; 1439 } 1440 if(GetObject(hbmp, sizeof(bm), &bm) == 0) 1441 { 1442 ERR("GetObject failed!\n"); 1443 return FALSE; 1444 } 1445 width = bm.bmWidth; 1446 height = bm.bmHeight; 1447 } 1448 1449 if(!width) width = 1; 1450 if(!height) height = 1; 1451 1452 /* Also make the mesa context current to mesa */ 1453 gl_make_current(sw_ctx->gl_ctx, fb->gl_buffer); 1454 1455 /* Setup our functions */ 1456 setup_DD_pointers(sw_ctx->gl_ctx); 1457 1458 /* Set the viewport if this is the first time we initialize this context */ 1459 if(sw_ctx->gl_ctx->Viewport.X == 0 && 1460 sw_ctx->gl_ctx->Viewport.Y == 0 && 1461 sw_ctx->gl_ctx->Viewport.Width == 0 && 1462 sw_ctx->gl_ctx->Viewport.Height == 0) 1463 { 1464 gl_Viewport(sw_ctx->gl_ctx, 0, 0, width, height); 1465 } 1466 1467 /* update the framebuffer size */ 1468 gl_ResizeBuffersMESA(sw_ctx->gl_ctx); 1469 1470 /* Use our API table */ 1471 IntSetCurrentDispatchTable(&sw_api_table.glDispatchTable); 1472 1473 /* We're good */ 1474 return TRUE; 1475 } 1476 1477 void sw_ReleaseContext(DHGLRC dhglrc) 1478 { 1479 struct sw_context* sw_ctx = (struct sw_context*)dhglrc; 1480 1481 /* Forward to mesa */ 1482 gl_make_current(NULL, NULL); 1483 1484 /* Unhook */ 1485 if(sw_ctx->hook) 1486 { 1487 UnhookWindowsHookEx(sw_ctx->hook); 1488 sw_ctx->hook = NULL; 1489 } 1490 } 1491 1492 BOOL sw_SwapBuffers(HDC hdc, struct wgl_dc_data* dc_data) 1493 { 1494 struct sw_framebuffer* fb = dc_data->sw_data; 1495 char Buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD)]; 1496 BITMAPINFO *bmi = (BITMAPINFO*)Buffer; 1497 BYTE Bpp = fb->pixel_format->cColorBits; 1498 1499 if (!fb->gl_visual->DBflag) 1500 return TRUE; 1501 1502 if (!fb->BackBuffer) 1503 return FALSE; 1504 1505 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader); 1506 bmi->bmiHeader.biBitCount = Bpp; 1507 bmi->bmiHeader.biClrImportant = 0; 1508 bmi->bmiHeader.biClrUsed = 0; 1509 bmi->bmiHeader.biPlanes = 1; 1510 bmi->bmiHeader.biSizeImage = WIDTH_BYTES_ALIGN32(fb->width, Bpp) * fb->height; 1511 bmi->bmiHeader.biXPelsPerMeter = 0; 1512 bmi->bmiHeader.biYPelsPerMeter = 0; 1513 bmi->bmiHeader.biHeight = fb->height; 1514 bmi->bmiHeader.biWidth = fb->width; 1515 bmi->bmiHeader.biCompression = Bpp == 16 ? BI_BITFIELDS : BI_RGB; 1516 1517 if (Bpp == 16) 1518 { 1519 DWORD* BitMasks = (DWORD*)(&bmi->bmiColors[0]); 1520 BitMasks[0] = 0x0000F800; 1521 BitMasks[1] = 0x000007E0; 1522 BitMasks[2] = 0x0000001F; 1523 } 1524 1525 return SetDIBitsToDevice(fb->Hdc, 0, 0, fb->width, fb->height, 0, 0, 0, fb->height, fb->BackBuffer, bmi, 1526 fb->pixel_format->iPixelType == PFD_TYPE_COLORINDEX ? DIB_PAL_COLORS : DIB_RGB_COLORS) != 0; 1527 } 1528