1 // SPDX-FileCopyrightText: Copyright 2014 Emil Velikov
2 // SPDX-License-Identifier: BSD-2-Clause
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"
19 wgl_config_destroy(struct wcore_config
*wc_self
)
21 struct wgl_config
*self
= wgl_config(wc_self
);
25 ok
&= wgl_window_priv_destroy(&self
->window
->wcore
);
31 /// @brief Check the values of `attrs->context_*`.
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
)) {
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
);
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");
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");
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");
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
);
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
;
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 };
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
;
176 // But first we need a current context to use it...
177 ok
= wglMakeCurrent(dpy
->hDC
, dpy
->hglrc
);
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");
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");
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
;
216 ok
= wgl_config_check_context_attrs(dpy
, attrs
);
220 self
= wcore_calloc(sizeof(*self
));
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
);
232 // Hurray, we've got the pixel format.
234 wc_window
= wgl_window_priv_create(wc_plat
, &self
->wcore
, 10, 10);
238 self
->window
= wgl_window(wc_window
);
240 // Now let's pray that the root window's hDC is compatible with the
242 ok
= SetPixelFormat(self
->window
->hDC
, self
->pixel_format
, &self
->pfd
);
249 wgl_config_destroy(&self
->wcore
);