winemac: Implement the WGL_WINE_query_renderer extension.
Signed-off-by: Ken Thomases <ken@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
dcfd21cfb2
commit
1df961bd3d
|
@ -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;
|
||||
|
@ -1766,6 +1801,425 @@ 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 (CFGetTypeID(data) != CFDataGetTypeID())
|
||||
{
|
||||
WARN("property %s is not a data object: %s\n", debugstr_cf(property), debugstr_cf(data));
|
||||
CFRelease(data);
|
||||
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,
|
||||
0, 0, /* reserve spots for kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core */
|
||||
0
|
||||
};
|
||||
CGError err;
|
||||
CGLPixelFormatObj pixel_format;
|
||||
GLint virtual_screens;
|
||||
|
||||
if (core)
|
||||
{
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
||||
attrs[3] = kCGLPFAOpenGLProfile;
|
||||
attrs[4] = (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core;
|
||||
#else
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* get_gl_string
|
||||
*/
|
||||
static const char* get_gl_string(CGLPixelFormatObj pixel_format, GLenum name)
|
||||
{
|
||||
const char* ret = NULL;
|
||||
CGLContextObj context, old_context;
|
||||
CGLError err;
|
||||
|
||||
err = CGLCreateContext(pixel_format, NULL, &context);
|
||||
if (err == kCGLNoError && context)
|
||||
{
|
||||
old_context = CGLGetCurrentContext();
|
||||
err = CGLSetCurrentContext(context);
|
||||
if (err == kCGLNoError)
|
||||
{
|
||||
ret = (const char*)opengl_funcs.gl.p_glGetString(name);
|
||||
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));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* get_fallback_renderer_version
|
||||
*/
|
||||
static void get_fallback_renderer_version(GLuint *value)
|
||||
{
|
||||
BOOL got_it = FALSE;
|
||||
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/System/Library/Frameworks/OpenGL.framework"),
|
||||
kCFURLPOSIXPathStyle, TRUE);
|
||||
if (url)
|
||||
{
|
||||
CFBundleRef bundle = CFBundleCreate(NULL, url);
|
||||
CFRelease(url);
|
||||
if (bundle)
|
||||
{
|
||||
CFStringRef version = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
|
||||
if (version && CFGetTypeID(version) == CFStringGetTypeID())
|
||||
{
|
||||
size_t len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(version), kCFStringEncodingUTF8);
|
||||
char* buf = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (buf && CFStringGetCString(version, buf, len, kCFStringEncodingUTF8))
|
||||
{
|
||||
unsigned int major, minor, bugfix;
|
||||
int count = sscanf(buf, "%u.%u.%u", &major, &minor, &bugfix);
|
||||
if (count >= 2)
|
||||
{
|
||||
value[0] = major;
|
||||
value[1] = minor;
|
||||
if (count == 3)
|
||||
value[2] = bugfix;
|
||||
else
|
||||
value[2] = 0;
|
||||
got_it = TRUE;
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
}
|
||||
CFRelease(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
if (!got_it)
|
||||
{
|
||||
/* Use the version of the OpenGL framework from OS X 10.6, which is the
|
||||
earliest version that the Mac driver supports. */
|
||||
value[0] = 1;
|
||||
value[1] = 6;
|
||||
value[2] = 14;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* parse_renderer_version
|
||||
*
|
||||
* Get the renderer version from the OpenGL version string. Assumes
|
||||
* the string is of the form
|
||||
* <GL major>.<GL minor>[.<GL bugfix>] <vendor>-<major>.<minor>[.<bugfix>]
|
||||
* where major, minor, and bugfix are what we're interested in. This
|
||||
* form for the vendor specific information is not generally applicable,
|
||||
* but seems reliable on OS X.
|
||||
*/
|
||||
static BOOL parse_renderer_version(const char* version, GLuint *value)
|
||||
{
|
||||
const char* p = strchr(version, ' ');
|
||||
int count;
|
||||
unsigned int major, minor, bugfix;
|
||||
|
||||
if (p) p = strchr(p + 1, '-');
|
||||
if (!p) return FALSE;
|
||||
|
||||
count = sscanf(p + 1, "%u.%u.%u", &major, &minor, &bugfix);
|
||||
if (count < 2)
|
||||
return FALSE;
|
||||
|
||||
value[0] = major;
|
||||
value[1] = minor;
|
||||
if (count == 3)
|
||||
value[2] = bugfix;
|
||||
else
|
||||
value[2] = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 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)
|
||||
{
|
||||
const char* version = get_gl_string(pixel_format, GL_VERSION);
|
||||
|
||||
CGLReleasePixelFormat(pixel_format);
|
||||
if (version)
|
||||
{
|
||||
unsigned int major, minor;
|
||||
|
||||
if (sscanf(version, "%u.%u", &major, &minor) == 2)
|
||||
{
|
||||
value[0] = major;
|
||||
value[1] = minor;
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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: no API to query this */
|
||||
*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:
|
||||
{
|
||||
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)
|
||||
{
|
||||
const char* version = get_gl_string(pixel_format, GL_VERSION);
|
||||
|
||||
CGLReleasePixelFormat(pixel_format);
|
||||
if (version)
|
||||
ret = parse_renderer_version(version, value);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
get_fallback_renderer_version(value);
|
||||
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 && err != kCGLBadProperty)
|
||||
WARN("CGLDescribeRenderer(kCGLRPVideoMemoryMegabytes) failed: %d %s\n", err, CGLErrorString(err));
|
||||
if (err != kCGLNoError)
|
||||
#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
|
||||
*
|
||||
|
@ -2329,6 +2783,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 +2835,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 +2934,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);
|
||||
|
@ -3154,6 +3654,124 @@ 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);
|
||||
|
||||
if (attribute == WGL_RENDERER_VERSION_WINE)
|
||||
{
|
||||
if (!parse_renderer_version((const char*)opengl_funcs.gl.p_glGetString(GL_VERSION), value))
|
||||
get_fallback_renderer_version(value);
|
||||
TRACE("WGL_RENDERER_VERSION_WINE -> %u.%u.%u\n", value[0], value[1], value[2]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
|
@ -3261,6 +3879,99 @@ 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)
|
||||
{
|
||||
ret = get_gl_string(pixel_format, device ? GL_RENDERER : GL_VENDOR);
|
||||
CGLReleasePixelFormat(pixel_format);
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
|
@ -3549,6 +4260,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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue