tu: Implement fallback linear staging blit for CopyImage
[mesa.git] / src / gallium / state_trackers / wgl / stw_wgl.c
1 /**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * @file
30 *
31 * Fake WGL API implementation.
32 *
33 * These functions implement the WGL API, on top of the ICD DDI, so that the
34 * resulting DLL can be used as a drop-in replacement for the system's
35 * opengl32.dll.
36 *
37 * These functions never get called for ICD drivers, which use exclusively the
38 * ICD DDI, i.e., the Drv* entrypoints.
39 */
40
41 #include <windows.h>
42 #include <GL/gl.h>
43
44 #include "util/u_debug.h"
45 #include "gldrv.h"
46 #include "stw_context.h"
47 #include "stw_pixelformat.h"
48 #include "stw_wgl.h"
49 #include "stw_ext_context.h"
50
51
52 static void
53 overrideOpenGL32EntryPoints(void);
54
55 WINGDIAPI BOOL APIENTRY
56 wglCopyContext(
57 HGLRC hglrcSrc,
58 HGLRC hglrcDst,
59 UINT mask )
60 {
61 return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc,
62 (DHGLRC)(UINT_PTR)hglrcDst,
63 mask );
64 }
65
66 WINGDIAPI HGLRC APIENTRY
67 wglCreateContext(
68 HDC hdc )
69 {
70 overrideOpenGL32EntryPoints();
71 return (HGLRC)(UINT_PTR)DrvCreateContext(hdc);
72 }
73
74 WINGDIAPI HGLRC APIENTRY
75 wglCreateLayerContext(
76 HDC hdc,
77 int iLayerPlane )
78 {
79 overrideOpenGL32EntryPoints();
80 return (HGLRC)(UINT_PTR)DrvCreateLayerContext( hdc, iLayerPlane );
81 }
82
83 WINGDIAPI BOOL APIENTRY
84 wglDeleteContext(
85 HGLRC hglrc )
86 {
87 return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc );
88 }
89
90
91 WINGDIAPI HGLRC APIENTRY
92 wglGetCurrentContext( VOID )
93 {
94 return (HGLRC)(UINT_PTR)stw_get_current_context();
95 }
96
97 WINGDIAPI HDC APIENTRY
98 wglGetCurrentDC( VOID )
99 {
100 return stw_get_current_dc();
101 }
102
103 WINGDIAPI HDC APIENTRY
104 wglGetCurrentReadDCARB( VOID )
105 {
106 return stw_get_current_read_dc();
107 }
108
109
110 WINGDIAPI BOOL APIENTRY
111 wglMakeCurrent(
112 HDC hdc,
113 HGLRC hglrc )
114 {
115 return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE;
116 }
117
118
119 WINGDIAPI BOOL APIENTRY
120 wglSwapBuffers(
121 HDC hdc )
122 {
123 return DrvSwapBuffers( hdc );
124 }
125
126
127 WINGDIAPI DWORD WINAPI
128 wglSwapMultipleBuffers(UINT n,
129 CONST WGLSWAP *ps)
130 {
131 UINT i;
132
133 for (i =0; i < n; ++i)
134 wglSwapBuffers(ps->hdc);
135
136 return 0;
137 }
138
139
140 WINGDIAPI BOOL APIENTRY
141 wglSwapLayerBuffers(
142 HDC hdc,
143 UINT fuPlanes )
144 {
145 return DrvSwapLayerBuffers( hdc, fuPlanes );
146 }
147
148 WINGDIAPI PROC APIENTRY
149 wglGetProcAddress(
150 LPCSTR lpszProc )
151 {
152 return DrvGetProcAddress( lpszProc );
153 }
154
155
156 WINGDIAPI int APIENTRY
157 wglChoosePixelFormat(
158 HDC hdc,
159 CONST PIXELFORMATDESCRIPTOR *ppfd )
160 {
161 if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ) || ppfd->nVersion != 1)
162 return 0;
163 if (ppfd->iPixelType != PFD_TYPE_RGBA)
164 return 0;
165 if (!(ppfd->dwFlags & PFD_DRAW_TO_WINDOW))
166 return 0;
167 if (!(ppfd->dwFlags & PFD_SUPPORT_OPENGL))
168 return 0;
169 if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP)
170 return 0;
171 if (ppfd->dwFlags & PFD_SUPPORT_GDI)
172 return 0;
173 if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO))
174 return 0;
175
176 return stw_pixelformat_choose( hdc, ppfd );
177 }
178
179 WINGDIAPI int APIENTRY
180 wglDescribePixelFormat(
181 HDC hdc,
182 int iPixelFormat,
183 UINT nBytes,
184 LPPIXELFORMATDESCRIPTOR ppfd )
185 {
186 return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd );
187 }
188
189 WINGDIAPI int APIENTRY
190 wglGetPixelFormat(
191 HDC hdc )
192 {
193 return stw_pixelformat_get( hdc );
194 }
195
196 WINGDIAPI BOOL APIENTRY
197 wglSetPixelFormat(
198 HDC hdc,
199 int iPixelFormat,
200 const PIXELFORMATDESCRIPTOR *ppfd )
201 {
202 /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
203 * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
204 */
205 (void) ppfd;
206
207 return DrvSetPixelFormat( hdc, iPixelFormat );
208 }
209
210
211 WINGDIAPI BOOL APIENTRY
212 wglUseFontBitmapsA(
213 HDC hdc,
214 DWORD first,
215 DWORD count,
216 DWORD listBase )
217 {
218 return wglUseFontBitmapsW(hdc, first, count, listBase);
219 }
220
221 WINGDIAPI BOOL APIENTRY
222 wglShareLists(
223 HGLRC hglrc1,
224 HGLRC hglrc2 )
225 {
226 return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1,
227 (DHGLRC)(UINT_PTR)hglrc2);
228 }
229
230 WINGDIAPI BOOL APIENTRY
231 wglUseFontBitmapsW(
232 HDC hdc,
233 DWORD first,
234 DWORD count,
235 DWORD listBase )
236 {
237 GLYPHMETRICS gm;
238 MAT2 tra;
239 FIXED one, minus_one, zero;
240 void *buffer = NULL;
241 BOOL result = TRUE;
242
243 one.value = 1;
244 one.fract = 0;
245 minus_one.value = -1;
246 minus_one.fract = 0;
247 zero.value = 0;
248 zero.fract = 0;
249
250 tra.eM11 = one;
251 tra.eM22 = minus_one;
252 tra.eM12 = tra.eM21 = zero;
253
254 for (int i = 0; i < count; i++) {
255 DWORD size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0,
256 NULL, &tra);
257
258 glNewList(listBase + i, GL_COMPILE);
259
260 if (size != GDI_ERROR) {
261 if (size == 0) {
262 glBitmap(0, 0, (GLfloat)-gm.gmptGlyphOrigin.x,
263 (GLfloat)gm.gmptGlyphOrigin.y,
264 (GLfloat)gm.gmCellIncX,
265 (GLfloat)gm.gmCellIncY, NULL);
266 }
267 else {
268 buffer = realloc(buffer, size);
269 size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm,
270 size, buffer, &tra);
271
272 glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
273 -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y,
274 gm.gmCellIncX, gm.gmCellIncY, buffer);
275 }
276 }
277 else {
278 result = FALSE;
279 }
280
281 glEndList();
282 }
283
284 free(buffer);
285
286 return result;
287 }
288
289 WINGDIAPI BOOL APIENTRY
290 wglUseFontOutlinesA(
291 HDC hdc,
292 DWORD first,
293 DWORD count,
294 DWORD listBase,
295 FLOAT deviation,
296 FLOAT extrusion,
297 int format,
298 LPGLYPHMETRICSFLOAT lpgmf )
299 {
300 (void) hdc;
301 (void) first;
302 (void) count;
303 (void) listBase;
304 (void) deviation;
305 (void) extrusion;
306 (void) format;
307 (void) lpgmf;
308
309 assert( 0 );
310
311 return FALSE;
312 }
313
314 WINGDIAPI BOOL APIENTRY
315 wglUseFontOutlinesW(
316 HDC hdc,
317 DWORD first,
318 DWORD count,
319 DWORD listBase,
320 FLOAT deviation,
321 FLOAT extrusion,
322 int format,
323 LPGLYPHMETRICSFLOAT lpgmf )
324 {
325 (void) hdc;
326 (void) first;
327 (void) count;
328 (void) listBase;
329 (void) deviation;
330 (void) extrusion;
331 (void) format;
332 (void) lpgmf;
333
334 assert( 0 );
335
336 return FALSE;
337 }
338
339 WINGDIAPI BOOL APIENTRY
340 wglDescribeLayerPlane(
341 HDC hdc,
342 int iPixelFormat,
343 int iLayerPlane,
344 UINT nBytes,
345 LPLAYERPLANEDESCRIPTOR plpd )
346 {
347 return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
348 }
349
350 WINGDIAPI int APIENTRY
351 wglSetLayerPaletteEntries(
352 HDC hdc,
353 int iLayerPlane,
354 int iStart,
355 int cEntries,
356 CONST COLORREF *pcr )
357 {
358 return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
359 }
360
361 WINGDIAPI int APIENTRY
362 wglGetLayerPaletteEntries(
363 HDC hdc,
364 int iLayerPlane,
365 int iStart,
366 int cEntries,
367 COLORREF *pcr )
368 {
369 return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
370 }
371
372 WINGDIAPI BOOL APIENTRY
373 wglRealizeLayerPalette(
374 HDC hdc,
375 int iLayerPlane,
376 BOOL bRealize )
377 {
378 (void) hdc;
379 (void) iLayerPlane;
380 (void) bRealize;
381
382 assert( 0 );
383
384 return FALSE;
385 }
386
387
388 /* When this library is used as a opengl32.dll drop-in replacement, ensure we
389 * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll,
390 * which could happen if this library's name is not opengl32.dll exactly.
391 *
392 * For example, Qt 5.4 bundles this as opengl32sw.dll:
393 * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/
394 */
395 static void
396 overrideOpenGL32EntryPoints(void)
397 {
398 wglCreateContext_func = &wglCreateContext;
399 wglDeleteContext_func = &wglDeleteContext;
400 }