2 * COPYRIGHT: See COPYING in the top level directory
4 * FILE: dll/opengl/opengl32/swimpl.c
5 * PURPOSE: OpenGL32 DLL, opengl software implementation
14 WINE_DEFAULT_DEBUG_CHANNEL(opengl32
);
16 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
17 #define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3)
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)
32 BYTE cRedBits
; BYTE cRedShift
;
33 BYTE cGreenBits
; BYTE cGreenShift
;
34 BYTE cBlueBits
; BYTE cBlueShift
;
35 BYTE cAlphaBits
; BYTE cAlphaShift
;
37 BYTE cAccumRedBits
; BYTE cAccumGreenBits
; BYTE cAccumBlueBits
; BYTE cAccumAlphaBits
;
41 static const struct pixel_format pixel_formats_32
[] =
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},
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},
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},
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},
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},
86 static const struct pixel_format pixel_formats_24
[] =
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},
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},
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},
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},
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},
131 static const struct pixel_format pixel_formats_16
[] =
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},
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},
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},
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},
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},
176 static const struct pixel_format pixel_formats_8
[] =
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},
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},
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},
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},
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},
221 struct sw_framebuffer
223 GLvisual
*gl_visual
; /* Describes the buffers */
224 GLframebuffer
*gl_buffer
; /* Depth, stencil, accum, etc buffers */
226 const struct pixel_format
* pixel_format
;
229 /* Current width/height */
230 GLuint width
; GLuint height
;
232 /* BackBuffer, if any */
238 GLcontext
*gl_ctx
; /* The core GL/Mesa context */
240 /* This is to keep track of the size of the front buffer */
243 /* Our frame buffer*/
244 struct sw_framebuffer
* fb
;
246 /* State variables */
273 /* WGL <-> mesa glue */
274 static const struct pixel_format
* get_format(INT pf_index
, INT
* pf_count
)
278 const struct pixel_format
* ret
;
281 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
282 ReleaseDC(NULL
, hdc
);
286 #define HANDLE_BPP(__x__) \
288 nb_format = ARRAYSIZE(pixel_formats_##__x__); \
289 if ((pf_index > nb_format) || (pf_index <= 0)) \
292 ret = &pixel_formats_##__x__[pf_index - 1]; \
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))
306 ret
= &pixel_formats_32
[pf_index
- 1];
310 *pf_count
= nb_format
;
315 INT
sw_DescribePixelFormat(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
* descr
)
318 const struct pixel_format
*pixel_format
;
320 TRACE("Describing format %i.\n", format
);
322 pixel_format
= get_format(format
, &ret
);
325 if((format
> ret
) || (size
!= sizeof(*descr
)))
328 /* Fill the structure */
329 descr
->nSize
= sizeof(*descr
);
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;
359 BOOL
sw_SetPixelFormat(HDC hdc
, struct wgl_dc_data
* dc_data
, INT format
)
361 struct sw_framebuffer
* fb
;
362 const struct pixel_format
*pixel_format
;
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
);
367 pixel_format
= get_format(format
, NULL
);
371 /* allocate our structure */
372 fb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*fb
));
375 ERR("HeapAlloc FAILED!\n");
379 fb
->pixel_format
= pixel_format
;
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
,
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
);
400 ERR("Failed to allocate a GL visual.\n");
401 HeapFree(GetProcessHeap(), 0, fb
);
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
);
417 /* Everything went fine */
418 dc_data
->sw_data
= fb
;
422 DHGLRC
sw_CreateContext(struct wgl_dc_data
* dc_data
)
424 struct sw_context
* sw_ctx
;
425 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
427 sw_ctx
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*sw_ctx
));
431 /* Initialize the context */
432 sw_ctx
->gl_ctx
= gl_create_context(fb
->gl_visual
, NULL
, sw_ctx
);
435 ERR("Failed to initialize the mesa context.\n");
436 HeapFree(GetProcessHeap(), 0, sw_ctx
);
442 /* Choose relevant default */
443 sw_ctx
->Mode
= fb
->gl_visual
->DBflag
? GL_BACK
: GL_FRONT
;
445 return (DHGLRC
)sw_ctx
;
448 BOOL
sw_DeleteContext(DHGLRC dhglrc
)
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();
455 /* Destroy everything */
456 gl_destroy_context(sw_ctx
->gl_ctx
);
458 HeapFree(GetProcessHeap(), 0, sw_ctx
);
461 IntSetCurrentDispatchTable(table_save
);
462 IntSetCurrentICDPrivate(icd_save
);
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
*);
473 static void APIENTRY
_swimpl_AddSwapHintRectWIN(GLint x
, GLint y
, GLsizei width
, GLsizei height
)
478 PROC
sw_GetProcAddress(LPCSTR name
)
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
;
494 WARN("Asking for proc address %s, returning NULL.\n", name
);
498 BOOL
sw_CopyContext(DHGLRC dhglrcSrc
, DHGLRC dhglrcDst
, UINT mask
)
500 FIXME("Software wglCopyContext is UNIMPLEMENTED, mask %lx.\n", mask
);
504 BOOL
sw_ShareLists(DHGLRC dhglrcSrc
, DHGLRC dhglrcDst
)
507 struct sw_context
* sw_ctx_src
= (struct sw_context
*)dhglrcSrc
;
508 struct sw_context
* sw_ctx_dst
= (struct sw_context
*)dhglrcDst
;
510 /* See if it was already shared */
511 if(sw_ctx_dst
->gl_ctx
->Shared
->RefCount
> 1)
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
);
519 FIXME("Unimplemented!\n");
530 struct wgl_dc_data
* dc_data
= IntGetCurrentDcData();
531 struct sw_context
* ctx
= (struct sw_context
*)IntGetCurrentDHGLRC();
532 PCWPSTRUCT pParams
= (PCWPSTRUCT
)lParam
;
534 if((!dc_data
) || (!ctx
))
537 if(!(dc_data
->flags
& WGL_DC_OBJ_DC
))
540 if((nCode
< 0) || (dc_data
->owner
.hwnd
!= pParams
->hwnd
) || (dc_data
->sw_data
== NULL
))
541 return CallNextHookEx(ctx
->hook
, nCode
, wParam
, lParam
);
543 if (pParams
->message
== WM_WINDOWPOSCHANGED
)
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
))
554 /* Size in WINDOWPOS includes the window frame, so get the size
555 * of the client area via GetClientRect. */
559 TRACE("Got WM_WINDOWPOSCHANGED\n");
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)
567 /* Propagate to mesa */
568 gl_ResizeBuffersMESA(ctx
->gl_ctx
);
573 return CallNextHookEx(ctx
->hook
, nCode
, wParam
, lParam
);
576 static const char* renderer_string(void)
578 return "ReactOS SW Implementation";
581 static inline void PUT_PIXEL_8(BYTE
* Buffer
, BYTE Value
)
585 static inline void PUT_PIXEL_16(USHORT
* Buffer
, USHORT Value
)
589 static inline void PUT_PIXEL_24(ULONG
* Buffer
, ULONG Value
)
591 *Buffer
&= 0xFF000000ul
;
592 *Buffer
|= Value
& 0x00FFFFFF;
594 static inline void PUT_PIXEL_32(ULONG
* Buffer
, ULONG Value
)
599 static inline BYTE
GET_PIXEL_8(BYTE
* Buffer
)
604 static inline USHORT
GET_PIXEL_16(USHORT
* Buffer
)
609 static inline ULONG
GET_PIXEL_24(ULONG
* Buffer
)
611 return *Buffer
& 0x00FFFFFF;
614 static inline ULONG
GET_PIXEL_32(ULONG
* Buffer
)
619 static inline BYTE
PACK_COLOR_8(GLubyte r
, GLubyte g
, GLubyte b
)
621 return (r
& 0x7) | ((g
& 0x7) << 3) | ((b
& 0x3) << 6);
624 static inline USHORT
PACK_COLOR_16(GLubyte r
, GLubyte g
, GLubyte b
)
626 return ((r
& 0x1F) << 11) | ((g
& 0x3F) << 5) | (b
& 0x1F);
629 static inline ULONG
PACK_COLOR_24(GLubyte r
, GLubyte g
, GLubyte b
)
631 return (r
<< 16) | (g
<< 8) | (b
);
634 static inline ULONG
PACK_COLOR_32(GLubyte r
, GLubyte g
, GLubyte b
)
636 return (r
<< 16) | (g
<< 8) | (b
);
639 static inline COLORREF
PACK_COLORREF_8(GLubyte r
, GLubyte g
, GLubyte b
)
641 return RGB(r
<< 5, g
<< 5, b
<< 6);
644 static inline COLORREF
PACK_COLORREF_16(GLubyte r
, GLubyte g
, GLubyte b
)
646 return RGB(r
<< 3, g
<< 2, b
<< 3);
649 static inline COLORREF
PACK_COLORREF_24(GLubyte r
, GLubyte g
, GLubyte b
)
654 static inline COLORREF
PACK_COLORREF_32(GLubyte r
, GLubyte g
, GLubyte b
)
659 static inline void UNPACK_COLOR_8(BYTE Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
662 *g
= (Color
>> 3) & 0x7;
663 *b
= (Color
>> 6) & 0x3;
666 static inline void UNPACK_COLOR_16(USHORT Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
668 *r
= (Color
>> 11) & 0x1F;
669 *g
= (Color
>> 5) & 0x3F;
673 static inline void UNPACK_COLOR_24(ULONG Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
675 *r
= (Color
>> 16) & 0xFF;
676 *g
= (Color
>> 8) & 0xFF;
680 static inline void UNPACK_COLOR_32(ULONG Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
682 *r
= (Color
>> 16) & 0xFF;
683 *g
= (Color
>> 8) & 0xFF;
687 static inline void UNPACK_COLORREF_8(COLORREF Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
689 *r
= GetRValue(Color
) >> 5;
690 *g
= GetGValue(Color
) >> 5;
691 *b
= GetBValue(Color
) >> 6;
694 static inline void UNPACK_COLORREF_16(COLORREF Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
696 *r
= GetRValue(Color
) >> 3;
697 *g
= GetGValue(Color
) >> 2;
698 *b
= GetBValue(Color
) >> 3;
701 static inline void UNPACK_COLORREF_24(COLORREF Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
703 *r
= GetRValue(Color
);
704 *g
= GetGValue(Color
);
705 *b
= GetBValue(Color
);
708 static inline void UNPACK_COLORREF_32(COLORREF Color
, GLubyte
* r
, GLubyte
* g
, GLubyte
* b
)
710 *r
= GetRValue(Color
);
711 *g
= GetGValue(Color
);
712 *b
= GetBValue(Color
);
715 #define MAKE_COLORREF(__bpp, __type) \
716 static inline COLORREF MAKE_COLORREF_##__bpp(const struct pixel_format *format, __type Color) \
720 if (format->iPixelType == PFD_TYPE_COLORINDEX) \
721 return PALETTEINDEX(Color); \
723 UNPACK_COLOR_##__bpp(Color, &r, &g, &b); \
725 return PACK_COLORREF_##__bpp(r, g, b); \
727 MAKE_COLORREF(8, BYTE
)
728 MAKE_COLORREF(16, USHORT
)
729 MAKE_COLORREF(24, ULONG
)
730 MAKE_COLORREF(32, ULONG
)
734 * Set the color index used to clear the color buffer.
736 #define CLEAR_INDEX(__bpp, __type) \
737 static void clear_index_##__bpp(GLcontext* ctx, GLuint index) \
739 struct sw_context* sw_ctx = ctx->DriverCtx; \
741 sw_ctx->u##__bpp.ClearColor = (__type)index; \
744 CLEAR_INDEX(16, USHORT
)
745 CLEAR_INDEX(24, ULONG
)
746 CLEAR_INDEX(32, ULONG
)
750 * Set the color used to clear the color buffer.
752 #define CLEAR_COLOR(__bpp) \
753 static void clear_color_##__bpp( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) \
755 struct sw_context* sw_ctx = ctx->DriverCtx; \
757 sw_ctx->u##__bpp.ClearColor = PACK_COLOR_##__bpp(r, g, b); \
759 TRACE("Set Clear color %u, %u, %u.\n", r, g, b); \
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.
771 static void clear_frontbuffer(
772 struct sw_context
* sw_ctx
,
773 struct sw_framebuffer
* fb
,
783 TRACE("Clearing front buffer (%u, %u, %u, %u), color 0x%08x.\n", x
, y
, width
, height
, ClearColor
);
785 Brush
= CreateSolidBrush(ClearColor
);
786 Brush
= SelectObject(fb
->Hdc
, Brush
);
788 ret
= PatBlt(fb
->Hdc
, x
, fb
->height
- (y
+ height
), width
, height
, PATCOPY
);
791 ERR("PatBlt failed. last Error %d.\n", GetLastError());
794 Brush
= SelectObject(fb
->Hdc
, Brush
);
798 #define CLEAR(__bpp, __type, __pixel_size) \
799 static void clear_##__bpp(GLcontext* ctx, GLboolean all,GLint x, GLint y, GLint width, GLint height)\
801 struct sw_context* sw_ctx = ctx->DriverCtx; \
802 struct sw_framebuffer* fb = sw_ctx->fb; \
809 height = fb->height; \
812 if (sw_ctx->Mode == GL_FRONT) \
814 clear_frontbuffer(sw_ctx, fb, x, y, width, height, \
815 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.ClearColor)); \
819 ScanLine = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp); \
822 BYTE* Buffer = ScanLine + x * __pixel_size; \
827 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.ClearColor); \
828 Buffer += __pixel_size; \
831 ScanLine += WIDTH_BYTES_ALIGN32(fb->width, __bpp); \
840 /* Set the current color index. */
841 #define SET_INDEX(__bpp) \
842 static void set_index_##__bpp(GLcontext* ctx, GLuint index) \
844 struct sw_context* sw_ctx = ctx->DriverCtx; \
846 sw_ctx->u##__bpp.CurrentColor = index; \
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 ) \
858 struct sw_context* sw_ctx = ctx->DriverCtx; \
860 sw_ctx->u##__bpp.CurrentColor = PACK_COLOR_##__bpp(r, g, b); \
869 * Selects either the front or back color buffer for reading and writing.
870 * mode is either GL_FRONT or GL_BACK.
872 static GLboolean
set_buffer( GLcontext
* ctx
, GLenum mode
)
874 struct sw_context
* sw_ctx
= ctx
->DriverCtx
;
875 struct sw_framebuffer
* fb
= sw_ctx
->fb
;
877 if (!fb
->gl_visual
->DBflag
)
880 if ((mode
!= GL_FRONT
) && (mode
!= GL_BACK
))
887 /* Return characteristics of the output buffer. */
888 static void buffer_size(GLcontext
* ctx
, GLuint
*width
, GLuint
*height
)
890 struct sw_context
* sw_ctx
= ctx
->DriverCtx
;
891 struct sw_framebuffer
* fb
= sw_ctx
->fb
;
892 HWND Window
= WindowFromDC(fb
->Hdc
);
897 GetClientRect(Window
, &client_rect
);
898 *width
= client_rect
.right
- client_rect
.left
;
899 *height
= client_rect
.bottom
- client_rect
.top
;
903 /* We are drawing to a bitmap */
907 Hbm
= GetCurrentObject(fb
->Hdc
, OBJ_BITMAP
);
909 if (!GetObjectW(Hbm
, sizeof(bm
), &bm
))
912 TRACE("Framebuffer size : %i, %i\n", bm
.bmWidth
, bm
.bmHeight
);
915 *height
= bm
.bmHeight
;
918 if ((*width
!= fb
->width
) || (*height
!= fb
->height
))
920 const struct pixel_format
* pixel_format
= fb
->pixel_format
;
922 if (pixel_format
->dwFlags
& PFD_DOUBLEBUFFER
)
924 /* Allocate a new backbuffer */
925 size_t BufferSize
= *height
* WIDTH_BYTES_ALIGN32(*width
, pixel_format
->cColorBits
);
928 fb
->BackBuffer
= HeapAlloc(GetProcessHeap(), 0, BufferSize
);
932 fb
->BackBuffer
= HeapReAlloc(GetProcessHeap(), 0, fb
->BackBuffer
, BufferSize
);
936 ERR("Failed allocating back buffer !.\n");
942 fb
->height
= *height
;
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[] ) \
953 TRACE("Writing color span at %u, %u (%u)\n", x, y, n); \
961 SetPixel(fb->Hdc, x + n, fb->height - y, \
962 PACK_COLORREF_##__bpp(red[n], green[n], blue[n])); \
970 SetPixel(fb->Hdc, x + n, fb->height - y, \
971 PACK_COLORREF_##__bpp(red[n], green[n], blue[n])); \
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
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[] ) \
988 struct sw_context* sw_ctx = ctx->DriverCtx; \
989 struct sw_framebuffer* fb = sw_ctx->fb; \
992 if (sw_ctx->Mode == GL_FRONT) \
994 write_color_span_frontbuffer_##__bpp(fb, n, x, y, red, green, blue, mask); \
998 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \
999 + (x + n) * __pixel_size; \
1004 Buffer -= __pixel_size; \
1007 PUT_PIXEL_##__bpp((__type*)Buffer, \
1008 PACK_COLOR_##__bpp(red[n], green[n], blue[n])); \
1016 Buffer -= __pixel_size; \
1017 PUT_PIXEL_##__bpp((__type*)Buffer, \
1018 PACK_COLOR_##__bpp(red[n], green[n], blue[n])); \
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
1028 static void write_monocolor_span_frontbuffer(struct sw_framebuffer
* fb
, GLuint n
, GLint x
, GLint y
,
1029 const GLubyte mask
[], COLORREF Color
)
1031 TRACE("Writing monocolor span at %u %u (%u), Color 0x%08x", x
, y
, n
, Color
);
1038 SetPixel(fb
->Hdc
, x
+ n
, y
, Color
);
1043 HBRUSH Brush
= CreateSolidBrush(Color
);
1044 Brush
= SelectObject(fb
->Hdc
, Brush
);
1046 PatBlt(fb
->Hdc
, x
, fb
->height
- y
, n
, 1, PATCOPY
);
1048 Brush
= SelectObject(fb
->Hdc
, Brush
);
1049 DeleteObject(Brush
);
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[]) \
1058 struct sw_context* sw_ctx = ctx->DriverCtx; \
1059 struct sw_framebuffer* fb = sw_ctx->fb; \
1062 if (sw_ctx->Mode == GL_FRONT) \
1064 write_monocolor_span_frontbuffer(fb, n, x, y, mask, \
1065 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor)); \
1069 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) + (x + n) * __pixel_size; \
1074 Buffer -= __pixel_size; \
1076 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \
1083 Buffer -= __pixel_size; \
1084 PUT_PIXEL_##__bpp((__type*)Buffer, sw_ctx->u##__bpp.CurrentColor); \
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
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[]) \
1102 struct sw_context* sw_ctx = ctx->DriverCtx; \
1103 struct sw_framebuffer* fb = sw_ctx->fb; \
1105 TRACE("Writing color pixels\n"); \
1107 if (sw_ctx->Mode == GL_FRONT) \
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])); \
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])); \
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
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
)
1144 TRACE("Writing monocolor pixels to front buffer.\n");
1150 SetPixel(fb
->Hdc
, x
[n
], fb
->height
- y
[n
], Color
);
1156 * Write an array of pixels with a boolean mask. The current color
1157 * is used for all pixels.
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[] ) \
1164 struct sw_context* sw_ctx = ctx->DriverCtx; \
1165 struct sw_framebuffer* fb = sw_ctx->fb; \
1167 if (sw_ctx->Mode == GL_FRONT) \
1169 write_monocolor_pixels_frontbuffer(fb, n, x, y, mask, \
1170 MAKE_COLORREF_##__bpp(fb->pixel_format, sw_ctx->u##__bpp.CurrentColor)); \
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); \
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
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
[] )
1197 ERR("Not implemented yet !\n");
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
[] )
1205 ERR("Not implemented yet !\n");
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
[])
1211 ERR("Not implemented yet !\n");
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[] ) \
1221 struct sw_context* sw_ctx = ctx->DriverCtx; \
1222 struct sw_framebuffer* fb = sw_ctx->fb; \
1225 if (sw_ctx->Mode == GL_FRONT) \
1230 Color = GetPixel(fb->Hdc, x + n, fb->height - y); \
1231 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]); \
1238 Buffer = fb->BackBuffer + y * WIDTH_BYTES_ALIGN32(fb->width, __bpp) \
1239 + (x + n) * __pixel_size; \
1242 Buffer -= __pixel_size; \
1243 UNPACK_COLOR_##__bpp(GET_PIXEL_##__bpp((__type*)Buffer), \
1244 &red[n], &green[n], &blue[n]); \
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
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
[])
1260 ERR("Not implemented yet !\n");
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[] ) \
1271 struct sw_context* sw_ctx = ctx->DriverCtx; \
1272 struct sw_framebuffer* fb = sw_ctx->fb; \
1274 if (sw_ctx->Mode == GL_FRONT) \
1281 Color = GetPixel(fb->Hdc, x[n], fb->height - y[n]); \
1282 UNPACK_COLORREF_##__bpp(Color, &red[n], &green[n], &blue[n]); \
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]); \
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
1308 static void setup_DD_pointers( GLcontext
* ctx
)
1310 struct sw_context
* sw_ctx
= ctx
->DriverCtx
;
1312 ctx
->Driver
.RendererString
= renderer_string
;
1313 ctx
->Driver
.UpdateState
= setup_DD_pointers
;
1315 switch (sw_ctx
->fb
->pixel_format
->cColorBits
)
1317 #define HANDLE_BPP(__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; \
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
;
1356 ctx
->Driver
.SetBuffer
= set_buffer
;
1357 ctx
->Driver
.GetBufferSize
= buffer_size
;
1359 /* Pixel/span writing functions: */
1360 ctx
->Driver
.WriteIndexSpan
= write_index_span
;
1361 ctx
->Driver
.WriteIndexPixels
= write_index_pixels
;
1363 /* Pixel/span reading functions: */
1364 ctx
->Driver
.ReadIndexSpan
= read_index_span
;
1365 ctx
->Driver
.ReadIndexPixels
= read_index_pixels
;
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"
1373 static GLCLTPROCTABLE sw_api_table
=
1375 OPENGL_VERSION_110_ENTRIES
,
1377 #define USE_GL_FUNC(name, proto_args, call_args, offset, stack) _mesa_##name,
1378 #include "glfuncs.h"
1383 GLcontext
* gl_get_thread_context(void)
1385 struct sw_context
* sw_ctx
= (struct sw_context
*)IntGetCurrentDHGLRC();
1386 return sw_ctx
->gl_ctx
;
1390 BOOL
sw_SetContext(struct wgl_dc_data
* dc_data
, DHGLRC dhglrc
)
1392 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
1393 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
1396 /* Get framebuffer size */
1397 if(dc_data
->flags
& WGL_DC_OBJ_DC
)
1399 HWND hwnd
= dc_data
->owner
.hwnd
;
1403 ERR("Physical DC without a window!\n");
1406 if(!GetClientRect(hwnd
, &client_rect
))
1408 ERR("GetClientRect failed!\n");
1412 /* This is a physical DC. Setup the hook */
1413 sw_ctx
->hook
= SetWindowsHookEx(WH_CALLWNDPROC
,
1414 sw_call_window_proc
,
1416 GetCurrentThreadId());
1418 /* Calculate width & height */
1419 width
= client_rect
.right
- client_rect
.left
;
1420 height
= client_rect
.bottom
- client_rect
.top
;
1422 else /* OBJ_MEMDC */
1426 HDC hdc
= dc_data
->owner
.hdc
;
1428 if(fb
->gl_visual
->DBflag
)
1430 ERR("Memory DC called with a double buffered format.\n");
1434 hbmp
= GetCurrentObject( hdc
, OBJ_BITMAP
);
1437 ERR("No Bitmap!\n");
1440 if(GetObject(hbmp
, sizeof(bm
), &bm
) == 0)
1442 ERR("GetObject failed!\n");
1446 height
= bm
.bmHeight
;
1449 if(!width
) width
= 1;
1450 if(!height
) height
= 1;
1452 /* Also make the mesa context current to mesa */
1453 gl_make_current(sw_ctx
->gl_ctx
, fb
->gl_buffer
);
1455 /* Setup our functions */
1456 setup_DD_pointers(sw_ctx
->gl_ctx
);
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)
1464 gl_Viewport(sw_ctx
->gl_ctx
, 0, 0, width
, height
);
1467 /* update the framebuffer size */
1468 gl_ResizeBuffersMESA(sw_ctx
->gl_ctx
);
1470 /* Use our API table */
1471 IntSetCurrentDispatchTable(&sw_api_table
.glDispatchTable
);
1477 void sw_ReleaseContext(DHGLRC dhglrc
)
1479 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
1481 /* Forward to mesa */
1482 gl_make_current(NULL
, NULL
);
1487 UnhookWindowsHookEx(sw_ctx
->hook
);
1488 sw_ctx
->hook
= NULL
;
1492 BOOL
sw_SwapBuffers(HDC hdc
, struct wgl_dc_data
* dc_data
)
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
;
1499 if (!fb
->gl_visual
->DBflag
)
1502 if (!fb
->BackBuffer
)
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
;
1519 DWORD
* BitMasks
= (DWORD
*)(&bmi
->bmiColors
[0]);
1520 BitMasks
[0] = 0x0000F800;
1521 BitMasks
[1] = 0x000007E0;
1522 BitMasks
[2] = 0x0000001F;
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;