[waffle] [PATCH 06/18] wgl: implement display management
Jose Fonseca
jfonseca at vmware.com
Wed Jul 23 08:27:40 PDT 2014
On 23/07/14 16:25, Jose Fonseca wrote:
> On 23/07/14 04:31, Emil Velikov wrote:
>> Unlike GLX and EGL, WGL(Windows) does not have the concept of a display
>> in the sense used in waffle.
>>
>> The 'root primitive' for WGL is a window with it's device context
>> which encapsulates the properties and capabilities of the device
>> doing the actual rendering (CPU or GPU).
>>
>> As such we first need to create a unique window class that will be
>> used for all waffle windows, and then create the 'root' window.
>>
>> The windows itself is disabled (cannot grab the input) and of zero
>> width and height.
>>
>> While we're here make sure that we create a context, which will be
>> needed in a variety of cases - when we query the WGL extensions, as a
>> fallback context in waffle_get_proc_address...
>>
>> v2: Bail out if we're using the GDI renderer.
>>
>> Signed-off-by: Emil Velikov <emil.l.velikov at gmail.com>
>> ---
>> src/waffle/wgl/wgl_display.c | 121
>> +++++++++++++++++++++++++++++++++++++++++-
>> src/waffle/wgl/wgl_display.h | 5 ++
>> src/waffle/wgl/wgl_platform.c | 41 ++++++++++++++
>> src/waffle/wgl/wgl_platform.h | 3 ++
>> 4 files changed, 168 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/waffle/wgl/wgl_display.c b/src/waffle/wgl/wgl_display.c
>> index a51e538..e5317aa 100644
>> --- a/src/waffle/wgl/wgl_display.c
>> +++ b/src/waffle/wgl/wgl_display.c
>> @@ -25,25 +25,126 @@
>>
>>
>> #include <stdlib.h>
>> +#include <strings.h>
>> +#include <windows.h>
>>
>> #include "wcore_error.h"
>>
>> #include "wgl_display.h"
>> +#include "wgl_dl.h"
>> +#include "wgl_platform.h"
>>
>> bool
>> wgl_display_destroy(struct wcore_display *wc_self)
>> {
>> struct wgl_display *self = wgl_display(wc_self);
>> - bool ok;
>> + bool ok = true;
>>
>> if (!self)
>> return true;
>>
>> - ok = wcore_display_teardown(wc_self);
>> + if (self->hWnd) {
>> + if (self->hglrc) {
>> + ok &= wglDeleteContext(self->hglrc);
>> + }
>> +
>> + if (self->hDC)
>> + ok &= ReleaseDC(self->hWnd, self->hDC);
>> +
>> + ok &= DestroyWindow(self->hWnd);
>> + }
>> +
>> + ok &= wcore_display_teardown(wc_self);
>> free(self);
>> return ok;
>> }
>>
>> +static bool
>> +wgl_display_create_window(struct wgl_platform *plat, struct
>> wgl_display *dpy)
>> +{
>> + dpy->hWnd = CreateWindow(plat->class_name, NULL,
>> + WS_POPUPWINDOW|WS_DISABLED,
>> + 0, 0, 0, 0, NULL, NULL, NULL, NULL);
>> + if (!dpy->hWnd)
>> + return false;
>> +
>> + dpy->hDC = GetDC(dpy->hWnd);
>> + if (!dpy->hDC)
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +static bool
>> +wgl_display_choose_config(struct wgl_display *dpy)
>> +{
>> + // XXX: Is there a move common/approapriate pixelformat ?
>
> approapriate -> appropriate
>
>> + PIXELFORMATDESCRIPTOR pfd = {
>> + sizeof(PIXELFORMATDESCRIPTOR),
>> + 1,
>> + PFD_SUPPORT_OPENGL |
>> + PFD_DRAW_TO_WINDOW |
>> + PFD_DOUBLEBUFFER,
>> + PFD_TYPE_RGBA,
>> + 32,
>> + 0, 0, 0, 0, 0, 0,
>> + 0,
>> + 0,
>> + 0,
>> + 0, 0, 0, 0,
>> + 16,
>> + 0,
>> + 0,
>> + PFD_MAIN_PLANE,
>> + 0,
>> + 0, 0, 0,
>
> It's hard to interpret this like this. memset(0) and then writing the
> fiels would make the code smaller and easier to read.
>
> You should ensure that cStencilBits is not zero, otherwise you might not
> get a stencil buffer, which will cause problems.
I now see this is only used for initialization. So I suppose it doesn't
really matter.
Jose
>
> See
> https://urldefense.proofpoint.com/v1/url?u=https://github.com/apitrace/apitrace/blob/master/retrace/glws_wgl.cpp%23L218&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=NMr9uy2iTjWVixC0wOcYCWEIYhfo80qKwRgdodpoDzA%3D%0A&m=tyTB22tb8qXxlAjtC9yppkPcm8bpett7KDrGHrMprfc%3D%0A&s=b8108e8bcaaa6738b851b7822226ed1d5baf2a4c13aef3362da9e1801016fda7
> for reference.
>
>> + };
>> + bool ok;
>> +
>> + dpy->pixel_format = ChoosePixelFormat(dpy->hDC, &pfd);
>> + if (!dpy->pixel_format)
>> + return false;
>> +
>> + ok = SetPixelFormat(dpy->hDC, dpy->pixel_format, &pfd);
>> + if (!ok)
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +static bool
>> +wgl_display_hardware_render(struct wgl_display *dpy)
>> +{
>> +#ifndef GL_RENDERER
>> +#define GL_RENDERER 0x1F01
>> +#endif
>> + typedef unsigned int GLenum;
>> + typedef unsigned char GLubyte;
>> + typedef const GLubyte * (__stdcall *PFNGLGETSTRINGPROC)(GLenum
>> name);
>> +
>> + PFNGLGETSTRINGPROC glGetString_func;
>> + const GLubyte *gl_renderer;
>> + bool ok;
>> +
>> + glGetString_func = wgl_dl_sym(dpy->wcore.platform,
>> WAFFLE_DL_OPENGL, "glGetString");
>> + if (!glGetString_func)
>> + return false;
>> +
>> + ok = wglMakeCurrent(dpy->hDC, dpy->hglrc);
>> + if (!ok)
>> + return false;
>> +
>> + gl_renderer = glGetString_func(GL_RENDERER);
>> + ok = wglMakeCurrent(NULL, NULL);
>> + if (!ok)
>> + return false;
>> +
>> + // Bail out if we cannot retrieve the renderer string or if we're
>> using GDI
>> + if (!gl_renderer || strcasecmp((const char *)gl_renderer, "GDI
>> Generic") == 0)
>> + return false;
>> +
>> + return true;
>> +}
>>
>> struct wcore_display*
>> wgl_display_connect(struct wcore_platform *wc_plat,
>> @@ -60,6 +161,22 @@ wgl_display_connect(struct wcore_platform *wc_plat,
>> if (!ok)
>> goto error;
>>
>> + ok = wgl_display_create_window(wgl_platform(wc_plat), self);
>> + if (!ok)
>> + goto error;
>> +
>> + ok = wgl_display_choose_config(self);
>> + if (!ok)
>> + goto error;
>> +
>> + self->hglrc = wglCreateContext(self->hDC);
>> + if (!self->hglrc)
>> + goto error;
>> +
>> + ok = wgl_display_hardware_render(self);
>> + if (!ok)
>> + goto error;
>> +
>> return &self->wcore;
>>
>> error:
>> diff --git a/src/waffle/wgl/wgl_display.h b/src/waffle/wgl/wgl_display.h
>> index 262ab18..6a2b6c7 100644
>> --- a/src/waffle/wgl/wgl_display.h
>> +++ b/src/waffle/wgl/wgl_display.h
>> @@ -35,6 +35,11 @@ struct wcore_platform;
>>
>> struct wgl_display {
>> struct wcore_display wcore;
>> +
>> + HWND hWnd;
>> + HDC hDC;
>> + int pixel_format;
>> + HGLRC hglrc;
>> };
>>
>> DEFINE_CONTAINER_CAST_FUNC(wgl_display,
>> diff --git a/src/waffle/wgl/wgl_platform.c
>> b/src/waffle/wgl/wgl_platform.c
>> index 6c31c7e..2f88aff 100644
>> --- a/src/waffle/wgl/wgl_platform.c
>> +++ b/src/waffle/wgl/wgl_platform.c
>> @@ -36,6 +36,8 @@
>>
>> static const struct wcore_platform_vtbl wgl_platform_vtbl;
>>
>> +const char* wfl_class_name = "waffle";
>> +
>> static bool
>> wgl_platform_destroy(struct wcore_platform *wc_self)
>> {
>> @@ -48,11 +50,45 @@ wgl_platform_destroy(struct wcore_platform *wc_self)
>> if (self->dl_gl)
>> ok &= wgl_dl_close(wc_self);
>>
>> + if (self->class_name)
>> + ok &= UnregisterClass(self->class_name, GetModuleHandle(NULL));
>> +
>> ok &= wcore_platform_teardown(wc_self);
>> free(self);
>> return ok;
>> }
>>
>> +static bool
>> +wgl_platform_register_class(const char* class_name)
>> +{
>> + WNDCLASS wc;
>> + bool ok;
>> +
>> + memset(&wc, 0, sizeof(wc));
>> + wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
>> + // XXX: Use a non-default window_proc ?
>> + wc.lpfnWndProc = DefWindowProc;
>> + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
>> + wc.hInstance = GetModuleHandle(NULL);
>> + wc.hCursor = LoadCursor(NULL, IDC_ARROW);
>> + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);;
>> + wc.lpszClassName = class_name;
>> +
>> + ok = !!RegisterClass(&wc);
>> +
>> + if (!ok) {
>> + int error = GetLastError();
>> +
>> + if (error) {
>> + wcore_errorf(WAFFLE_ERROR_UNKNOWN,
>> + "RegisterClass() failed: %d",
>> + error);
>> + }
>> + }
>> +
>> + return ok;
>> +}
>> +
>> struct wcore_platform*
>> wgl_platform_create(void)
>> {
>> @@ -67,6 +103,11 @@ wgl_platform_create(void)
>> if (!ok)
>> goto error;
>>
>> + ok = wgl_platform_register_class(wfl_class_name);
>> + if (!ok)
>> + goto error;
>> + self->class_name = wfl_class_name;
>> +
>> self->wcore.vtbl = &wgl_platform_vtbl;
>> return &self->wcore;
>>
>> diff --git a/src/waffle/wgl/wgl_platform.h
>> b/src/waffle/wgl/wgl_platform.h
>> index 9aa3611..9223aea 100644
>> --- a/src/waffle/wgl/wgl_platform.h
>> +++ b/src/waffle/wgl/wgl_platform.h
>> @@ -38,6 +38,9 @@ struct wgl_platform {
>>
>> /// @brief The OpenGL library obtained with LoadLibraryA().
>> void *dl_gl;
>> +
>> + /// @brief The class name of the waffle windows.
>> + const char *class_name;
>> };
>>
>> DEFINE_CONTAINER_CAST_FUNC(wgl_platform,
>>
>
> _______________________________________________
> waffle mailing list
> waffle at lists.freedesktop.org
> https://urldefense.proofpoint.com/v1/url?u=http://lists.freedesktop.org/mailman/listinfo/waffle&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=NMr9uy2iTjWVixC0wOcYCWEIYhfo80qKwRgdodpoDzA%3D%0A&m=tyTB22tb8qXxlAjtC9yppkPcm8bpett7KDrGHrMprfc%3D%0A&s=22332a643f8479c61395dfdafa03391e7e2c9187a3178dbc7178033741889717
>
More information about the waffle
mailing list