[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