[PATCH] winemac: Implement the WGL_WINE_query_renderer extension.
Ken Thomases
ken at codeweavers.com
Tue Apr 26 03:29:57 CDT 2016
Signed-off-by: Ken Thomases <ken at codeweavers.com>
---
dlls/winemac.drv/opengl.c | 598 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 598 insertions(+)
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c
index ab79a82..7a2c2a5 100644
--- a/dlls/winemac.drv/opengl.c
+++ b/dlls/winemac.drv/opengl.c
@@ -60,6 +60,7 @@ struct wgl_context
{
struct list entry;
int format;
+ GLint renderer_id;
macdrv_opengl_context context;
CGLContextObj cglcontext;
HWND draw_hwnd;
@@ -301,6 +302,7 @@ static const char* debugstr_attrib(int attrib, int value)
ATTRIB(WGL_PIXEL_TYPE_ARB),
ATTRIB(WGL_RED_BITS_ARB),
ATTRIB(WGL_RED_SHIFT_ARB),
+ ATTRIB(WGL_RENDERER_ID_WINE),
ATTRIB(WGL_SAMPLE_BUFFERS_ARB),
ATTRIB(WGL_SAMPLES_ARB),
ATTRIB(WGL_SHARE_ACCUM_ARB),
@@ -372,6 +374,31 @@ static const char* debugstr_attrib(int attrib, int value)
}
+/**********************************************************************
+ * active_displays_mask
+ */
+static CGOpenGLDisplayMask active_displays_mask(void)
+{
+ CGError err;
+ CGDirectDisplayID displays[32];
+ uint32_t count, i;
+ CGOpenGLDisplayMask mask;
+
+ err = CGGetActiveDisplayList(sizeof(displays) / sizeof(displays[0]), displays, &count);
+ if (err != kCGErrorSuccess)
+ {
+ displays[0] = CGMainDisplayID();
+ count = 1;
+ }
+
+ mask = 0;
+ for (i = 0; i < count; i++)
+ mask |= CGDisplayIDToOpenGLDisplayMask(displays[i]);
+
+ return mask;
+}
+
+
static BOOL get_renderer_property(CGLRendererInfoObj renderer_info, GLint renderer_index,
CGLRendererProperty property, GLint *value)
{
@@ -1386,6 +1413,14 @@ static BOOL create_context(struct wgl_context *context, CGLContextObj share, uns
attribs[n++] = kCGLPFAMinimumPolicy;
attribs[n++] = kCGLPFAClosestPolicy;
+ if (context->renderer_id)
+ {
+ attribs[n++] = kCGLPFARendererID;
+ attribs[n++] = context->renderer_id;
+ attribs[n++] = kCGLPFASingleRenderer;
+ attribs[n++] = kCGLPFANoRecovery;
+ }
+
if (pf->accelerated)
{
attribs[n++] = kCGLPFAAccelerated;
@@ -1767,6 +1802,301 @@ static void sync_swap_interval(struct wgl_context *context)
/**********************************************************************
+ * get_iokit_display_property
+ */
+static BOOL get_iokit_display_property(CGLRendererInfoObj renderer_info, GLint renderer, CFStringRef property, GLuint* value)
+{
+ GLint accelerated;
+ GLint display_mask;
+ int i;
+
+ if (!get_renderer_property(renderer_info, renderer, kCGLRPAccelerated, &accelerated) || !accelerated)
+ {
+ TRACE("assuming unaccelerated renderers don't have IOKit properties\n");
+ return FALSE;
+ }
+
+ if (!get_renderer_property(renderer_info, renderer, kCGLRPDisplayMask, &display_mask))
+ {
+ WARN("failed to get kCGLRPDisplayMask\n");
+ return FALSE;
+ }
+
+ for (i = 0; i < sizeof(GLint) * 8; i++)
+ {
+ GLint this_display_mask = (GLint)(1U << i);
+ if (this_display_mask & display_mask)
+ {
+ CGDirectDisplayID display_id = CGOpenGLDisplayMaskToDisplayID(this_display_mask);
+ io_service_t service;
+ CFDataRef data;
+ uint32_t prop_value;
+
+ if (!display_id)
+ continue;
+ service = CGDisplayIOServicePort(display_id);
+ if (!service)
+ {
+ WARN("CGDisplayIOServicePort(%u) failed\n", display_id);
+ continue;
+ }
+
+ data = IORegistryEntrySearchCFProperty(service, kIOServicePlane, property, NULL,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (!data)
+ {
+ WARN("IORegistryEntrySearchCFProperty(%s) failed for display %u\n", debugstr_cf(property), display_id);
+ continue;
+ }
+ if (CFDataGetLength(data) != sizeof(prop_value))
+ {
+ WARN("%s data for display %u has unexpected length %llu\n", debugstr_cf(property), display_id,
+ (unsigned long long)CFDataGetLength(data));
+ CFRelease(data);
+ continue;
+ }
+
+ CFDataGetBytes(data, CFRangeMake(0, sizeof(prop_value)), (UInt8*)&prop_value);
+ CFRelease(data);
+ *value = prop_value;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**********************************************************************
+ * create_pixel_format_for_renderer
+ *
+ * Helper for macdrv_wglQueryRendererIntegerWINE(). Caller is
+ * responsible for releasing the pixel format object.
+ */
+static CGLPixelFormatObj create_pixel_format_for_renderer(CGLRendererInfoObj renderer_info, GLint renderer, BOOL core)
+{
+ GLint renderer_id;
+ CGLPixelFormatAttribute attrs[] = {
+ kCGLPFARendererID, 0,
+ kCGLPFASingleRenderer,
+#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)(core ? kCGLOGLPVersion_3_2_Core : kCGLOGLPVersion_Legacy),
+#endif
+ 0
+ };
+ CGError err;
+ CGLPixelFormatObj pixel_format;
+ GLint virtual_screens;
+
+#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+ if (core)
+ return NULL;
+#endif
+
+ if (!get_renderer_property(renderer_info, renderer, kCGLRPRendererID, &renderer_id))
+ return NULL;
+
+ attrs[1] = renderer_id;
+ err = CGLChoosePixelFormat(attrs, &pixel_format, &virtual_screens);
+ if (err != kCGLNoError)
+ pixel_format = NULL;
+ return pixel_format;
+}
+
+
+/**********************************************************************
+ * map_renderer_index
+ *
+ * We can't create pixel formats for all renderers listed. For example,
+ * in a dual-GPU system, the integrated GPU is typically unavailable
+ * when the discrete GPU is active.
+ *
+ * This function conceptually creates a list of "good" renderers from the
+ * list of all renderers. It treats the input "renderer" parameter as an
+ * index into that list of good renderers and returns the corresponding
+ * index into the list of all renderers.
+ */
+static GLint map_renderer_index(CGLRendererInfoObj renderer_info, GLint renderer_count, GLint renderer)
+{
+ GLint good_count, i;
+
+ good_count = 0;
+ for (i = 0; i < renderer_count; i++)
+ {
+ CGLPixelFormatObj pix = create_pixel_format_for_renderer(renderer_info, i, FALSE);
+ if (pix)
+ {
+ CGLReleasePixelFormat(pix);
+ good_count++;
+ if (good_count > renderer)
+ break;
+ }
+ else
+ TRACE("skipping bad renderer %d\n", i);
+ }
+
+ TRACE("mapped requested renderer %d to index %d\n", renderer, i);
+ return i;
+}
+
+
+/**********************************************************************
+ * query_renderer_integer
+ */
+static BOOL query_renderer_integer(CGLRendererInfoObj renderer_info, GLint renderer, GLenum attribute, GLuint *value)
+{
+ BOOL ret = FALSE;
+ CGLError err;
+
+ if (TRACE_ON(wgl))
+ {
+ GLint renderer_id;
+ if (!get_renderer_property(renderer_info, renderer, kCGLRPRendererID, &renderer_id))
+ renderer_id = 0;
+ TRACE("renderer %d (ID 0x%08x) attribute 0x%04x value %p\n", renderer, renderer_id, attribute, value);
+ }
+
+ switch (attribute)
+ {
+ case WGL_RENDERER_ACCELERATED_WINE:
+ if (!get_renderer_property(renderer_info, renderer, kCGLRPAccelerated, (GLint*)value))
+ break;
+ *value = !!*value;
+ ret = TRUE;
+ TRACE("WGL_RENDERER_ACCELERATED_WINE -> %u\n", *value);
+ break;
+
+ case WGL_RENDERER_DEVICE_ID_WINE:
+ ret = get_iokit_display_property(renderer_info, renderer, CFSTR("device-id"), value);
+ if (!ret)
+ {
+ *value = 0xffffffff;
+ ret = TRUE;
+ }
+ TRACE("WGL_RENDERER_DEVICE_ID_WINE -> 0x%04x\n", *value);
+ break;
+
+ case WGL_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_WINE:
+ case WGL_RENDERER_OPENGL_CORE_PROFILE_VERSION_WINE:
+ {
+ BOOL core = (attribute == WGL_RENDERER_OPENGL_CORE_PROFILE_VERSION_WINE);
+ CGLPixelFormatObj pixel_format = create_pixel_format_for_renderer(renderer_info, renderer, core);
+
+ if (pixel_format)
+ {
+ CGLContextObj context, old_context;
+
+ err = CGLCreateContext(pixel_format, NULL, &context);
+ CGLReleasePixelFormat(pixel_format);
+ if (err == kCGLNoError && context)
+ {
+ old_context = CGLGetCurrentContext();
+ err = CGLSetCurrentContext(context);
+ if (err == kCGLNoError)
+ {
+ const char* version = (const char*)opengl_funcs.gl.p_glGetString(GL_VERSION);
+ unsigned int major, minor;
+
+ if (sscanf(version, "%u.%u", &major, &minor) == 2)
+ {
+ value[0] = major;
+ value[1] = minor;
+ ret = TRUE;
+ }
+ CGLSetCurrentContext(old_context);
+ }
+ else
+ WARN("CGLSetCurrentContext failed: %d %s\n", err, CGLErrorString(err));
+ CGLReleaseContext(context);
+ }
+ else
+ WARN("CGLCreateContext failed: %d %s\n", err, CGLErrorString(err));
+ }
+
+ if (!ret)
+ {
+ value[0] = value[1] = 0;
+ ret = TRUE;
+ }
+ TRACE("%s -> %u.%u\n", core ? "WGL_RENDERER_OPENGL_CORE_PROFILE_VERSION_WINE" :
+ "WGL_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_WINE", value[0], value[1]);
+ break;
+ }
+
+ case WGL_RENDERER_PREFERRED_PROFILE_WINE:
+ {
+ CGLPixelFormatObj pixel_format = create_pixel_format_for_renderer(renderer_info, renderer, TRUE);
+
+ if (pixel_format)
+ {
+ CGLReleasePixelFormat(pixel_format);
+ *value = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ TRACE("WGL_RENDERER_PREFERRED_PROFILE_WINE -> WGL_CONTEXT_CORE_PROFILE_BIT_ARB (0x%04x)\n", *value);
+ }
+ else
+ {
+ *value = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ TRACE("WGL_RENDERER_PREFERRED_PROFILE_WINE -> WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB (0x%04x)\n", *value);
+ }
+ ret = TRUE;
+ break;
+ }
+
+ case WGL_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_WINE:
+ /* FIXME: not sure what this means */
+ *value = 0;
+ ret = TRUE;
+ TRACE("WGL_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_WINE -> %u\n", *value);
+ break;
+
+ case WGL_RENDERER_VENDOR_ID_WINE:
+ ret = get_iokit_display_property(renderer_info, renderer, CFSTR("vendor-id"), value);
+ if (!ret)
+ {
+ *value = 0xffffffff;
+ ret = TRUE;
+ }
+ TRACE("WGL_RENDERER_VENDOR_ID_WINE -> 0x%04x\n", *value);
+ break;
+
+ case WGL_RENDERER_VERSION_WINE:
+ /* FIXME: anything better we can return? */
+ value[0] = 1;
+ value[1] = value[2] = 0;
+ ret = TRUE;
+ TRACE("WGL_RENDERER_VERSION_WINE -> %u.%u.%u\n", value[0], value[1], value[2]);
+ break;
+
+ case WGL_RENDERER_VIDEO_MEMORY_WINE:
+#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ err = CGLDescribeRenderer(renderer_info, renderer, kCGLRPVideoMemoryMegabytes, (GLint*)value);
+ if (err == kCGLNoError)
+ {
+ ret = TRUE;
+ TRACE("WGL_RENDERER_VIDEO_MEMORY_WINE -> %uMB\n", *value);
+ break;
+ }
+ if (err != kCGLBadProperty)
+ WARN("CGLDescribeRenderer(kCGLRPVideoMemoryMegabytes) failed: %d %s\n", err, CGLErrorString(err));
+#endif
+ if (get_renderer_property(renderer_info, renderer, kCGLRPVideoMemory, (GLint*)value))
+ *value /= 1024 * 1024;
+ else
+ *value = 0;
+ ret = TRUE;
+ TRACE("WGL_RENDERER_VIDEO_MEMORY_WINE -> %uMB\n", *value);
+ break;
+
+ default:
+ FIXME("unrecognized attribute 0x%04x\n", attribute);
+ break;
+ }
+
+ return ret;
+}
+
+
+/**********************************************************************
* macdrv_glCopyColorTable
*
* Hook into glCopyColorTable as part of the implementation of
@@ -2329,6 +2659,7 @@ static struct wgl_context *macdrv_wglCreateContextAttribsARB(HDC hdc,
const int *iptr;
int major = 1, minor = 0, profile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB, flags = 0;
BOOL core = FALSE;
+ GLint renderer_id = 0;
TRACE("hdc %p, share_context %p, attrib_list %p\n", hdc, share_context, attrib_list);
@@ -2380,6 +2711,50 @@ static struct wgl_context *macdrv_wglCreateContextAttribsARB(HDC hdc,
profile = value;
break;
+ case WGL_RENDERER_ID_WINE:
+ {
+ CGLError err;
+ CGLRendererInfoObj renderer_info;
+ GLint renderer_count, temp;
+
+ err = CGLQueryRendererInfo(active_displays_mask(), &renderer_info, &renderer_count);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLQueryRendererInfo failed: %d %s\n", err, CGLErrorString(err));
+ SetLastError(ERROR_GEN_FAILURE);
+ return NULL;
+ }
+
+ value = map_renderer_index(renderer_info, renderer_count, value);
+
+ if (value >= renderer_count)
+ {
+ WARN("WGL_RENDERER_ID_WINE renderer %d exceeds count (%d)\n", value, renderer_count);
+ CGLDestroyRendererInfo(renderer_info);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if (!get_renderer_property(renderer_info, value, kCGLRPRendererID, &temp))
+ {
+ WARN("WGL_RENDERER_ID_WINE failed to get ID of renderer %d\n", value);
+ CGLDestroyRendererInfo(renderer_info);
+ SetLastError(ERROR_GEN_FAILURE);
+ return NULL;
+ }
+
+ CGLDestroyRendererInfo(renderer_info);
+
+ if (renderer_id && temp != renderer_id)
+ {
+ WARN("WGL_RENDERER_ID_WINE requested two different renderers (0x%08x vs. 0x%08x)\n", renderer_id, temp);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+ renderer_id = temp;
+ break;
+ }
+
default:
WARN("Unknown attribute %s.\n", debugstr_attrib(attr, value));
SetLastError(ERROR_INVALID_PARAMETER);
@@ -2435,6 +2810,7 @@ static struct wgl_context *macdrv_wglCreateContextAttribsARB(HDC hdc,
if (!(context = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context)))) return NULL;
context->format = format;
+ context->renderer_id = renderer_id;
if (!create_context(context, share_context ? share_context->cglcontext : NULL, major))
{
HeapFree(GetProcessHeap(), 0, context);
@@ -3155,6 +3531,116 @@ static BOOL macdrv_wglMakeContextCurrentARB(HDC draw_hdc, HDC read_hdc, struct w
/**********************************************************************
+ * macdrv_wglQueryCurrentRendererIntegerWINE
+ *
+ * WGL_WINE_query_renderer: wglQueryCurrentRendererIntegerWINE
+ */
+static BOOL macdrv_wglQueryCurrentRendererIntegerWINE(GLenum attribute, GLuint *value)
+{
+ BOOL ret = FALSE;
+ struct wgl_context *context = NtCurrentTeb()->glContext;
+ CGLPixelFormatObj pixel_format;
+ CGLError err;
+ GLint virtual_screen;
+ GLint display_mask;
+ GLint pf_renderer_id;
+ CGLRendererInfoObj renderer_info;
+ GLint renderer_count;
+ GLint renderer;
+
+ TRACE("context %p/%p/%p attribute 0x%04x value %p\n", context, (context ? context->context : NULL),
+ (context ? context->cglcontext : NULL), attribute, value);
+
+ pixel_format = CGLGetPixelFormat(context->cglcontext);
+ err = CGLGetVirtualScreen(context->cglcontext, &virtual_screen);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLGetVirtualScreen failed: %d %s\n", err, CGLErrorString(err));
+ return FALSE;
+ }
+
+ err = CGLDescribePixelFormat(pixel_format, virtual_screen, kCGLPFADisplayMask, &display_mask);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLDescribePixelFormat(kCGLPFADisplayMask) failed: %d %s\n", err, CGLErrorString(err));
+ return FALSE;
+ }
+
+ err = CGLDescribePixelFormat(pixel_format, virtual_screen, kCGLPFARendererID, &pf_renderer_id);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLDescribePixelFormat(kCGLPFARendererID) failed: %d %s\n", err, CGLErrorString(err));
+ return FALSE;
+ }
+
+ err = CGLQueryRendererInfo(display_mask, &renderer_info, &renderer_count);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLQueryRendererInfo failed: %d %s\n", err, CGLErrorString(err));
+ return FALSE;
+ }
+
+ for (renderer = 0; renderer < renderer_count; renderer++)
+ {
+ GLint renderer_id;
+
+ if (!get_renderer_property(renderer_info, renderer, kCGLRPRendererID, &renderer_id))
+ continue;
+
+ if (renderer_id == pf_renderer_id)
+ {
+ ret = query_renderer_integer(renderer_info, renderer, attribute, value);
+ break;
+ }
+ }
+
+ if (renderer >= renderer_count)
+ ERR("failed to find renderer ID 0x%08x for display mask 0x%08x\n", pf_renderer_id, display_mask);
+
+ CGLDestroyRendererInfo(renderer_info);
+ return ret;
+}
+
+
+/**********************************************************************
+ * macdrv_wglQueryCurrentRendererStringWINE
+ *
+ * WGL_WINE_query_renderer: wglQueryCurrentRendererStringWINE
+ */
+static const char *macdrv_wglQueryCurrentRendererStringWINE(GLenum attribute)
+{
+ const char* ret = NULL;
+ struct wgl_context *context = NtCurrentTeb()->glContext;
+
+ TRACE("context %p/%p/%p attribute 0x%04x\n", context, (context ? context->context : NULL),
+ (context ? context->cglcontext : NULL), attribute);
+
+ switch (attribute)
+ {
+ case WGL_RENDERER_DEVICE_ID_WINE:
+ {
+ ret = (const char*)opengl_funcs.gl.p_glGetString(GL_RENDERER);
+ TRACE("WGL_RENDERER_DEVICE_ID_WINE -> %s\n", debugstr_a(ret));
+ break;
+ }
+
+ case WGL_RENDERER_VENDOR_ID_WINE:
+ {
+ ret = (const char*)opengl_funcs.gl.p_glGetString(GL_VENDOR);
+ TRACE("WGL_RENDERER_VENDOR_ID_WINE -> %s\n", debugstr_a(ret));
+ break;
+ }
+
+ default:
+ FIXME("unrecognized attribute 0x%04x\n", attribute);
+ break;
+ }
+
+ return ret;
+}
+
+
+/**********************************************************************
* macdrv_wglQueryPbufferARB
*
* WGL_ARB_pbuffer: wglQueryPbufferARB
@@ -3262,6 +3748,112 @@ static BOOL macdrv_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int iAttribut
/**********************************************************************
+ * macdrv_wglQueryRendererIntegerWINE
+ *
+ * WGL_WINE_query_renderer: wglQueryRendererIntegerWINE
+ */
+static BOOL macdrv_wglQueryRendererIntegerWINE(HDC dc, GLint renderer, GLenum attribute, GLuint *value)
+{
+ BOOL ret = FALSE;
+ CGLRendererInfoObj renderer_info;
+ GLint renderer_count;
+ CGLError err;
+
+ TRACE("dc %p renderer %d attribute 0x%04x value %p\n", dc, renderer, attribute, value);
+
+ err = CGLQueryRendererInfo(active_displays_mask(), &renderer_info, &renderer_count);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLQueryRendererInfo failed: %d %s\n", err, CGLErrorString(err));
+ return FALSE;
+ }
+
+ renderer = map_renderer_index(renderer_info, renderer_count, renderer);
+
+ if (renderer < renderer_count)
+ ret = query_renderer_integer(renderer_info, renderer, attribute, value);
+ else
+ TRACE("requested information for renderer %d exceeding count %d\n", renderer, renderer_count);
+
+ CGLDestroyRendererInfo(renderer_info);
+ return ret;
+}
+
+
+/**********************************************************************
+ * macdrv_wglQueryRendererStringWINE
+ *
+ * WGL_WINE_query_renderer: wglQueryRendererStringWINE
+ */
+static const char *macdrv_wglQueryRendererStringWINE(HDC dc, GLint renderer, GLenum attribute)
+{
+ const char* ret = NULL;
+ CGLRendererInfoObj renderer_info;
+ GLint renderer_count;
+ CGLError err;
+
+ TRACE("dc %p renderer %d attribute 0x%04x\n", dc, renderer, attribute);
+
+ err = CGLQueryRendererInfo(active_displays_mask(), &renderer_info, &renderer_count);
+ if (err != kCGLNoError)
+ {
+ WARN("CGLQueryRendererInfo failed: %d %s\n", err, CGLErrorString(err));
+ return FALSE;
+ }
+
+ renderer = map_renderer_index(renderer_info, renderer_count, renderer);
+
+ if (renderer >= renderer_count)
+ {
+ TRACE("requested information for renderer %d exceeding count %d\n", renderer, renderer_count);
+ goto done;
+ }
+
+ switch (attribute)
+ {
+ case WGL_RENDERER_DEVICE_ID_WINE:
+ case WGL_RENDERER_VENDOR_ID_WINE:
+ {
+ BOOL device = (attribute == WGL_RENDERER_DEVICE_ID_WINE);
+ CGLPixelFormatObj pixel_format = create_pixel_format_for_renderer(renderer_info, renderer, TRUE);
+
+ if (!pixel_format)
+ pixel_format = create_pixel_format_for_renderer(renderer_info, renderer, FALSE);
+ if (pixel_format)
+ {
+ CGLContextObj context, old_context;
+
+ err = CGLCreateContext(pixel_format, NULL, &context);
+ CGLReleasePixelFormat(pixel_format);
+ if (err == kCGLNoError && context)
+ {
+ old_context = CGLGetCurrentContext();
+ err = CGLSetCurrentContext(context);
+ if (err == kCGLNoError)
+ {
+ ret = (const char*)opengl_funcs.gl.p_glGetString(device ? GL_RENDERER : GL_VENDOR);
+ CGLSetCurrentContext(old_context);
+ }
+ CGLReleaseContext(context);
+ }
+ }
+
+ TRACE("%s -> %s\n", device ? "WGL_RENDERER_DEVICE_ID_WINE" : "WGL_RENDERER_VENDOR_ID_WINE", debugstr_a(ret));
+ break;
+ }
+
+ default:
+ FIXME("unrecognized attribute 0x%04x\n", attribute);
+ break;
+ }
+
+done:
+ CGLDestroyRendererInfo(renderer_info);
+ return ret;
+}
+
+
+/**********************************************************************
* macdrv_wglReleasePbufferDCARB
*
* WGL_ARB_pbuffer: wglReleasePbufferDCARB
@@ -3549,6 +4141,12 @@ static void load_extensions(void)
*/
register_extension("WGL_WINE_pixel_format_passthrough");
opengl_funcs.ext.p_wglSetPixelFormatWINE = macdrv_wglSetPixelFormatWINE;
+
+ register_extension("WGL_WINE_query_renderer");
+ opengl_funcs.ext.p_wglQueryCurrentRendererIntegerWINE = macdrv_wglQueryCurrentRendererIntegerWINE;
+ opengl_funcs.ext.p_wglQueryCurrentRendererStringWINE = macdrv_wglQueryCurrentRendererStringWINE;
+ opengl_funcs.ext.p_wglQueryRendererIntegerWINE = macdrv_wglQueryRendererIntegerWINE;
+ opengl_funcs.ext.p_wglQueryRendererStringWINE = macdrv_wglQueryRendererStringWINE;
}
--
2.6.0
More information about the wine-patches
mailing list