From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winewayland.drv/opengl.c | 103 +++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 8 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index f072b8063a1..ee2ad362aa6 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -48,6 +48,7 @@ static struct opengl_funcs opengl_funcs; static EGLDisplay egl_display; static char wgl_extensions[4096]; static EGLConfig *egl_configs; +static struct wgl_pixel_format *wgl_pixel_formats; static int num_egl_configs;
#define USE_GL_FUNC(name) #name, @@ -546,6 +547,7 @@ static BOOL wayland_wglDeleteContext(struct wgl_context *ctx)
static BOOL has_opengl(void);
+/* TODO: We can use the wgl_pixel_formats to implement this, possibly in opengl32 */ static int wayland_wglDescribePixelFormat(HDC hdc, int fmt, UINT size, PIXELFORMATDESCRIPTOR *pfd) { @@ -762,6 +764,12 @@ static BOOL wayland_wglSwapIntervalEXT(int interval) return ret; }
+static UINT wayland_get_pixel_formats(const struct wgl_pixel_format **formats) +{ + *formats = wgl_pixel_formats; + return num_egl_configs; +} + static BOOL has_extension(const char *list, const char *ext) { size_t len = strlen(ext); @@ -822,9 +830,75 @@ static BOOL init_opengl_funcs(void) opengl_funcs.ext.p_wglGetSwapIntervalEXT = wayland_wglGetSwapIntervalEXT; opengl_funcs.ext.p_wglSwapIntervalEXT = wayland_wglSwapIntervalEXT;
+ register_extension("WGL_ARB_pixel_format"); + register_extension("WGL_ARB_pixel_format_float"); + register_extension("WGL_ATI_pixel_format_float"); + /* We use the default implementation from opengl32 based on p_get_pixel_formats. + * We still need to mark these as non-NULL so that the extension is detected. */ + opengl_funcs.ext.p_wglChoosePixelFormatARB = (void *)1; + opengl_funcs.ext.p_wglGetPixelFormatAttribivARB = (void *)1; + opengl_funcs.ext.p_wglGetPixelFormatAttribfvARB = (void *)1; + return TRUE; }
+static void convert_egl_to_wgl_format(EGLConfig config, int id, + struct wgl_pixel_format *fmt) +{ + EGLint value; + + fmt->id = id; + fmt->draw_to_window = GL_TRUE; + fmt->acceleration = 2; /* Full acceleration */ + fmt->support_opengl = GL_TRUE; + fmt->double_buffer = GL_TRUE; + +#define SET_ATTRIB(wgl_field, attrib) \ + value = 0; \ + p_eglGetConfigAttrib(egl_display, config, attrib, &value); \ + fmt->wgl_field = value; + +#define SET_ATTRIB_VALUE(wgl_field, attrib, val) \ + value = 0; \ + p_eglGetConfigAttrib(egl_display, config, attrib, &value); \ + fmt->wgl_field = val; + + SET_ATTRIB_VALUE(transparent, EGL_TRANSPARENT_TYPE, (value == EGL_TRANSPARENT_RGB)); + SET_ATTRIB_VALUE(pixel_type, EGL_COLOR_COMPONENT_TYPE_EXT, + (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) ? 3 : 0); + + SET_ATTRIB(color_bits, EGL_BUFFER_SIZE); + SET_ATTRIB(red_bits, EGL_RED_SIZE); + SET_ATTRIB(green_bits, EGL_GREEN_SIZE); + SET_ATTRIB(blue_bits, EGL_BLUE_SIZE); + SET_ATTRIB(alpha_bits, EGL_ALPHA_SIZE); + /* Although we don't get information from EGL about the component shifts + * or the native format, the 0xARGB order is the most common. */ + fmt->blue_shift = 0; + fmt->green_shift = fmt->blue_bits; + fmt->red_shift = fmt->green_bits + fmt->blue_bits; + if (fmt->alpha_bits) + fmt->alpha_shift = fmt->red_bits + fmt->green_bits + fmt->blue_bits; + else + fmt->alpha_shift = 0; + + SET_ATTRIB(depth_bits, EGL_DEPTH_SIZE); + SET_ATTRIB(stencil_bits, EGL_STENCIL_SIZE); + SET_ATTRIB(transparent_red_value, EGL_TRANSPARENT_RED_VALUE); + SET_ATTRIB(transparent_green_value, EGL_TRANSPARENT_GREEN_VALUE); + SET_ATTRIB(transparent_blue_value, EGL_TRANSPARENT_BLUE_VALUE); + SET_ATTRIB(sample_buffers, EGL_SAMPLE_BUFFERS); + SET_ATTRIB(samples, EGL_SAMPLES); + SET_ATTRIB(bind_to_texture_rgb, EGL_BIND_TO_TEXTURE_RGB); + SET_ATTRIB(bind_to_texture_rgba, EGL_BIND_TO_TEXTURE_RGBA); + /* Rectangle? */ + + /* TODO: Advertise SRGB and support it for surface creation*/ + +#undef SET_ATTRIB +#undef SET_ATTRIB_VALUE +} + static BOOL init_egl_configs(void) { EGLint i; @@ -852,23 +926,35 @@ static BOOL init_egl_configs(void) return FALSE; }
- if (TRACE_ON(waylanddrv)) + if (!(wgl_pixel_formats = calloc(1, num_egl_configs * sizeof(*wgl_pixel_formats)))) + { + ERR("Failed to allocate memory for wgl_pixel_formats\n"); + free(egl_configs); + egl_configs = NULL; + return FALSE; + } + + for (i = 0; i < num_egl_configs; i++) { - for (i = 0; i < num_egl_configs; i++) + convert_egl_to_wgl_format(egl_configs[i], i + 1, &wgl_pixel_formats[i]); + + if (TRACE_ON(waylanddrv)) { EGLint id, type, visual_id, native, render, color, r, g, b, a, d, s; + p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_NATIVE_VISUAL_ID, &visual_id); p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SURFACE_TYPE, &type); p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_RENDERABLE_TYPE, &render); p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_CONFIG_ID, &id); p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_NATIVE_RENDERABLE, &native); p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_COLOR_BUFFER_TYPE, &color); - p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_RED_SIZE, &r); - p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_GREEN_SIZE, &g); - p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_BLUE_SIZE, &b); - p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_ALPHA_SIZE, &a); - p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_DEPTH_SIZE, &d); - p_eglGetConfigAttrib(egl_display, egl_configs[i], EGL_STENCIL_SIZE, &s); + r = wgl_pixel_formats[i].red_bits; + g = wgl_pixel_formats[i].green_bits; + b = wgl_pixel_formats[i].blue_bits; + a = wgl_pixel_formats[i].alpha_bits; + d = wgl_pixel_formats[i].depth_bits; + s = wgl_pixel_formats[i].stencil_bits; + TRACE("%u: config %d id %d type %x visual %d native %d render %x " "colortype %d rgba %d,%d,%d,%d depth %u stencil %d\n", num_egl_configs, i, id, type, visual_id, native, render, @@ -986,6 +1072,7 @@ static struct opengl_funcs opengl_funcs = .p_wglSetPixelFormat = wayland_wglSetPixelFormat, .p_wglShareLists = wayland_wglShareLists, .p_wglSwapBuffers = wayland_wglSwapBuffers, + .p_get_pixel_formats = wayland_get_pixel_formats, } };