[waffle] [PATCH 06/18] wgl: implement display management

Jose Fonseca jfonseca at vmware.com
Wed Jul 23 08:25:43 PDT 2014


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.


See 
https://github.com/apitrace/apitrace/blob/master/retrace/glws_wgl.cpp#L218 
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,
>



More information about the waffle mailing list