gitlab-ci: enable sanitizers for the meson builds
[mesa-waffle.git] / src / waffle / wgl / wgl_display.c
blobcc4d37c75ddfbe850777ccf0795010ecd41c7de4
1 // SPDX-FileCopyrightText: Copyright 2014 Emil Velikov
2 // SPDX-License-Identifier: BSD-2-Clause
4 #include "c99_compat.h"
5 #include <assert.h>
6 #include <stdlib.h>
7 #include <windows.h>
9 #include "wcore_error.h"
11 #include "win_platform.h"
13 #include "wgl_display.h"
14 #include "wgl_platform.h"
16 bool
17 wgl_display_destroy(struct wcore_display *wc_self)
19 struct wgl_display *self = wgl_display(wc_self);
20 bool ok = true;
22 if (self->hWnd) {
23 if (self->hglrc) {
24 ok &= wglDeleteContext(self->hglrc);
27 if (self->hDC)
28 ok &= ReleaseDC(self->hWnd, self->hDC);
30 ok &= DestroyWindow(self->hWnd);
33 free(self);
34 return ok;
37 static bool
38 wgl_display_create_window(struct wgl_platform *plat, struct wgl_display *dpy)
40 dpy->hWnd = CreateWindow(plat->class_name, NULL,
41 WS_POPUPWINDOW|WS_DISABLED,
42 0, 0, 0, 0, NULL, NULL, NULL, NULL);
43 if (!dpy->hWnd)
44 return false;
46 dpy->hDC = GetDC(dpy->hWnd);
47 if (!dpy->hDC)
48 return false;
50 return true;
53 static bool
54 wgl_display_choose_config(struct wgl_display *dpy)
56 // XXX: Is there a move common/appropriate pixelformat ?
57 PIXELFORMATDESCRIPTOR pfd = {0};
58 bool ok;
60 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
61 pfd.nVersion = 1;
63 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
65 pfd.iPixelType = PFD_TYPE_RGBA;
66 pfd.iLayerType = PFD_MAIN_PLANE;
67 pfd.cColorBits = 32;
68 pfd.cDepthBits = 16;
70 dpy->pixel_format = ChoosePixelFormat(dpy->hDC, &pfd);
71 if (!dpy->pixel_format)
72 return false;
74 ok = SetPixelFormat(dpy->hDC, dpy->pixel_format, &pfd);
75 if (!ok)
76 return false;
78 return true;
81 static bool
82 wgl_display_hardware_render(struct wgl_display *dpy)
84 #ifndef GL_RENDERER
85 #define GL_RENDERER 0x1F01
86 #endif
87 typedef unsigned int GLenum;
88 typedef unsigned char GLubyte;
89 typedef const GLubyte * (__stdcall *PFNGLGETSTRINGPROC)(GLenum name);
91 PFNGLGETSTRINGPROC glGetString_func;
92 const GLubyte *gl_renderer;
94 glGetString_func = win_platform_dlsym(dpy->wcore.platform, WAFFLE_DL_OPENGL,
95 "glGetString");
96 if (!glGetString_func)
97 return false;
99 gl_renderer = glGetString_func(GL_RENDERER);
101 // Bail out if we cannot retrieve the renderer string or if we're using GDI
102 if (!gl_renderer || strcasecmp((const char *)gl_renderer, "GDI Generic") == 0)
103 return false;
105 return true;
108 static bool
109 wgl_display_set_extensions(struct wgl_display *dpy)
111 typedef const char * (__stdcall *PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
112 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func;
113 const char *extensions;
115 wglGetExtensionsStringARB_func = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
116 if (!wglGetExtensionsStringARB_func) {
117 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
118 "wglGetProcAddress(\"wglGetExtensionsStringARB\") failed");
119 return false;
122 extensions = wglGetExtensionsStringARB_func(dpy->hDC);
124 if (!extensions) {
125 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
126 "wglGetExtensionsStringARB failed");
127 return false;
130 dpy->ARB_create_context = waffle_is_extension_in_string(extensions, "WGL_ARB_create_context");
131 dpy->ARB_create_context_profile = waffle_is_extension_in_string(extensions, "WGL_ARB_create_context_profile");
132 dpy->ARB_create_context_robustness = waffle_is_extension_in_string(extensions, "WGL_ARB_create_context_robustness");
133 dpy->EXT_create_context_es_profile = waffle_is_extension_in_string(extensions, "WGL_EXT_create_context_es_profile");
135 // The WGL_EXT_create_context_es2_profile spec, version 5 2012/04/06,
136 // states that WGL_EXT_create_context_es_profile is an alias of
137 // WGL_EXT_create_context_es2_profile and requires that both names must be
138 // exported together for backwards compatibility with clients that expect
139 // the es2_profile name.
140 if (dpy->EXT_create_context_es_profile) {
141 dpy->EXT_create_context_es2_profile = true;
143 else {
144 // Assume that WGL does not implement version 3 of the extension, in
145 // which case the ES contexts WGL is capable of creating is ES2.
146 dpy->EXT_create_context_es2_profile = waffle_is_extension_in_string(extensions, "WGL_EXT_create_context_es2_profile");
149 dpy->ARB_pixel_format = waffle_is_extension_in_string(extensions, "WGL_ARB_pixel_format");
151 return true;
154 static bool
155 wgl_display_set_func_ptrs(struct wgl_display *dpy)
157 if (dpy->ARB_create_context) {
158 dpy->wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB");
159 if (!dpy->wglCreateContextAttribsARB) {
160 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
161 "wglGetProcAddress(\"wglCreateContextAttribsARB\") failed");
162 return false;
166 if (dpy->ARB_pixel_format) {
167 dpy->wglChoosePixelFormatARB = (void *)wglGetProcAddress("wglChoosePixelFormatARB");
168 if (!dpy->wglChoosePixelFormatARB) {
169 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
170 "wglGetProcAddress(\"wglChoosePixelFormatARB\") failed");
171 return false;
175 return true;
178 struct wcore_display*
179 wgl_display_connect(struct wcore_platform *wc_plat,
180 const char *name)
182 struct wgl_display *self;
183 bool ok;
185 self = wcore_calloc(sizeof(*self));
186 if (!self)
187 return NULL;
189 wcore_display_init(&self->wcore, wc_plat);
191 ok = wgl_display_create_window(wgl_platform(wc_plat), self);
192 if (!ok)
193 goto error;
195 ok = wgl_display_choose_config(self);
196 if (!ok)
197 goto error;
199 self->hglrc = wglCreateContext(self->hDC);
200 if (!self->hglrc)
201 goto error;
203 ok = wglMakeCurrent(self->hDC, self->hglrc);
204 if (!ok)
205 goto error;
207 ok = wgl_display_hardware_render(self);
208 if (!ok)
209 goto error;
211 ok = wgl_display_set_extensions(self);
212 if (!ok)
213 goto error;
215 ok = wgl_display_set_func_ptrs(self);
216 if (!ok)
217 goto error;
219 ok = wglMakeCurrent(NULL, NULL);
220 if (!ok)
221 goto error;
223 return &self->wcore;
225 error:
226 wgl_display_destroy(&self->wcore);
227 return NULL;
230 bool
231 wgl_display_supports_context_api(struct wcore_display *wc_self,
232 int32_t context_api)
234 struct wgl_display *self = wgl_display(wc_self);
236 switch (context_api) {
237 case WAFFLE_CONTEXT_OPENGL:
238 return true;
239 case WAFFLE_CONTEXT_OPENGL_ES1:
240 return self->EXT_create_context_es_profile;
241 case WAFFLE_CONTEXT_OPENGL_ES2:
242 return self->EXT_create_context_es2_profile;
243 case WAFFLE_CONTEXT_OPENGL_ES3:
244 return self->EXT_create_context_es_profile;
245 default:
246 assert(false);
247 return false;