Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/wgl/stw_ext_pbuffer.c
4561 views
1
/**************************************************************************
2
*
3
* Copyright 2010 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
#include <windows.h>
29
30
#define WGL_WGLEXT_PROTOTYPES
31
32
#include <GL/gl.h>
33
#include <GL/wglext.h>
34
35
#include "pipe/p_defines.h"
36
#include "pipe/p_screen.h"
37
38
#include "util/u_debug.h"
39
40
#include "stw_device.h"
41
#include "stw_pixelformat.h"
42
#include "stw_framebuffer.h"
43
44
45
#define LARGE_WINDOW_SIZE 60000
46
47
48
static LRESULT CALLBACK
49
WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
50
{
51
MINMAXINFO *pMMI;
52
switch (uMsg) {
53
case WM_GETMINMAXINFO:
54
// Allow to create a window bigger than the desktop
55
pMMI = (MINMAXINFO *)lParam;
56
pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE;
57
pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE;
58
pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE;
59
pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE;
60
break;
61
default:
62
break;
63
}
64
65
return DefWindowProc(hWnd, uMsg, wParam, lParam);
66
}
67
68
69
HPBUFFERARB WINAPI
70
wglCreatePbufferARB(HDC hCurrentDC,
71
int iPixelFormat,
72
int iWidth,
73
int iHeight,
74
const int *piAttribList)
75
{
76
static boolean first = TRUE;
77
const int *piAttrib;
78
int useLargest = 0;
79
const struct stw_pixelformat_info *info;
80
struct stw_framebuffer *fb;
81
DWORD dwExStyle;
82
DWORD dwStyle;
83
RECT rect;
84
HWND hWnd;
85
HDC hDC;
86
int iDisplayablePixelFormat;
87
PIXELFORMATDESCRIPTOR pfd;
88
BOOL bRet;
89
int textureFormat = WGL_NO_TEXTURE_ARB;
90
int textureTarget = WGL_NO_TEXTURE_ARB;
91
BOOL textureMipmap = FALSE;
92
93
info = stw_pixelformat_get_info(iPixelFormat);
94
if (!info) {
95
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
96
return 0;
97
}
98
99
if (iWidth <= 0 || iHeight <= 0) {
100
SetLastError(ERROR_INVALID_DATA);
101
return 0;
102
}
103
104
if (piAttribList) {
105
for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
106
switch (*piAttrib) {
107
case WGL_PBUFFER_LARGEST_ARB:
108
piAttrib++;
109
useLargest = *piAttrib;
110
break;
111
case WGL_TEXTURE_FORMAT_ARB:
112
/* WGL_ARB_render_texture */
113
piAttrib++;
114
textureFormat = *piAttrib;
115
if (textureFormat != WGL_TEXTURE_RGB_ARB &&
116
textureFormat != WGL_TEXTURE_RGBA_ARB &&
117
textureFormat != WGL_NO_TEXTURE_ARB) {
118
SetLastError(ERROR_INVALID_DATA);
119
return 0;
120
}
121
break;
122
case WGL_TEXTURE_TARGET_ARB:
123
/* WGL_ARB_render_texture */
124
piAttrib++;
125
textureTarget = *piAttrib;
126
if (textureTarget != WGL_TEXTURE_CUBE_MAP_ARB &&
127
textureTarget != WGL_TEXTURE_1D_ARB &&
128
textureTarget != WGL_TEXTURE_2D_ARB &&
129
textureTarget != WGL_NO_TEXTURE_ARB) {
130
SetLastError(ERROR_INVALID_DATA);
131
return 0;
132
}
133
break;
134
case WGL_MIPMAP_TEXTURE_ARB:
135
/* WGL_ARB_render_texture */
136
piAttrib++;
137
textureMipmap = !!*piAttrib;
138
break;
139
default:
140
SetLastError(ERROR_INVALID_DATA);
141
debug_printf("wgl: Unsupported attribute 0x%x in %s\n",
142
*piAttrib, __func__);
143
return 0;
144
}
145
}
146
}
147
148
if (iWidth > stw_dev->max_2d_length) {
149
if (useLargest) {
150
iWidth = stw_dev->max_2d_length;
151
} else {
152
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
153
return 0;
154
}
155
}
156
157
if (iHeight > stw_dev->max_2d_length) {
158
if (useLargest) {
159
iHeight = stw_dev->max_2d_length;
160
} else {
161
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
162
return 0;
163
}
164
}
165
166
/*
167
* Implement pbuffers through invisible windows
168
*/
169
170
if (first) {
171
WNDCLASS wc;
172
memset(&wc, 0, sizeof wc);
173
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
174
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
175
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
176
wc.lpfnWndProc = WndProc;
177
wc.lpszClassName = "wglpbuffer";
178
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
179
RegisterClass(&wc);
180
first = FALSE;
181
}
182
183
dwExStyle = 0;
184
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
185
186
if (0) {
187
/*
188
* Don't hide the window -- useful for debugging what the application is
189
* drawing
190
*/
191
192
dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW;
193
} else {
194
dwStyle |= WS_POPUPWINDOW;
195
}
196
197
rect.left = 0;
198
rect.top = 0;
199
rect.right = rect.left + iWidth;
200
rect.bottom = rect.top + iHeight;
201
202
/*
203
* The CreateWindowEx parameters are the total (outside) dimensions of the
204
* window, which can vary with Windows version and user settings. Use
205
* AdjustWindowRect to get the required total area for the given client area.
206
*
207
* AdjustWindowRectEx does not accept WS_OVERLAPPED style (which is defined
208
* as 0), which means we need to use some other style instead, e.g.,
209
* WS_OVERLAPPEDWINDOW or WS_POPUPWINDOW as above.
210
*/
211
212
AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
213
214
hWnd = CreateWindowEx(dwExStyle,
215
"wglpbuffer", /* wc.lpszClassName */
216
NULL,
217
dwStyle,
218
CW_USEDEFAULT, /* x */
219
CW_USEDEFAULT, /* y */
220
rect.right - rect.left, /* width */
221
rect.bottom - rect.top, /* height */
222
NULL,
223
NULL,
224
NULL,
225
NULL);
226
if (!hWnd) {
227
return 0;
228
}
229
230
#ifdef DEBUG
231
/*
232
* Verify the client area size matches the specified size.
233
*/
234
235
GetClientRect(hWnd, &rect);
236
assert(rect.left == 0);
237
assert(rect.top == 0);
238
assert(rect.right - rect.left == iWidth);
239
assert(rect.bottom - rect.top == iHeight);
240
#endif
241
242
hDC = GetDC(hWnd);
243
if (!hDC) {
244
return 0;
245
}
246
247
/*
248
* We can't pass non-displayable pixel formats to GDI, which is why we
249
* create the framebuffer object before calling SetPixelFormat().
250
*/
251
fb = stw_framebuffer_create(hDC, iPixelFormat);
252
if (!fb) {
253
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
254
return NULL;
255
}
256
257
fb->bPbuffer = TRUE;
258
259
/* WGL_ARB_render_texture fields */
260
fb->textureTarget = textureTarget;
261
fb->textureFormat = textureFormat;
262
fb->textureMipmap = textureMipmap;
263
264
iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
265
266
stw_framebuffer_unlock(fb);
267
268
/*
269
* We need to set a displayable pixel format on the hidden window DC
270
* so that wglCreateContext and wglMakeCurrent are not overruled by GDI.
271
*/
272
bRet = SetPixelFormat(hDC, iDisplayablePixelFormat, &pfd);
273
assert(bRet);
274
275
return (HPBUFFERARB)fb;
276
}
277
278
279
HDC WINAPI
280
wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
281
{
282
struct stw_framebuffer *fb;
283
HDC hDC;
284
285
if (!hPbuffer) {
286
SetLastError(ERROR_INVALID_HANDLE);
287
return NULL;
288
}
289
290
fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
291
292
hDC = GetDC(fb->hWnd);
293
294
return hDC;
295
}
296
297
298
int WINAPI
299
wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
300
HDC hDC)
301
{
302
struct stw_framebuffer *fb;
303
304
if (!hPbuffer) {
305
SetLastError(ERROR_INVALID_HANDLE);
306
return 0;
307
}
308
309
fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
310
311
return ReleaseDC(fb->hWnd, hDC);
312
}
313
314
315
BOOL WINAPI
316
wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
317
{
318
struct stw_framebuffer *fb;
319
320
if (!hPbuffer) {
321
SetLastError(ERROR_INVALID_HANDLE);
322
return FALSE;
323
}
324
325
fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
326
327
/* This will destroy all our data */
328
return DestroyWindow(fb->hWnd);
329
}
330
331
332
BOOL WINAPI
333
wglQueryPbufferARB(HPBUFFERARB hPbuffer,
334
int iAttribute,
335
int *piValue)
336
{
337
struct stw_framebuffer *fb;
338
339
if (!hPbuffer) {
340
SetLastError(ERROR_INVALID_HANDLE);
341
return FALSE;
342
}
343
344
fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
345
346
switch (iAttribute) {
347
case WGL_PBUFFER_WIDTH_ARB:
348
*piValue = fb->width;
349
return TRUE;
350
case WGL_PBUFFER_HEIGHT_ARB:
351
*piValue = fb->height;
352
return TRUE;
353
case WGL_PBUFFER_LOST_ARB:
354
/* We assume that no content is ever lost due to display mode change */
355
*piValue = FALSE;
356
return TRUE;
357
/* WGL_ARB_render_texture */
358
case WGL_TEXTURE_TARGET_ARB:
359
*piValue = fb->textureTarget;
360
return TRUE;
361
case WGL_TEXTURE_FORMAT_ARB:
362
*piValue = fb->textureFormat;
363
return TRUE;
364
case WGL_MIPMAP_TEXTURE_ARB:
365
*piValue = fb->textureMipmap;
366
return TRUE;
367
case WGL_MIPMAP_LEVEL_ARB:
368
*piValue = fb->textureLevel;
369
return TRUE;
370
case WGL_CUBE_MAP_FACE_ARB:
371
*piValue = fb->textureFace + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
372
return TRUE;
373
default:
374
SetLastError(ERROR_INVALID_DATA);
375
return FALSE;
376
}
377
}
378
379