ec008b54e16ca688a66f8e362336a3e2370f7867
[reactos.git] / dll / opengl / opengl32 / swimpl.c
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", 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 }