gitlab-ci: enable sanitizers for the meson builds
[mesa-waffle.git] / src / waffle / wgl / wgl_config.c
blobb3bf5a5818374516e71820117c0892c4c7a2fa96
1 // SPDX-FileCopyrightText: Copyright 2014 Emil Velikov
2 // SPDX-License-Identifier: BSD-2-Clause
4 #include <assert.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <windows.h>
9 #include "wcore_config_attrs.h"
10 #include "wcore_error.h"
12 #include "wgl_config.h"
13 #include "wgl_context.h"
14 #include "wgl_display.h"
15 #include "wgl_platform.h"
16 #include "wgl_window.h"
18 bool
19 wgl_config_destroy(struct wcore_config *wc_self)
21 struct wgl_config *self = wgl_config(wc_self);
22 bool ok = true;
24 if (self->window)
25 ok &= wgl_window_priv_destroy(&self->window->wcore);
27 free(self);
28 return ok;
31 /// @brief Check the values of `attrs->context_*`.
32 static bool
33 wgl_config_check_context_attrs(struct wgl_display *dpy,
34 const struct wcore_config_attrs *attrs)
36 if (!dpy->ARB_create_context &&
37 wgl_context_needs_arb_create_context(attrs)) {
38 const char *gl = "";
39 const char *fwd_compat = "";
40 const char *debug = "";
41 const char *robust = "";
43 // XXX: Keep in sync with glx_context_needs_arb_create_context()
44 if (attrs->context_api != WAFFLE_CONTEXT_OPENGL)
45 gl = " - a OpenGL ES* context\n";
46 else if (wcore_config_attrs_version_ge(attrs, 32))
47 gl = " - a OpenGL 3.2+ context\n";
49 if (attrs->context_forward_compatible)
50 fwd_compat = " - a forward-compatible context\n";
52 if (attrs->context_debug)
53 debug = " - a debug context\n";
55 if (attrs->context_robust)
56 robust = " - a robust access context\n";
58 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
59 "WGL_ARB_create_context is required to create:\n"
60 "%s%s%s%s", gl, fwd_compat, debug, robust);
61 return false;
64 if (attrs->context_robust && !dpy->ARB_create_context_robustness) {
65 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
66 "WGL_ARB_create_context_robustness is required in order to "
67 "request a robust access context");
68 return false;
71 switch (attrs->context_api) {
72 case WAFFLE_CONTEXT_OPENGL:
73 if (wcore_config_attrs_version_ge(attrs, 32) && !dpy->ARB_create_context_profile) {
74 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
75 "WGL_ARB_create_context_profile is required "
76 "to create a context with version >= 3.2");
77 return false;
80 return true;
82 case WAFFLE_CONTEXT_OPENGL_ES1:
83 case WAFFLE_CONTEXT_OPENGL_ES2:
84 case WAFFLE_CONTEXT_OPENGL_ES3:
85 if (!dpy->EXT_create_context_es_profile &&
86 !dpy->EXT_create_context_es2_profile) {
87 wcore_errorf(WAFFLE_ERROR_UNSUPPORTED_ON_PLATFORM,
88 "WGL_EXT_create_context_es_profile or "
89 "WGL_EXT_create_context_es2_profile is required "
90 "to create an OpenGL ES* context");
91 return false;
94 return true;
96 default:
97 assert(false);
98 return false;
102 static void
103 wgl_config_set_pixeldescriptor(struct wgl_config *config,
104 const struct wcore_config_attrs *attrs)
106 PIXELFORMATDESCRIPTOR *pfd = &config->pfd;
108 pfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
109 pfd->nVersion = 1;
111 pfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
112 if (attrs->double_buffered)
113 pfd->dwFlags |= PFD_DOUBLEBUFFER;
115 pfd->iPixelType = PFD_TYPE_RGBA;
117 pfd->cColorBits = attrs->rgba_size;
118 pfd->cRedBits = attrs->red_size;
119 pfd->cGreenBits = attrs->green_size;
120 pfd->cBlueBits = attrs->blue_size;
121 pfd->cAlphaBits = attrs->alpha_size;
123 pfd->cDepthBits = attrs->depth_size;
124 pfd->cStencilBits = attrs->stencil_size;
126 // XXX: Double check these
127 pfd->cAccumRedBits = attrs->accum_buffer;
128 pfd->cAccumGreenBits = attrs->accum_buffer;
129 pfd->cAccumBlueBits = attrs->accum_buffer;
130 pfd->cAccumAlphaBits = attrs->accum_buffer;
131 pfd->cAccumBits = pfd->cAccumRedBits +
132 pfd->cAccumGreenBits +
133 pfd->cAccumBlueBits +
134 pfd->cAccumAlphaBits;
136 pfd->iLayerType = PFD_MAIN_PLANE;
139 static bool
140 wgl_config_choose_native(struct wgl_config *config,
141 struct wgl_display *dpy,
142 const struct wcore_config_attrs *attrs)
145 // Use wglChoosePixelFormatARB if available.
146 if (dpy->ARB_pixel_format) {
147 float fAttribs[1] = { 0 };
148 int iAttribs[] = {
149 WGL_COLOR_BITS_ARB, attrs->rgba_size,
150 WGL_RED_BITS_ARB, attrs->red_size,
151 WGL_GREEN_BITS_ARB, attrs->green_size,
152 WGL_BLUE_BITS_ARB, attrs->blue_size,
153 WGL_ALPHA_BITS_ARB, attrs->alpha_size,
155 WGL_DEPTH_BITS_ARB, attrs->depth_size,
156 WGL_STENCIL_BITS_ARB, attrs->stencil_size,
158 WGL_SAMPLE_BUFFERS_ARB, attrs->sample_buffers,
159 WGL_STEREO_ARB, attrs->samples,
161 WGL_DOUBLE_BUFFER_ARB, attrs->double_buffered,
163 WGL_ACCUM_RED_BITS_ARB, attrs->accum_buffer,
164 WGL_ACCUM_GREEN_BITS_ARB, attrs->accum_buffer,
165 WGL_ACCUM_BLUE_BITS_ARB, attrs->accum_buffer,
166 WGL_ACCUM_ALPHA_BITS_ARB, attrs->accum_buffer,
168 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
169 WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
173 unsigned int num_formats;
174 bool ok;
176 // But first we need a current context to use it...
177 ok = wglMakeCurrent(dpy->hDC, dpy->hglrc);
178 if (!ok)
179 return false;
181 ok = dpy->wglChoosePixelFormatARB(dpy->hDC, iAttribs, fAttribs, 1,
182 &config->pixel_format, &num_formats);
184 wglMakeCurrent(NULL, NULL);
186 if (!ok || !num_formats) {
187 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
188 "wglChoosePixelFormatARB failed");
189 return false;
193 else {
194 config->pixel_format = ChoosePixelFormat(dpy->hDC, &config->pfd);
195 if (!config->pixel_format) {
196 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
197 "ChoosePixelFormat failed to find a matching format");
198 return false;
202 return true;
206 struct wcore_config*
207 wgl_config_choose(struct wcore_platform *wc_plat,
208 struct wcore_display *wc_dpy,
209 const struct wcore_config_attrs *attrs)
211 struct wgl_config *self;
212 struct wgl_display *dpy = wgl_display(wc_dpy);
213 struct wcore_window *wc_window;
214 bool ok;
216 ok = wgl_config_check_context_attrs(dpy, attrs);
217 if (!ok)
218 return NULL;
220 self = wcore_calloc(sizeof(*self));
221 if (!self)
222 return NULL;
224 wcore_config_init(&self->wcore, wc_dpy, attrs);
226 wgl_config_set_pixeldescriptor(self, attrs);
228 ok = wgl_config_choose_native(self, dpy, attrs);
229 if (!ok)
230 goto error;
232 // Hurray, we've got the pixel format.
234 wc_window = wgl_window_priv_create(wc_plat, &self->wcore, 10, 10);
235 if (!wc_window)
236 goto error;
238 self->window = wgl_window(wc_window);
240 // Now let's pray that the root window's hDC is compatible with the
241 // new window hDC.
242 ok = SetPixelFormat(self->window->hDC, self->pixel_format, &self->pfd);
243 if (!ok)
244 goto error;
246 return &self->wcore;
248 error:
249 wgl_config_destroy(&self->wcore);
250 return NULL;