This commit is contained in:
elwrcl committed 2026-06-06 13:25:15 +03:00
1 parent 04d4dc8b09
commit 818cab85dc
12511 files changed
+6156641

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
AppleSGLX Release Notes
o OpenGL Support
AppleSGLX supports the same version of OpenGL as Leopard (OpenGL 2.1).
Many extensions from the OpenGL framework are now builtin.
This adds support for GLSL, and a variety of other features.
o Thread Support
Thread support has been improved since the libGL in XQuartz 2.3.2.1.
o GLX 1.4 Support
The GLX 1.3 and 1.4 functions should all work with a few exceptions
as outlined in this document.
o glXMakeContextCurrent (a GLX 1.3 feature)
glXMakeContextCurrent should work with the readable drawable. The
OpenGL functions: glReadPixels, glCopyPixels, and glCopyColorTable,
should use the readable drawable if it's different than the rendering
drawable.
o glXGetProcAddress (a GLX 1.4 feature and ARB extension)
glXGetProcAddress should work and allow getting the address of any
extension functions you may need from the X11 libGL, or OpenGL framework
libGL. Previous versions of the X11 libGL didn't allow getting the newer
OpenGL framework addresses.
o GLXPixmaps
New support for GLXPixmaps works well with mixed X11 and OpenGL drawing
operations. You can create them using glXCreateGLXPixmap or
glXCreatePixmap.
o GLXPbuffers
Support for GLXPbuffers has been added. These are drawables that are
not possible to render to with X11, which is allowed by the spec.
A GLXPbuffer will never generate a clobber event, however
glXSelectEvent and glXGetSelectedEvent should operate normally.
Clobber events are not generated due to low-level architectural
differences. The contents of your pbuffers will not be clobbered.
o Shared Contexts
Due to basic low-level architectural differences the usage of shared
contexts requires a similar visual or GLXFBConfig be used in the
creation of a shared context. It's best if you specify the same
visual. This is due to a CGL design difference, and not something
that is easily worked around. UPDATE: some changes made seem to
help resolve this issue in many cases, so you may be able to use a
shared context without this restriction.
o Indirect
The X server supports indirect fairly well, so OpenGL applications
can be run remotely and displayed by XQuartz. This means you can run
applications from a remote host on an XQuartz X server.
AppleSGLX does not support indirect rendering. Any indirect context
created will appear to glXIsDirect as an indirect context, but it
does not actually support indirect rendering to a remote X server.
AppleSGLX supports GLXPixmaps and GLXPbuffers with direct and indirect
contexts, though they are all direct contexts by definition (see above).
+26
View File
@@ -0,0 +1,26 @@
Test shared contexts!
Go over every glxcmd in glxcmds.c and make sure we have them working.
Verify the XError behavior of GLXPixmap support functions.
Test GLXPixmap support with various pixmap depths.
Test GLXPixmap support with invalid pixmaps (to stress the protocol code).
-- Feb 10, 2009
Test glXCopyContext.
-- Dec 12 2008
TEST glXCopyContext needs some work and additional code in apple_glx.c.
----
Make sure we report the proper list of GLX extensions available. Apple direct may not support some
that Mesa does, and vice-versa.
Modify create_destroy_context and create a new test called create_destroy_context_thread_race.
Where 2 threads are doing the same sort of path of create and destroy. The locking should protect
us there, but we need to verify nothing goes wrong.
+128
View File
@@ -0,0 +1,128 @@
/*
Copyright (c) 2008 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "apple_cgl.h"
#include "apple_glx.h"
#include "util/os_misc.h"
#ifndef OPENGL_FRAMEWORK_PATH
#define OPENGL_FRAMEWORK_PATH "/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL"
#endif
static void *dl_handle = NULL;
struct apple_cgl_api apple_cgl;
static bool initialized = false;
static void *
sym(void *h, const char *name)
{
void *s;
s = dlsym(h, name);
if (NULL == s) {
fprintf(stderr, "error: %s\n", dlerror());
abort();
}
return s;
}
void
apple_cgl_init(void)
{
void *h;
const char *opengl_framework_path;
if (initialized)
return;
opengl_framework_path = os_get_option("OPENGL_FRAMEWORK_PATH");
if (!opengl_framework_path) {
opengl_framework_path = OPENGL_FRAMEWORK_PATH;
}
(void) dlerror(); /*drain dlerror */
h = dlopen(opengl_framework_path, RTLD_NOW);
if (NULL == h) {
fprintf(stderr, "error: unable to dlopen %s : %s\n",
opengl_framework_path, dlerror());
abort();
}
dl_handle = h;
apple_cgl.get_version = sym(h, "CGLGetVersion");
apple_cgl.get_version(&apple_cgl.version_major, &apple_cgl.version_minor);
apple_glx_diagnostic("CGL major %d minor %d\n", apple_cgl.version_major, apple_cgl.version_minor);
if (1 != apple_cgl.version_major) {
fprintf(stderr, "WARNING: the CGL major version has changed!\n"
"libGL may be incompatible!\n");
}
apple_cgl.choose_pixel_format = sym(h, "CGLChoosePixelFormat");
apple_cgl.destroy_pixel_format = sym(h, "CGLDestroyPixelFormat");
apple_cgl.clear_drawable = sym(h, "CGLClearDrawable");
apple_cgl.flush_drawable = sym(h, "CGLFlushDrawable");
apple_cgl.create_context = sym(h, "CGLCreateContext");
apple_cgl.destroy_context = sym(h, "CGLDestroyContext");
apple_cgl.set_current_context = sym(h, "CGLSetCurrentContext");
apple_cgl.get_current_context = sym(h, "CGLGetCurrentContext");
apple_cgl.error_string = sym(h, "CGLErrorString");
apple_cgl.set_off_screen = sym(h, "CGLSetOffScreen");
apple_cgl.copy_context = sym(h, "CGLCopyContext");
apple_cgl.create_pbuffer = sym(h, "CGLCreatePBuffer");
apple_cgl.destroy_pbuffer = sym(h, "CGLDestroyPBuffer");
apple_cgl.set_pbuffer = sym(h, "CGLSetPBuffer");
initialized = true;
}
void *
apple_cgl_get_dl_handle(void)
{
return dl_handle;
}
+87
View File
@@ -0,0 +1,87 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#ifndef APPLE_CGL_H
#define APPLE_CGL_H
#include <stdio.h>
#include <OpenGL/CGLCurrent.h>
#include <OpenGL/CGLTypes.h>
#include <OpenGL/OpenGL.h>
/* For GLint and GLsizei on Tiger */
#include <OpenGL/gl.h>
struct apple_cgl_api
{
GLint version_major, version_minor;
void (*get_version) (GLint * version_major, GLint * version_minor);
CGLError(*choose_pixel_format) (const CGLPixelFormatAttribute * attribs,
CGLPixelFormatObj * pix, GLint * npix);
CGLError(*destroy_pixel_format) (CGLPixelFormatObj pix);
CGLError(*clear_drawable) (CGLContextObj ctx);
CGLError(*flush_drawable) (CGLContextObj ctx);
CGLError(*create_context) (CGLPixelFormatObj pix, CGLContextObj share,
CGLContextObj * ctx);
CGLError(*destroy_context) (CGLContextObj pix);
CGLError(*set_current_context) (CGLContextObj ctx);
CGLContextObj(*get_current_context) (void);
const char *(*error_string) (CGLError error);
CGLError(*set_off_screen) (CGLContextObj ctx,
GLsizei width, GLsizei height, GLint rowbytes,
void *baseaddr);
CGLError(*copy_context) (CGLContextObj src, CGLContextObj dst,
GLbitfield mask);
CGLError(*create_pbuffer) (GLsizei width,
GLsizei height,
GLenum target,
GLenum internalFormat,
GLint max_level, CGLPBufferObj * pbuffer);
CGLError(*destroy_pbuffer) (CGLPBufferObj pbuffer);
CGLError(*set_pbuffer) (CGLContextObj ctx,
CGLPBufferObj pbuffer,
GLenum face, GLint level, GLint screen);
};
extern struct apple_cgl_api apple_cgl;
extern void apple_cgl_init(void);
extern void *apple_cgl_get_dl_handle(void);
#endif
+79
View File
@@ -0,0 +1,79 @@
/*
* GLX implementation that uses Apple's OpenGL.framework
*
* Copyright (c) 2007-2011 Apple Inc.
* Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 2002 Greg Parker. All Rights Reserved.
*
* Portions of this file are copied from Mesa's xf86glx.c,
* which contains the following copyright:
*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <GL/gl.h>
#include "glapi.h"
#include "dispatch.h"
#include "apple_glx.h"
#include "apple_xgl_api.h"
#include "apple_cgl.h"
struct _glapi_table * __ogl_framework_api = NULL;
struct _glapi_table * __applegl_api = NULL;
static void _apple_glapi_create_table(void) {
if (__applegl_api)
return;
__ogl_framework_api = _glapi_create_table_from_handle(apple_cgl_get_dl_handle(), "gl");
assert(__ogl_framework_api);
size_t glapi_table_size = _gloffset_COUNT * sizeof(_glapi_proc*);
__applegl_api = malloc(glapi_table_size);
assert(__applegl_api);
memcpy(__applegl_api, __ogl_framework_api, glapi_table_size);
_glapi_table_patch(__applegl_api, "ReadPixels", __applegl_glReadPixels);
_glapi_table_patch(__applegl_api, "CopyPixels", __applegl_glCopyPixels);
_glapi_table_patch(__applegl_api, "DrawBuffers", __applegl_glDrawBuffer);
_glapi_table_patch(__applegl_api, "Viewport", __applegl_glViewport);
}
void apple_mesa_glapi_set_dispatch(void) {
_apple_glapi_create_table();
_mesa_glapi_set_dispatch(__applegl_api);
}
void apple_glapi_oglfw_viewport_scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
_apple_glapi_create_table();
CALL_Viewport(__ogl_framework_api, (x, y, width, height));
CALL_Scissor(__ogl_framework_api, (x, y, width, height));
}
+146
View File
@@ -0,0 +1,146 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <pthread.h>
#include <inttypes.h>
#include "appledri.h"
#include "apple_glx.h"
#include "apple_glx_context.h"
#include "apple_cgl.h"
static bool initialized = false;
static int dri_event_base = 0;
int
apple_get_dri_event_base(void)
{
if (!initialized) {
fprintf(stderr,
"error: dri_event_base called before apple_init_glx!\n");
abort();
}
return dri_event_base;
}
static void
surface_notify_handler(Display * dpy, unsigned int uid, int kind)
{
switch (kind) {
case AppleDRISurfaceNotifyDestroyed:
apple_glx_diagnostic("%s: surface destroyed %u\n", __func__, uid);
apple_glx_surface_destroy(uid);
break;
case AppleDRISurfaceNotifyChanged:{
int updated;
updated = apple_glx_context_surface_changed(uid, pthread_self());
apple_glx_diagnostic("surface notify updated %d\n", updated);
}
break;
default:
fprintf(stderr, "unhandled kind of event: %d in %s\n", kind, __func__);
}
}
xp_client_id
apple_glx_get_client_id(void)
{
static xp_client_id id;
if (0 == id) {
if ((XP_Success != xp_init(XP_IN_BACKGROUND)) ||
(Success != xp_get_client_id(&id))) {
return 0;
}
}
return id;
}
/* Return true if an error occurred. */
bool
apple_init_glx(Display * dpy)
{
int eventBase, errorBase;
int major, minor, patch;
if (!XAppleDRIQueryExtension(dpy, &eventBase, &errorBase))
return true;
if (!XAppleDRIQueryVersion(dpy, &major, &minor, &patch))
return true;
if (initialized)
return false;
apple_glx_log_init();
apple_glx_log(ASL_LEVEL_INFO, "Initializing libGL.");
apple_cgl_init();
(void) apple_glx_get_client_id();
XAppleDRISetSurfaceNotifyHandler(surface_notify_handler);
/* This should really be per display. */
dri_event_base = eventBase;
initialized = true;
return false;
}
void
apple_glx_swap_buffers(void *ptr)
{
struct apple_glx_context *ac = ptr;
apple_cgl.flush_drawable(ac->context_obj);
}
void
apple_glx_waitx(Display * dpy, void *ptr)
{
struct apple_private_context *ac = ptr;
(void) ac;
glFlush();
glFinish();
XSync(dpy, False);
}
+51
View File
@@ -0,0 +1,51 @@
/*
Copyright (c) 2008 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#ifndef APPLE_GLX_H
#define APPLE_GLX_H
#include <stdbool.h>
#include <GL/gl.h>
#include <X11/Xlib.h>
#define XP_NO_X_HEADERS
#include <Xplugin.h>
#include "apple_glx_log.h"
xp_client_id apple_glx_get_client_id(void);
bool apple_init_glx(Display * dpy);
void apple_glx_swap_buffers(void *ptr);
void apple_glx_waitx(Display * dpy, void *ptr);
int apple_get_dri_event_base(void);
void apple_mesa_glapi_set_dispatch(void);
void apple_glapi_oglfw_viewport_scissor(GLint x, GLint y, GLsizei width, GLsizei height);
#endif
+618
View File
@@ -0,0 +1,618 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
// Get the newer glext.h first
#include <GL/gl.h>
#include <GL/glext.h>
#include <OpenGL/CGLTypes.h>
#include <OpenGL/CGLCurrent.h>
#include <OpenGL/OpenGL.h>
#include "glxclient.h"
#include "apple_glx.h"
#include "apple_glx_context.h"
#include "appledri.h"
#include "apple_visual.h"
#include "apple_cgl.h"
#include "apple_glx_drawable.h"
#include "util/u_debug.h"
static pthread_mutex_t context_lock = PTHREAD_MUTEX_INITIALIZER;
/*
* This should be locked on creation and destruction of the
* apple_glx_contexts.
*
* It's also locked when the surface_notify_handler is searching
* for a uid associated with a surface.
*/
static struct apple_glx_context *context_list = NULL;
/* This guards the context_list above. */
static void
lock_context_list(void)
{
int err;
err = pthread_mutex_lock(&context_lock);
if (err) {
fprintf(stderr, "pthread_mutex_lock failure in %s: %d\n",
__func__, err);
abort();
}
}
static void
unlock_context_list(void)
{
int err;
err = pthread_mutex_unlock(&context_lock);
if (err) {
fprintf(stderr, "pthread_mutex_unlock failure in %s: %d\n",
__func__, err);
abort();
}
}
static bool
is_context_valid(struct apple_glx_context *ac)
{
struct apple_glx_context *i;
lock_context_list();
for (i = context_list; i; i = i->next) {
if (ac == i) {
unlock_context_list();
return true;
}
}
unlock_context_list();
return false;
}
/* This creates an apple_private_context struct.
*
* It's typically called to save the struct in a GLXContext.
*
* This is also where the CGLContextObj is created, and the CGLPixelFormatObj.
*/
bool
apple_glx_create_context(void **ptr, Display * dpy, int screen,
const void *mode, void *sharedContext,
int *errorptr, bool * x11errorptr)
{
struct apple_glx_context *ac;
struct apple_glx_context *sharedac = sharedContext;
CGLError error;
*ptr = NULL;
ac = malloc(sizeof *ac);
if (NULL == ac) {
*errorptr = BadAlloc;
*x11errorptr = true;
return true;
}
if (sharedac && !is_context_valid(sharedac)) {
*errorptr = GLXBadContext;
*x11errorptr = false;
free(ac);
return true;
}
ac->context_obj = NULL;
ac->pixel_format_obj = NULL;
ac->drawable = NULL;
ac->thread_id = pthread_self();
ac->screen = screen;
ac->double_buffered = false;
ac->uses_stereo = false;
ac->need_update = false;
ac->is_current = false;
ac->made_current = false;
ac->last_surface_window = None;
apple_visual_create_pfobj(&ac->pixel_format_obj, mode,
&ac->double_buffered, &ac->uses_stereo,
/*offscreen */ false);
error = apple_cgl.create_context(ac->pixel_format_obj,
sharedac ? sharedac->context_obj : NULL,
&ac->context_obj);
if (error) {
(void) apple_cgl.destroy_pixel_format(ac->pixel_format_obj);
free(ac);
if (kCGLBadMatch == error) {
*errorptr = BadMatch;
*x11errorptr = true;
}
else {
*errorptr = GLXBadContext;
*x11errorptr = false;
}
DebugMessageF("error: %s\n", apple_cgl.error_string(error));
return true;
}
/* The context creation succeeded, so we can link in the new context. */
lock_context_list();
if (context_list)
context_list->previous = ac;
ac->previous = NULL;
ac->next = context_list;
context_list = ac;
*ptr = ac;
apple_glx_diagnostic("%s: ac %p ac->context_obj %p\n",
__func__, (void *) ac, (void *) ac->context_obj);
unlock_context_list();
return false;
}
void
apple_glx_destroy_context(void **ptr, Display * dpy)
{
struct apple_glx_context *ac = *ptr;
if (NULL == ac)
return;
apple_glx_diagnostic("%s: ac %p ac->context_obj %p\n",
__func__, (void *) ac, (void *) ac->context_obj);
if (apple_cgl.get_current_context() == ac->context_obj) {
apple_glx_diagnostic("%s: context ac->context_obj %p "
"is still current!\n", __func__,
(void *) ac->context_obj);
if (apple_cgl.set_current_context(NULL)) {
abort();
}
}
/* Remove ac from the context_list as soon as possible. */
lock_context_list();
if (ac->previous) {
ac->previous->next = ac->next;
}
else {
context_list = ac->next;
}
if (ac->next) {
ac->next->previous = ac->previous;
}
unlock_context_list();
if (apple_cgl.clear_drawable(ac->context_obj)) {
fprintf(stderr, "error: while clearing drawable!\n");
abort();
}
/*
* This potentially causes surface_notify_handler to be called in
* apple_glx.c...
* We can NOT have a lock held at this point. It would result in
* an abort due to an attempted deadlock. This is why we earlier
* removed the ac pointer from the double-linked list.
*/
if (ac->drawable) {
ac->drawable->destroy(ac->drawable);
}
if (apple_cgl.destroy_pixel_format(ac->pixel_format_obj)) {
fprintf(stderr, "error: destroying pixel format in %s\n", __func__);
abort();
}
if (apple_cgl.destroy_context(ac->context_obj)) {
fprintf(stderr, "error: destroying context_obj in %s\n", __func__);
abort();
}
free(ac);
*ptr = NULL;
apple_glx_garbage_collect_drawables(dpy);
}
/* Return true if an error occurred. */
bool
apple_glx_make_current_context(Display * dpy, void *oldptr, void *ptr,
GLXDrawable drawable)
{
struct apple_glx_context *oldac = oldptr;
struct apple_glx_context *ac = ptr;
struct apple_glx_drawable *newagd = NULL;
CGLError cglerr;
bool same_drawable = false;
#if 0
apple_glx_diagnostic("%s: oldac %p ac %p drawable 0x%lx\n",
__func__, (void *) oldac, (void *) ac, drawable);
apple_glx_diagnostic("%s: oldac->context_obj %p ac->context_obj %p\n",
__func__,
(void *) (oldac ? oldac->context_obj : NULL),
(void *) (ac ? ac->context_obj : NULL));
#endif
/* This a common path for GLUT and other apps, so special case it. */
if (ac && ac->drawable && ac->drawable->drawable == drawable) {
same_drawable = true;
if (ac->is_current)
return false;
}
/* Reset the is_current state of the old context, if non-NULL. */
if (oldac && (ac != oldac))
oldac->is_current = false;
if (NULL == ac) {
/*Clear the current context for this thread. */
apple_cgl.set_current_context(NULL);
if (oldac) {
oldac->is_current = false;
if (oldac->drawable) {
oldac->drawable->destroy(oldac->drawable);
oldac->drawable = NULL;
}
/* Invalidate this to prevent surface recreation. */
oldac->last_surface_window = None;
}
return false;
}
if (None == drawable) {
bool error = false;
/* Clear the current drawable for this context_obj. */
if (apple_cgl.set_current_context(ac->context_obj))
error = true;
if (apple_cgl.clear_drawable(ac->context_obj))
error = true;
if (ac->drawable) {
ac->drawable->destroy(ac->drawable);
ac->drawable = NULL;
}
/* Invalidate this to prevent surface recreation. */
ac->last_surface_window = None;
apple_glx_diagnostic("%s: drawable is None, error is: %d\n",
__func__, error);
return error;
}
/* This is an optimisation to avoid searching for the current drawable. */
if (ac->drawable && ac->drawable->drawable == drawable) {
newagd = ac->drawable;
}
else {
/* Find the drawable if possible, and retain a reference to it. */
newagd =
apple_glx_drawable_find(drawable, APPLE_GLX_DRAWABLE_REFERENCE);
}
/*
* Try to destroy the old drawable, so long as the new one
* isn't the old.
*/
if (ac->drawable && !same_drawable) {
ac->drawable->destroy(ac->drawable);
ac->drawable = NULL;
}
if (NULL == newagd) {
if (apple_glx_surface_create(dpy, ac->screen, drawable, &newagd))
return true;
/* The drawable is referenced once by apple_glx_surface_create. */
/*
* FIXME: We actually need 2 references to prevent premature surface
* destruction. The problem is that the surface gets destroyed in
* the case of the context being reused for another window, and
* we then lose the surface contents. Wait for destruction of a
* window to destroy a surface.
*
* Note: this may leave around surfaces we don't want around, if
* say we are using X for raster drawing after OpenGL rendering,
* but it will be compatible with the old libGL's behavior.
*
* Someday the X11 and OpenGL rendering must be unified at some
* layer. I suspect we can do that via shared memory and
* multiple threads in the X server (1 for each context created
* by a client). This would also allow users to render from
* multiple clients to the same OpenGL surface. In fact it could
* all be OpenGL.
*
*/
newagd->reference(newagd);
/* Save the new drawable with the context structure. */
ac->drawable = newagd;
}
else {
/* We are reusing an existing drawable structure. */
if (same_drawable) {
assert(ac->drawable == newagd);
/* The drawable_find above retained a reference for us. */
}
else {
ac->drawable = newagd;
}
}
/*
* Avoid this costly path if this is the same drawable and the
* context is already current.
*/
if (same_drawable && ac->is_current) {
apple_glx_diagnostic("same_drawable and ac->is_current\n");
return false;
}
cglerr = apple_cgl.set_current_context(ac->context_obj);
if (kCGLNoError != cglerr) {
fprintf(stderr, "set current error: %s\n",
apple_cgl.error_string(cglerr));
return true;
}
ac->is_current = true;
assert(NULL != ac->context_obj);
assert(NULL != ac->drawable);
ac->thread_id = pthread_self();
/* This will be set if the pending_destroy code indicates it should be: */
ac->last_surface_window = None;
switch (ac->drawable->type) {
case APPLE_GLX_DRAWABLE_PBUFFER:
case APPLE_GLX_DRAWABLE_SURFACE:
case APPLE_GLX_DRAWABLE_PIXMAP:
if (ac->drawable->callbacks.make_current) {
if (ac->drawable->callbacks.make_current(ac, ac->drawable))
return true;
}
break;
default:
fprintf(stderr, "internal error: invalid drawable type: %d\n",
ac->drawable->type);
abort();
}
return false;
}
bool
apple_glx_is_current_drawable(Display * dpy, void *ptr, GLXDrawable drawable)
{
struct apple_glx_context *ac = ptr;
if (ac->drawable && ac->drawable->drawable == drawable) {
return true;
}
else if (NULL == ac->drawable && None != ac->last_surface_window) {
apple_glx_context_update(dpy, ac);
return (ac->drawable && ac->drawable->drawable == drawable);
}
return false;
}
bool
apple_glx_copy_context(void *currentptr, void *srcptr, void *destptr,
unsigned long mask, int *errorptr, bool * x11errorptr)
{
struct apple_glx_context *src, *dest;
CGLError err;
src = srcptr;
dest = destptr;
if (src->screen != dest->screen) {
*errorptr = BadMatch;
*x11errorptr = true;
return true;
}
if (dest == currentptr || dest->is_current) {
*errorptr = BadAccess;
*x11errorptr = true;
return true;
}
/*
* If srcptr is the current context then we should do an implicit glFlush.
*/
if (currentptr == srcptr)
glFlush();
err = apple_cgl.copy_context(src->context_obj, dest->context_obj,
(GLbitfield) mask);
if (kCGLNoError != err) {
*errorptr = GLXBadContext;
*x11errorptr = false;
return true;
}
return false;
}
/*
* The value returned is the total number of contexts set to update.
* It's meant for debugging/introspection.
*/
int
apple_glx_context_surface_changed(unsigned int uid, pthread_t caller)
{
struct apple_glx_context *ac;
int updated = 0;
lock_context_list();
for (ac = context_list; ac; ac = ac->next) {
if (ac->drawable && APPLE_GLX_DRAWABLE_SURFACE == ac->drawable->type
&& ac->drawable->types.surface.uid == uid) {
if (caller == ac->thread_id) {
apple_glx_diagnostic("caller is the same thread for uid %u\n",
uid);
xp_update_gl_context(ac->context_obj);
}
else {
ac->need_update = true;
++updated;
}
}
}
unlock_context_list();
return updated;
}
void
apple_glx_context_update(Display * dpy, void *ptr)
{
struct apple_glx_context *ac = ptr;
if (NULL == ac->drawable && None != ac->last_surface_window) {
bool failed;
/* Attempt to recreate the surface for a destroyed drawable. */
failed =
apple_glx_make_current_context(dpy, ac, ac, ac->last_surface_window);
apple_glx_diagnostic("%s: surface recreation failed? %s\n", __func__,
failed ? "YES" : "NO");
}
if (ac->need_update) {
xp_update_gl_context(ac->context_obj);
ac->need_update = false;
apple_glx_diagnostic("%s: updating context %p\n", __func__, ptr);
}
if (ac->drawable && APPLE_GLX_DRAWABLE_SURFACE == ac->drawable->type
&& ac->drawable->types.surface.pending_destroy) {
apple_glx_diagnostic("%s: clearing drawable %p\n", __func__, ptr);
apple_cgl.clear_drawable(ac->context_obj);
if (ac->drawable) {
struct apple_glx_drawable *d;
apple_glx_diagnostic("%s: attempting to destroy drawable %p\n",
__func__, ptr);
apple_glx_diagnostic("%s: ac->drawable->drawable is 0x%lx\n",
__func__, ac->drawable->drawable);
d = ac->drawable;
ac->last_surface_window = d->drawable;
ac->drawable = NULL;
/*
* This will destroy the surface drawable if there are
* no references to it.
* It also subtracts 1 from the reference_count.
* If there are references to it, then it's probably made
* current in another context.
*/
d->destroy(d);
}
}
}
bool
apple_glx_context_uses_stereo(void *ptr)
{
struct apple_glx_context *ac = ptr;
return ac->uses_stereo;
}
+93
View File
@@ -0,0 +1,93 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#ifndef APPLE_GLX_CONTEXT_H
#define APPLE_GLX_CONTEXT_H
/* <rdar://problem/6953344> */
#define glTexImage1D glTexImage1D_OSX
#define glTexImage2D glTexImage2D_OSX
#define glTexImage3D glTexImage3D_OSX
#include <OpenGL/CGLTypes.h>
#include <OpenGL/CGLContext.h>
#undef glTexImage1D
#undef glTexImage2D
#undef glTexImage3D
#include <stdbool.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#define XP_NO_X_HEADERS
#include <Xplugin.h>
#undef XP_NO_X_HEADERS
#include "apple_glx_drawable.h"
struct apple_glx_context
{
CGLContextObj context_obj;
CGLPixelFormatObj pixel_format_obj;
struct apple_glx_drawable *drawable;
pthread_t thread_id;
int screen;
bool double_buffered;
bool uses_stereo;
bool need_update;
bool is_current; /* True if the context is current in some thread. */
bool made_current; /* True if the context has ever been made current. */
/*
* last_surface is set by the pending_destroy code handler for a drawable.
* Due to a CG difference, we have to recreate a surface if the window
* is unmapped and mapped again.
*/
Window last_surface_window;
struct apple_glx_context *previous, *next;
};
bool apple_glx_create_context(void **ptr, Display * dpy, int screen,
const void *mode, void *sharedContext,
int *errorptr, bool * x11errorptr);
void apple_glx_destroy_context(void **ptr, Display * dpy);
bool apple_glx_make_current_context(Display * dpy, void *oldptr, void *ptr,
GLXDrawable drawable);
bool apple_glx_is_current_drawable(Display * dpy, void *ptr,
GLXDrawable drawable);
bool apple_glx_copy_context(void *currentptr, void *srcptr, void *destptr,
unsigned long mask, int *errorptr,
bool * x11errorptr);
int apple_glx_context_surface_changed(unsigned int uid, pthread_t caller);
void apple_glx_context_update(Display * dpy, void *ptr);
bool apple_glx_context_uses_stereo(void *ptr);
#endif /*APPLE_GLX_CONTEXT_H */
+553
View File
@@ -0,0 +1,553 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
#include <string.h>
#include "apple_glx.h"
#include "apple_glx_context.h"
#include "apple_glx_drawable.h"
#include "appledri.h"
static pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER;
static struct apple_glx_drawable *drawables_list = NULL;
static void
lock_drawables_list(void)
{
int err;
err = pthread_mutex_lock(&drawables_lock);
if (err) {
fprintf(stderr, "pthread_mutex_lock failure in %s: %s\n",
__func__, strerror(err));
abort();
}
}
static void
unlock_drawables_list(void)
{
int err;
err = pthread_mutex_unlock(&drawables_lock);
if (err) {
fprintf(stderr, "pthread_mutex_unlock failure in %s: %s\n",
__func__, strerror(err));
abort();
}
}
struct apple_glx_drawable *
apple_glx_find_drawable(Display * dpy, GLXDrawable drawable)
{
struct apple_glx_drawable *i, *agd = NULL;
lock_drawables_list();
for (i = drawables_list; i; i = i->next) {
if (i->drawable == drawable) {
agd = i;
break;
}
}
unlock_drawables_list();
return agd;
}
static void
drawable_lock(struct apple_glx_drawable *agd)
{
int err;
err = pthread_mutex_lock(&agd->mutex);
if (err) {
fprintf(stderr, "pthread_mutex_lock error: %s\n", strerror(err));
abort();
}
}
static void
drawable_unlock(struct apple_glx_drawable *d)
{
int err;
err = pthread_mutex_unlock(&d->mutex);
if (err) {
fprintf(stderr, "pthread_mutex_unlock error: %s\n", strerror(err));
abort();
}
}
static void
reference_drawable(struct apple_glx_drawable *d)
{
d->lock(d);
d->reference_count++;
d->unlock(d);
}
static void
release_drawable(struct apple_glx_drawable *d)
{
d->lock(d);
d->reference_count--;
d->unlock(d);
}
/* The drawables list must be locked prior to calling this. */
/* Return true if the drawable was destroyed. */
static bool
destroy_drawable(struct apple_glx_drawable *d)
{
int err;
d->lock(d);
if (d->reference_count > 0) {
d->unlock(d);
return false;
}
d->unlock(d);
if (d->previous) {
d->previous->next = d->next;
}
else {
/*
* The item must be at the head of the list, if it
* has no previous pointer.
*/
drawables_list = d->next;
}
if (d->next)
d->next->previous = d->previous;
unlock_drawables_list();
if (d->callbacks.destroy) {
/*
* Warning: this causes other routines to be called (potentially)
* from surface_notify_handler. It's probably best to not have
* any locks at this point locked.
*/
d->callbacks.destroy(d->display, d);
}
apple_glx_diagnostic("%s: freeing %p\n", __func__, (void *) d);
/* Stupid recursive locks */
while (pthread_mutex_unlock(&d->mutex) == 0);
err = pthread_mutex_destroy(&d->mutex);
if (err) {
fprintf(stderr, "pthread_mutex_destroy error: %s\n", strerror(err));
abort();
}
free(d);
/* So that the locks are balanced and the caller correctly unlocks. */
lock_drawables_list();
return true;
}
/*
* This is typically called when a context is destroyed or the current
* drawable is made None.
*/
static bool
destroy_drawable_callback(struct apple_glx_drawable *d)
{
bool result;
d->lock(d);
apple_glx_diagnostic("%s: %p ->reference_count before -- %d\n", __func__,
(void *) d, d->reference_count);
d->reference_count--;
if (d->reference_count > 0) {
d->unlock(d);
return false;
}
d->unlock(d);
lock_drawables_list();
result = destroy_drawable(d);
unlock_drawables_list();
return result;
}
static bool
is_pbuffer(struct apple_glx_drawable *d)
{
return APPLE_GLX_DRAWABLE_PBUFFER == d->type;
}
static bool
is_pixmap(struct apple_glx_drawable *d)
{
return APPLE_GLX_DRAWABLE_PIXMAP == d->type;
}
static void
common_init(Display * dpy, GLXDrawable drawable, struct apple_glx_drawable *d)
{
int err;
pthread_mutexattr_t attr;
d->display = dpy;
d->reference_count = 0;
d->drawable = drawable;
d->type = -1;
err = pthread_mutexattr_init(&attr);
if (err) {
fprintf(stderr, "pthread_mutexattr_init error: %s\n", strerror(err));
abort();
}
/*
* There are some patterns that require a recursive mutex,
* when working with locks that protect the apple_glx_drawable,
* and reference functions like ->reference, and ->release.
*/
err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
if (err) {
fprintf(stderr, "error: setting pthread mutex type: %s\n", strerror(err));
abort();
}
err = pthread_mutex_init(&d->mutex, &attr);
if (err) {
fprintf(stderr, "pthread_mutex_init error: %s\n", strerror(err));
abort();
}
(void) pthread_mutexattr_destroy(&attr);
d->lock = drawable_lock;
d->unlock = drawable_unlock;
d->reference = reference_drawable;
d->release = release_drawable;
d->destroy = destroy_drawable_callback;
d->is_pbuffer = is_pbuffer;
d->is_pixmap = is_pixmap;
d->width = -1;
d->height = -1;
d->row_bytes = 0;
d->path[0] = '\0';
d->fd = -1;
d->buffer = NULL;
d->buffer_length = 0;
d->previous = NULL;
d->next = NULL;
}
static void
link_tail(struct apple_glx_drawable *agd)
{
lock_drawables_list();
/* Link the new drawable into the global list. */
agd->next = drawables_list;
if (drawables_list)
drawables_list->previous = agd;
drawables_list = agd;
unlock_drawables_list();
}
/*WARNING: this returns a locked and referenced object. */
bool
apple_glx_drawable_create(Display * dpy,
int screen,
GLXDrawable drawable,
struct apple_glx_drawable **agdResult,
struct apple_glx_drawable_callbacks *callbacks)
{
struct apple_glx_drawable *d;
d = calloc(1, sizeof *d);
if (NULL == d) {
perror("malloc");
return true;
}
common_init(dpy, drawable, d);
d->type = callbacks->type;
d->callbacks = *callbacks;
d->reference(d);
d->lock(d);
link_tail(d);
apple_glx_diagnostic("%s: new drawable %p\n", __func__, (void *) d);
*agdResult = d;
return false;
}
static int error_count = 0;
static int
error_handler(Display * dpy, XErrorEvent * err)
{
if (err->error_code == BadWindow) {
++error_count;
}
return 0;
}
void
apple_glx_garbage_collect_drawables(Display * dpy)
{
struct apple_glx_drawable *d, *dnext;
Window root;
int x, y;
unsigned int width, height, bd, depth;
int (*old_handler) (Display *, XErrorEvent *);
if (NULL == drawables_list)
return;
old_handler = XSetErrorHandler(error_handler);
XSync(dpy, False);
lock_drawables_list();
for (d = drawables_list; d;) {
dnext = d->next;
d->lock(d);
if (d->reference_count > 0) {
/*
* Skip this, because some context still retains a reference
* to the drawable.
*/
d->unlock(d);
d = dnext;
continue;
}
d->unlock(d);
error_count = 0;
/*
* Mesa uses XGetWindowAttributes, but some of these things are
* most definitely not Windows, and that's against the rules.
* XGetGeometry on the other hand is legal with a Pixmap and Window.
*/
XGetGeometry(dpy, d->drawable, &root, &x, &y, &width, &height, &bd,
&depth);
if (error_count > 0) {
/*
* Note: this may not actually destroy the drawable.
* If another context retains a reference to the drawable
* after the reference count test above.
*/
(void) destroy_drawable(d);
error_count = 0;
}
d = dnext;
}
XSetErrorHandler(old_handler);
unlock_drawables_list();
}
unsigned int
apple_glx_get_drawable_count(void)
{
unsigned int result = 0;
struct apple_glx_drawable *d;
lock_drawables_list();
for (d = drawables_list; d; d = d->next)
++result;
unlock_drawables_list();
return result;
}
struct apple_glx_drawable *
apple_glx_drawable_find_by_type(GLXDrawable drawable, int type, int flags)
{
struct apple_glx_drawable *d;
lock_drawables_list();
for (d = drawables_list; d; d = d->next) {
if (d->type == type && d->drawable == drawable) {
if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
d->reference(d);
if (flags & APPLE_GLX_DRAWABLE_LOCK)
d->lock(d);
unlock_drawables_list();
return d;
}
}
unlock_drawables_list();
return NULL;
}
struct apple_glx_drawable *
apple_glx_drawable_find(GLXDrawable drawable, int flags)
{
struct apple_glx_drawable *d;
lock_drawables_list();
for (d = drawables_list; d; d = d->next) {
if (d->drawable == drawable) {
if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
d->reference(d);
if (flags & APPLE_GLX_DRAWABLE_LOCK)
d->lock(d);
unlock_drawables_list();
return d;
}
}
unlock_drawables_list();
return NULL;
}
/* Return true if the type is valid for the drawable. */
bool
apple_glx_drawable_destroy_by_type(Display * dpy,
GLXDrawable drawable, int type)
{
struct apple_glx_drawable *d;
lock_drawables_list();
for (d = drawables_list; d; d = d->next) {
if (drawable == d->drawable && type == d->type) {
/*
* The user has requested that we destroy this resource.
* However, there may be references in the contexts to it, so
* release it, and call destroy_drawable which doesn't destroy
* if the reference_count is > 0.
*/
d->release(d);
apple_glx_diagnostic("%s d->reference_count %d\n",
__func__, d->reference_count);
destroy_drawable(d);
unlock_drawables_list();
return true;
}
}
unlock_drawables_list();
return false;
}
struct apple_glx_drawable *
apple_glx_drawable_find_by_uid(unsigned int uid, int flags)
{
struct apple_glx_drawable *d;
lock_drawables_list();
for (d = drawables_list; d; d = d->next) {
/* Only surfaces have a uid. */
if (APPLE_GLX_DRAWABLE_SURFACE == d->type) {
if (d->types.surface.uid == uid) {
if (flags & APPLE_GLX_DRAWABLE_REFERENCE)
d->reference(d);
if (flags & APPLE_GLX_DRAWABLE_LOCK)
d->lock(d);
unlock_drawables_list();
return d;
}
}
}
unlock_drawables_list();
return NULL;
}
+227
View File
@@ -0,0 +1,227 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#ifndef APPLE_GLX_DRAWABLE_H
#define APPLE_GLX_DRAWABLE_H
/* Must be first for:
* <rdar://problem/6953344>
*/
#include "apple_glx_context.h"
#include <pthread.h>
#include <stdbool.h>
#include <limits.h>
#include <GL/glx.h>
#define XP_NO_X_HEADERS
#include <Xplugin.h>
#undef XP_NO_X_HEADERS
enum
{
APPLE_GLX_DRAWABLE_SURFACE = 1,
APPLE_GLX_DRAWABLE_PBUFFER,
APPLE_GLX_DRAWABLE_PIXMAP
};
/* The flag for the find routine. */
enum
{
APPLE_GLX_DRAWABLE_LOCK = 2,
APPLE_GLX_DRAWABLE_REFERENCE = 4
};
struct apple_glx_context;
struct apple_glx_drawable;
struct apple_glx_surface
{
xp_surface_id surface_id;
unsigned int uid;
bool pending_destroy;
};
struct apple_glx_pbuffer
{
GLXPbuffer xid; /* our pixmap */
int width, height;
GLint fbconfigID;
CGLPBufferObj buffer_obj;
unsigned long event_mask;
};
struct apple_glx_pixmap
{
GLXPixmap xpixmap;
void *buffer;
int width, height, pitch, /*bytes per pixel */ bpp;
size_t size;
char path[PATH_MAX];
int fd;
CGLPixelFormatObj pixel_format_obj;
CGLContextObj context_obj;
GLint fbconfigID;
};
struct apple_glx_drawable_callbacks
{
int type;
bool(*make_current) (struct apple_glx_context * ac,
struct apple_glx_drawable * d);
void (*destroy) (Display * dpy, struct apple_glx_drawable * d);
};
struct apple_glx_drawable
{
Display *display;
int reference_count;
GLXDrawable drawable;
int type; /* APPLE_GLX_DRAWABLE_* */
union
{
struct apple_glx_pixmap pixmap;
struct apple_glx_pbuffer pbuffer;
struct apple_glx_surface surface;
} types;
struct apple_glx_drawable_callbacks callbacks;
/*
* This mutex protects the reference count and any other drawable data.
* It's used to prevent an early release of a drawable.
*/
pthread_mutex_t mutex;
void (*lock) (struct apple_glx_drawable * agd);
void (*unlock) (struct apple_glx_drawable * agd);
void (*reference) (struct apple_glx_drawable * agd);
void (*release) (struct apple_glx_drawable * agd);
bool(*destroy) (struct apple_glx_drawable * agd);
bool(*is_pbuffer) (struct apple_glx_drawable * agd);
bool(*is_pixmap) (struct apple_glx_drawable * agd);
/*BEGIN These are used for the mixed mode drawing... */
int width, height;
int row_bytes;
char path[PATH_MAX];
int fd; /* The file descriptor for this drawable's shared memory. */
void *buffer; /* The memory for the drawable. Typically shared memory. */
size_t buffer_length;
/*END*/ struct apple_glx_drawable *previous, *next;
};
struct apple_glx_context;
/* May return NULL if not found */
struct apple_glx_drawable *apple_glx_find_drawable(Display * dpy,
GLXDrawable drawable);
/* Returns true on error and locks the agd result with a reference. */
bool apple_glx_drawable_create(Display * dpy,
int screen,
GLXDrawable drawable,
struct apple_glx_drawable **agd,
struct apple_glx_drawable_callbacks
*callbacks);
/* Returns true on error */
bool apple_glx_create_drawable(Display * dpy,
struct apple_glx_context *ac,
GLXDrawable drawable,
struct apple_glx_drawable **agd);
void apple_glx_garbage_collect_drawables(Display * dpy);
/*
* This returns the total number of drawables.
* It's mostly intended for debugging and introspection.
*/
unsigned int apple_glx_get_drawable_count(void);
struct apple_glx_drawable *apple_glx_drawable_find_by_type(GLXDrawable
drawable, int type,
int flags);
struct apple_glx_drawable *apple_glx_drawable_find(GLXDrawable drawable,
int flags);
bool apple_glx_drawable_destroy_by_type(Display * dpy, GLXDrawable drawable,
int type);
struct apple_glx_drawable *apple_glx_drawable_find_by_uid(unsigned int uid,
int flags);
/* Surfaces */
bool apple_glx_surface_create(Display * dpy, int screen, GLXDrawable drawable,
struct apple_glx_drawable **resultptr);
void apple_glx_surface_destroy(unsigned int uid);
/* Pbuffers */
/* Returns true if an error occurred. */
bool apple_glx_pbuffer_create(Display * dpy, GLXFBConfig config,
int width, int height, int *errorcode,
GLXPbuffer * pbuf);
/* Returns true if the pbuffer was invalid. */
bool apple_glx_pbuffer_destroy(Display * dpy, GLXPbuffer pbuf);
/* Returns true if the pbuffer was valid and the attribute. */
bool apple_glx_pbuffer_query(GLXDrawable d, int attribute,
unsigned int *value);
/* Returns true if the GLXDrawable is a valid GLXPbuffer, and the mask is set. */
bool apple_glx_pbuffer_set_event_mask(GLXDrawable d, unsigned long mask);
/* Returns true if the GLXDrawable is a valid GLXPbuffer, and the *mask is set. */
bool apple_glx_pbuffer_get_event_mask(GLXDrawable d, unsigned long *mask);
/* Pixmaps */
/* mode is a struct glx_config * */
/* Returns true if an error occurred. */
bool apple_glx_pixmap_create(Display * dpy, int screen, Pixmap pixmap,
const void *mode);
/* Returns true if an error occurred. */
bool apple_glx_pixmap_destroy(Display * dpy, Pixmap pixmap);
bool apple_glx_pixmap_query(GLXPixmap pixmap, int attribute,
unsigned int *value);
#endif
+119
View File
@@ -0,0 +1,119 @@
/*
* Copyright (c) 2012 Apple Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
* HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name(s) of the above
* copyright holders shall not be used in advertising or otherwise to
* promote the sale, use or other dealings in this Software without
* prior written authorization.
*/
#include <sys/cdefs.h>
#include <asl.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h>
#include <pthread.h>
#include "glxclient.h"
#include "apple_glx_log.h"
#include "util/u_debug.h"
static aslclient aslc;
void apple_glx_log_init(void) {
aslc = asl_open(NULL, NULL, 0);
}
void _apple_glx_log(int level, const char *file, const char *function,
int line, const char *fmt, ...) {
va_list v;
va_start(v, fmt);
_apple_glx_vlog(level, file, function, line, fmt, v);
va_end(v);
}
static const char *
_asl_level_string(int level)
{
if (level == ASL_LEVEL_EMERG) return ASL_STRING_EMERG;
if (level == ASL_LEVEL_ALERT) return ASL_STRING_ALERT;
if (level == ASL_LEVEL_CRIT) return ASL_STRING_CRIT;
if (level == ASL_LEVEL_ERR) return ASL_STRING_ERR;
if (level == ASL_LEVEL_WARNING) return ASL_STRING_WARNING;
if (level == ASL_LEVEL_NOTICE) return ASL_STRING_NOTICE;
if (level == ASL_LEVEL_INFO) return ASL_STRING_INFO;
if (level == ASL_LEVEL_DEBUG) return ASL_STRING_DEBUG;
return "unknown";
}
void _apple_glx_vlog(int level, const char *file, const char *function,
int line, const char *fmt, va_list args) {
aslmsg msg;
uint64_t thread = 0;
if (pthread_is_threaded_np()) {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
thread = (uint64_t)(uintptr_t)pthread_self();
#elif MAC_OS_X_VERSION_MIN_REQUIRED < 1060
if (&pthread_threadid_np) {
pthread_threadid_np(NULL, &thread);
} else {
thread = (uint64_t)(uintptr_t)pthread_self();
}
#else
pthread_threadid_np(NULL, &thread);
#endif
}
DebugMessageF("%-9s %24s:%-4d %s(%"PRIu64"): ",
_asl_level_string(level), file, line, function, thread);
msg = asl_new(ASL_TYPE_MSG);
if (msg) {
if (file)
asl_set(msg, "File", file);
if (function)
asl_set(msg, "Function", function);
if (line) {
char *_line;
asprintf(&_line, "%d", line);
if (_line) {
asl_set(msg, "Line", _line);
free(_line);
}
}
if (pthread_is_threaded_np()) {
char *_thread;
asprintf(&_thread, "%"PRIu64, thread);
if (_thread) {
asl_set(msg, "Thread", _thread);
free(_thread);
}
}
}
asl_vlog(aslc, msg, level, fmt, args);
if (msg)
asl_free(msg);
}
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2012 Apple Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
* HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name(s) of the above
* copyright holders shall not be used in advertising or otherwise to
* promote the sale, use or other dealings in this Software without
* prior written authorization.
*/
#ifndef APPLE_GLX_LOG_H
#define APPLE_GLX_LOG_H
#include <sys/cdefs.h>
#include <asl.h>
void apple_glx_log_init(void);
__printflike(5, 6)
void _apple_glx_log(int level, const char *file, const char *function,
int line, const char *fmt, ...);
#define apple_glx_log(l, f, args ...) \
_apple_glx_log(l, __FILE__, __func__, __LINE__, f, ## args)
__printflike(5, 0)
void _apple_glx_vlog(int level, const char *file, const char *function,
int line, const char *fmt, va_list v);
#define apple_glx_vlog(l, f, v) \
_apple_glx_vlog(l, __FILE__, __func__, __LINE__, f, v)
/* This is just here to help the transition.
* TODO: Replace calls to apple_glx_diagnostic
*/
#define apple_glx_diagnostic(f, args ...) \
apple_glx_log(ASL_LEVEL_DEBUG, f, ## args)
#endif
+346
View File
@@ -0,0 +1,346 @@
/*
Copyright (c) 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
/* Must be before OpenGL.framework is included. Remove once fixed:
* <rdar://problem/7872773>
*/
#include <GL/gl.h>
#include <GL/glext.h>
#define __gltypes_h_ 1
/* Must be first for:
* <rdar://problem/6953344>
*/
#include "apple_glx_context.h"
#include "apple_glx_drawable.h"
#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "glxclient.h"
#include "apple_glx.h"
#include "glxconfig.h"
#include "apple_cgl.h"
#include "util/u_debug.h"
/* mesa defines in glew.h, Apple in glext.h.
* Due to namespace nightmares, just do it here.
*/
#ifndef GL_TEXTURE_RECTANGLE_EXT
#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
#endif
static bool pbuffer_make_current(struct apple_glx_context *ac,
struct apple_glx_drawable *d);
static void pbuffer_destroy(Display * dpy, struct apple_glx_drawable *d);
static struct apple_glx_drawable_callbacks callbacks = {
.type = APPLE_GLX_DRAWABLE_PBUFFER,
.make_current = pbuffer_make_current,
.destroy = pbuffer_destroy
};
/* Return true if an error occurred. */
bool
pbuffer_make_current(struct apple_glx_context *ac,
struct apple_glx_drawable *d)
{
struct apple_glx_pbuffer *pbuf = &d->types.pbuffer;
CGLError cglerr;
assert(APPLE_GLX_DRAWABLE_PBUFFER == d->type);
cglerr = apple_cgl.set_pbuffer(ac->context_obj, pbuf->buffer_obj, 0, 0, 0);
if (kCGLNoError != cglerr) {
fprintf(stderr, "set_pbuffer: %s\n", apple_cgl.error_string(cglerr));
return true;
}
if (!ac->made_current) {
apple_glapi_oglfw_viewport_scissor(0, 0, pbuf->width, pbuf->height);
ac->made_current = true;
}
apple_glx_diagnostic("made pbuffer drawable 0x%lx current\n", d->drawable);
return false;
}
void
pbuffer_destroy(Display * dpy, struct apple_glx_drawable *d)
{
struct apple_glx_pbuffer *pbuf = &d->types.pbuffer;
assert(APPLE_GLX_DRAWABLE_PBUFFER == d->type);
apple_glx_diagnostic("destroying pbuffer for drawable 0x%lx\n",
d->drawable);
apple_cgl.destroy_pbuffer(pbuf->buffer_obj);
XFreePixmap(dpy, pbuf->xid);
}
/* Return true if an error occurred. */
bool
apple_glx_pbuffer_destroy(Display * dpy, GLXPbuffer pbuf)
{
return !apple_glx_drawable_destroy_by_type(dpy, pbuf,
APPLE_GLX_DRAWABLE_PBUFFER);
}
/* Return true if an error occurred. */
bool
apple_glx_pbuffer_create(Display * dpy, GLXFBConfig config,
int width, int height, int *errorcode,
GLXPbuffer * result)
{
struct apple_glx_drawable *d;
struct apple_glx_pbuffer *pbuf = NULL;
CGLError err;
Window root;
int screen;
Pixmap xid;
struct glx_config *modes = (struct glx_config *) config;
root = DefaultRootWindow(dpy);
screen = DefaultScreen(dpy);
/*
* This pixmap is only used for a persistent XID.
* The XC-MISC extension cleans up XIDs and reuses them transparently,
* so we need to retain a server-side reference.
*/
xid = XCreatePixmap(dpy, root, (unsigned int) 1,
(unsigned int) 1, DefaultDepth(dpy, screen));
if (None == xid) {
*errorcode = BadAlloc;
return true;
}
if (apple_glx_drawable_create(dpy, screen, xid, &d, &callbacks)) {
*errorcode = BadAlloc;
return true;
}
/* The lock is held in d from create onward. */
pbuf = &d->types.pbuffer;
pbuf->xid = xid;
pbuf->width = width;
pbuf->height = height;
err = apple_cgl.create_pbuffer(width, height, GL_TEXTURE_RECTANGLE_EXT,
(modes->alphaBits > 0) ? GL_RGBA : GL_RGB,
0, &pbuf->buffer_obj);
if (kCGLNoError != err) {
d->unlock(d);
d->destroy(d);
*errorcode = BadMatch;
return true;
}
pbuf->fbconfigID = modes->fbconfigID;
pbuf->event_mask = 0;
*result = pbuf->xid;
d->unlock(d);
return false;
}
/* Return true if an error occurred. */
static bool
get_max_size(int *widthresult, int *heightresult)
{
CGLContextObj oldcontext;
GLint ar[2];
oldcontext = apple_cgl.get_current_context();
if (!oldcontext) {
/*
* There is no current context, so we need to make one in order
* to call glGetInteger.
*/
CGLPixelFormatObj pfobj;
CGLError err;
CGLPixelFormatAttribute attr[10];
int c = 0;
GLint vsref = 0;
CGLContextObj newcontext;
attr[c++] = kCGLPFAColorSize;
attr[c++] = 32;
attr[c++] = 0;
err = apple_cgl.choose_pixel_format(attr, &pfobj, &vsref);
if (kCGLNoError != err) {
DebugMessageF("choose_pixel_format error in %s: %s\n", __func__,
apple_cgl.error_string(err));
return true;
}
err = apple_cgl.create_context(pfobj, NULL, &newcontext);
if (kCGLNoError != err) {
DebugMessageF("create_context error in %s: %s\n", __func__,
apple_cgl.error_string(err));
apple_cgl.destroy_pixel_format(pfobj);
return true;
}
err = apple_cgl.set_current_context(newcontext);
if (kCGLNoError != err) {
DebugMessageF("set_current_context error in %s: %s\n", __func__,
apple_cgl.error_string(err));
return true;
}
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, ar);
apple_cgl.set_current_context(oldcontext);
apple_cgl.destroy_context(newcontext);
apple_cgl.destroy_pixel_format(pfobj);
}
else {
/* We have a valid context. */
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, ar);
}
*widthresult = ar[0];
*heightresult = ar[1];
return false;
}
bool
apple_glx_pbuffer_query(GLXPbuffer p, int attr, unsigned int *value)
{
bool result = false;
struct apple_glx_drawable *d;
struct apple_glx_pbuffer *pbuf;
d = apple_glx_drawable_find_by_type(p, APPLE_GLX_DRAWABLE_PBUFFER,
APPLE_GLX_DRAWABLE_LOCK);
if (d) {
pbuf = &d->types.pbuffer;
switch (attr) {
case GLX_WIDTH:
*value = pbuf->width;
result = true;
break;
case GLX_HEIGHT:
*value = pbuf->height;
result = true;
break;
case GLX_PRESERVED_CONTENTS:
*value = true;
result = true;
break;
case GLX_LARGEST_PBUFFER:{
int width, height;
if (get_max_size(&width, &height)) {
fprintf(stderr, "internal error: "
"unable to find the largest pbuffer!\n");
}
else {
*value = width;
result = true;
}
}
break;
case GLX_FBCONFIG_ID:
*value = pbuf->fbconfigID;
result = true;
break;
}
d->unlock(d);
}
return result;
}
bool
apple_glx_pbuffer_set_event_mask(GLXDrawable drawable, unsigned long mask)
{
struct apple_glx_drawable *d;
bool result = false;
d = apple_glx_drawable_find_by_type(drawable, APPLE_GLX_DRAWABLE_PBUFFER,
APPLE_GLX_DRAWABLE_LOCK);
if (d) {
d->types.pbuffer.event_mask = mask;
result = true;
d->unlock(d);
}
return result;
}
bool
apple_glx_pbuffer_get_event_mask(GLXDrawable drawable, unsigned long *mask)
{
struct apple_glx_drawable *d;
bool result = false;
d = apple_glx_drawable_find_by_type(drawable, APPLE_GLX_DRAWABLE_PBUFFER,
APPLE_GLX_DRAWABLE_LOCK);
if (d) {
*mask = d->types.pbuffer.event_mask;
result = true;
d->unlock(d);
}
return result;
}
+229
View File
@@ -0,0 +1,229 @@
/*
Copyright (c) 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <assert.h>
#include "apple_glx.h"
#include "apple_cgl.h"
#include "apple_visual.h"
#include "apple_glx_drawable.h"
#include "appledri.h"
#include "glxconfig.h"
static bool pixmap_make_current(struct apple_glx_context *ac,
struct apple_glx_drawable *d);
static void pixmap_destroy(Display * dpy, struct apple_glx_drawable *d);
static struct apple_glx_drawable_callbacks callbacks = {
.type = APPLE_GLX_DRAWABLE_PIXMAP,
.make_current = pixmap_make_current,
.destroy = pixmap_destroy
};
static bool
pixmap_make_current(struct apple_glx_context *ac,
struct apple_glx_drawable *d)
{
CGLError cglerr;
struct apple_glx_pixmap *p = &d->types.pixmap;
assert(APPLE_GLX_DRAWABLE_PIXMAP == d->type);
cglerr = apple_cgl.set_current_context(p->context_obj);
if (kCGLNoError != cglerr) {
fprintf(stderr, "set current context: %s\n",
apple_cgl.error_string(cglerr));
return true;
}
cglerr = apple_cgl.set_off_screen(p->context_obj, p->width, p->height,
p->pitch, p->buffer);
if (kCGLNoError != cglerr) {
fprintf(stderr, "set off screen: %s\n", apple_cgl.error_string(cglerr));
return true;
}
if (!ac->made_current) {
apple_glapi_oglfw_viewport_scissor(0, 0, p->width, p->height);
ac->made_current = true;
}
return false;
}
static void
pixmap_destroy(Display * dpy, struct apple_glx_drawable *d)
{
struct apple_glx_pixmap *p = &d->types.pixmap;
if (p->pixel_format_obj)
(void) apple_cgl.destroy_pixel_format(p->pixel_format_obj);
if (p->context_obj)
(void) apple_cgl.destroy_context(p->context_obj);
XAppleDRIDestroyPixmap(dpy, p->xpixmap);
if (p->buffer) {
if (munmap(p->buffer, p->size))
perror("munmap");
if (-1 == close(p->fd))
perror("close");
if (shm_unlink(p->path))
perror("shm_unlink");
}
apple_glx_diagnostic("destroyed pixmap buffer for: 0x%lx\n", d->drawable);
}
/* Return true if an error occurred. */
bool
apple_glx_pixmap_create(Display * dpy, int screen, Pixmap pixmap,
const void *mode)
{
struct apple_glx_drawable *d;
struct apple_glx_pixmap *p;
bool double_buffered;
bool uses_stereo;
CGLError error;
const struct glx_config *cmodes = mode;
if (apple_glx_drawable_create(dpy, screen, pixmap, &d, &callbacks))
return true;
/* d is locked and referenced at this point. */
p = &d->types.pixmap;
p->xpixmap = pixmap;
p->buffer = NULL;
if (!XAppleDRICreatePixmap(dpy, screen, pixmap,
&p->width, &p->height, &p->pitch, &p->bpp,
&p->size, p->path, PATH_MAX)) {
d->unlock(d);
d->destroy(d);
return true;
}
p->fd = shm_open(p->path, O_RDWR, 0);
if (p->fd < 0) {
perror("shm_open");
d->unlock(d);
d->destroy(d);
return true;
}
p->buffer = mmap(NULL, p->size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, p->fd, 0);
if (MAP_FAILED == p->buffer) {
perror("mmap");
d->unlock(d);
d->destroy(d);
return true;
}
apple_visual_create_pfobj(&p->pixel_format_obj, mode, &double_buffered,
&uses_stereo, /*offscreen */ true);
error = apple_cgl.create_context(p->pixel_format_obj, NULL,
&p->context_obj);
if (kCGLNoError != error) {
d->unlock(d);
d->destroy(d);
return true;
}
p->fbconfigID = cmodes->fbconfigID;
d->unlock(d);
apple_glx_diagnostic("created: pixmap buffer for 0x%lx\n", d->drawable);
return false;
}
bool
apple_glx_pixmap_query(GLXPixmap pixmap, int attr, unsigned int *value)
{
struct apple_glx_drawable *d;
struct apple_glx_pixmap *p;
bool result = false;
d = apple_glx_drawable_find_by_type(pixmap, APPLE_GLX_DRAWABLE_PIXMAP,
APPLE_GLX_DRAWABLE_LOCK);
if (d) {
p = &d->types.pixmap;
switch (attr) {
case GLX_WIDTH:
*value = p->width;
result = true;
break;
case GLX_HEIGHT:
*value = p->height;
result = true;
break;
case GLX_FBCONFIG_ID:
*value = p->fbconfigID;
result = true;
break;
}
d->unlock(d);
}
return result;
}
/* Return true if the type is valid for pixmap. */
bool
apple_glx_pixmap_destroy(Display * dpy, GLXPixmap pixmap)
{
return !apple_glx_drawable_destroy_by_type(dpy, pixmap,
APPLE_GLX_DRAWABLE_PIXMAP);
}
+225
View File
@@ -0,0 +1,225 @@
/*
Copyright (c) 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <assert.h>
#include "glxclient.h"
#include "apple_glx.h"
#include "appledri.h"
#include "apple_glx_drawable.h"
static bool surface_make_current(struct apple_glx_context *ac,
struct apple_glx_drawable *d);
static void surface_destroy(Display * dpy, struct apple_glx_drawable *d);
static struct apple_glx_drawable_callbacks callbacks = {
.type = APPLE_GLX_DRAWABLE_SURFACE,
.make_current = surface_make_current,
.destroy = surface_destroy
};
static void
update_viewport_and_scissor(Display * dpy, GLXDrawable drawable)
{
Window root;
int x, y;
unsigned int width = 0, height = 0, bd, depth;
XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &bd, &depth);
apple_glapi_oglfw_viewport_scissor(0, 0, width, height);
}
static bool
surface_make_current(struct apple_glx_context *ac,
struct apple_glx_drawable *d)
{
struct apple_glx_surface *s = &d->types.surface;
xp_error error;
assert(APPLE_GLX_DRAWABLE_SURFACE == d->type);
apple_glx_diagnostic("%s: ac->context_obj %p s->surface_id %u\n",
__func__, (void *) ac->context_obj, s->surface_id);
error = xp_attach_gl_context(ac->context_obj, s->surface_id);
if (error) {
fprintf(stderr, "error: xp_attach_gl_context returned: %d\n", error);
return true;
}
if (!ac->made_current) {
/*
* The first time a new context is made current the glViewport
* and glScissor should be updated.
*/
update_viewport_and_scissor(ac->drawable->display,
ac->drawable->drawable);
ac->made_current = true;
}
apple_glx_diagnostic("%s: drawable 0x%lx\n", __func__, d->drawable);
return false;
}
static void
surface_destroy(Display * dpy, struct apple_glx_drawable *d)
{
struct apple_glx_surface *s = &d->types.surface;
apple_glx_diagnostic("%s: s->surface_id %u\n", __func__, s->surface_id);
xp_error error = xp_destroy_surface(s->surface_id);
if (error) {
fprintf(stderr, "xp_destroy_surface error: %d\n", (int) error);
}
/*
* Check if this surface destroy came from the surface being destroyed
* on the server. If s->pending_destroy is true, then it did, and
* we don't want to try to destroy the surface on the server.
*/
if (!s->pending_destroy) {
/*
* Warning: this causes other routines to be called (potentially)
* from surface_notify_handler. It's probably best to not have
* any locks at this point locked.
*/
XAppleDRIDestroySurface(d->display, DefaultScreen(d->display),
d->drawable);
apple_glx_diagnostic
("%s: destroyed a surface for drawable 0x%lx uid %u\n", __func__,
d->drawable, s->uid);
}
}
/* Return true if an error occurred. */
static bool
create_surface(Display * dpy, int screen, struct apple_glx_drawable *d)
{
struct apple_glx_surface *s = &d->types.surface;
unsigned int key[2];
xp_client_id id;
id = apple_glx_get_client_id();
if (0 == id)
return true;
assert(None != d->drawable);
s->pending_destroy = false;
if (XAppleDRICreateSurface(dpy, screen, d->drawable, id, key, &s->uid)) {
xp_error error;
error = xp_import_surface(key, &s->surface_id);
if (error) {
fprintf(stderr, "error: xp_import_surface returned: %d\n", error);
return true;
}
apple_glx_diagnostic("%s: created a surface for drawable 0x%lx"
" with uid %u\n", __func__, d->drawable, s->uid);
return false; /*success */
}
return true; /* unable to create a surface. */
}
/* Return true if an error occurred. */
/* This returns a referenced object via resultptr. */
bool
apple_glx_surface_create(Display * dpy, int screen,
GLXDrawable drawable,
struct apple_glx_drawable ** resultptr)
{
struct apple_glx_drawable *d;
if (apple_glx_drawable_create(dpy, screen, drawable, &d, &callbacks))
return true;
/* apple_glx_drawable_create creates a locked and referenced object. */
if (create_surface(dpy, screen, d)) {
d->unlock(d);
d->destroy(d);
return true;
}
*resultptr = d;
d->unlock(d);
return false;
}
/*
* All surfaces are reference counted, and surfaces are only created
* when the window is made current. When all contexts no longer reference
* a surface drawable the apple_glx_drawable gets destroyed, and thus
* its surface is destroyed.
*
* However we can make the destruction occur a bit sooner by setting
* pending_destroy, which is then checked for in glViewport by
* apple_glx_context_update.
*/
void
apple_glx_surface_destroy(unsigned int uid)
{
struct apple_glx_drawable *d;
d = apple_glx_drawable_find_by_uid(uid, APPLE_GLX_DRAWABLE_REFERENCE
| APPLE_GLX_DRAWABLE_LOCK);
if (d) {
d->types.surface.pending_destroy = true;
d->release(d);
/*
* We release 2 references to the surface. One was acquired by
* the find, and the other was leftover from a context, or
* the surface being displayed, so the destroy() will decrease it
* once more.
*
* If the surface is in a context, it will take one d->destroy(d);
* to actually destroy it when the pending_destroy is processed
* by a glViewport callback (see apple_glx_context_update()).
*/
if (!d->destroy(d)) {
/* apple_glx_drawable_find_by_uid returns a locked drawable */
d->unlock(d);
}
}
}
+198
View File
@@ -0,0 +1,198 @@
/*
Copyright (c) 2008, 2009 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <GL/gl.h>
#include <util/u_debug.h>
/* <rdar://problem/6953344> */
#define glTexImage1D glTexImage1D_OSX
#define glTexImage2D glTexImage2D_OSX
#define glTexImage3D glTexImage3D_OSX
#include <OpenGL/OpenGL.h>
#include <OpenGL/CGLContext.h>
#include <OpenGL/CGLRenderers.h>
#include <OpenGL/CGLTypes.h>
#undef glTexImage1D
#undef glTexImage2D
#undef glTexImage3D
#ifndef kCGLPFAOpenGLProfile
#define kCGLPFAOpenGLProfile 99
#endif
#ifndef kCGLOGLPVersion_3_2_Core
#define kCGLOGLPVersion_3_2_Core 0x3200
#endif
#include "apple_cgl.h"
#include "apple_visual.h"
#include "apple_glx.h"
#include "glxconfig.h"
enum
{
MAX_ATTR = 60
};
static char __crashreporter_info_buff__[4096] = { 0 };
static const char *__crashreporter_info__ __attribute__((__used__)) =
&__crashreporter_info_buff__[0];
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
// This is actually a toolchain requirement, but I'm not sure the correct check,
// but it should be fine to just only include it for Leopard and later. This line
// just tells the linker to never strip this symbol (such as for space optimization)
__asm__ (".desc ___crashreporter_info__, 0x10");
#endif
void
apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode,
bool * double_buffered, bool * uses_stereo,
bool offscreen)
{
CGLPixelFormatAttribute attr[MAX_ATTR];
int numattr = 0;
GLint vsref = 0;
CGLError error = 0;
bool use_core_profile = debug_get_bool_option("LIBGL_PROFILE_CORE", false);
if (offscreen) {
apple_glx_diagnostic
("offscreen rendering enabled. Using kCGLPFAOffScreen\n");
attr[numattr++] = kCGLPFAOffScreen;
}
else if (debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false)) {
apple_glx_diagnostic
("Software rendering requested. Using kCGLRendererGenericFloatID.\n");
attr[numattr++] = kCGLPFARendererID;
attr[numattr++] = kCGLRendererGenericFloatID;
}
else if (debug_get_bool_option("LIBGL_ALLOW_SOFTWARE", false)) {
apple_glx_diagnostic
("Software rendering is not being excluded. Not using kCGLPFAAccelerated.\n");
}
else {
attr[numattr++] = kCGLPFAAccelerated;
}
/*
* The program chose a config based on the fbconfigs or visuals.
* Those are based on the attributes from CGL, so we probably
* do want the closest match for the color, depth, and accum.
*/
attr[numattr++] = kCGLPFAClosestPolicy;
if (mode->stereoMode) {
attr[numattr++] = kCGLPFAStereo;
*uses_stereo = true;
}
else {
*uses_stereo = false;
}
if (!offscreen && mode->doubleBufferMode) {
attr[numattr++] = kCGLPFADoubleBuffer;
*double_buffered = true;
}
else {
*double_buffered = false;
}
attr[numattr++] = kCGLPFAColorSize;
attr[numattr++] = mode->redBits + mode->greenBits + mode->blueBits;
attr[numattr++] = kCGLPFAAlphaSize;
attr[numattr++] = mode->alphaBits;
if ((mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits) > 0) {
attr[numattr++] = kCGLPFAAccumSize;
attr[numattr++] = mode->accumRedBits + mode->accumGreenBits +
mode->accumBlueBits + mode->accumAlphaBits;
}
if (mode->depthBits > 0) {
attr[numattr++] = kCGLPFADepthSize;
attr[numattr++] = mode->depthBits;
}
if (mode->stencilBits > 0) {
attr[numattr++] = kCGLPFAStencilSize;
attr[numattr++] = mode->stencilBits;
}
if (mode->sampleBuffers > 0) {
attr[numattr++] = kCGLPFAMultisample;
attr[numattr++] = kCGLPFASampleBuffers;
attr[numattr++] = mode->sampleBuffers;
attr[numattr++] = kCGLPFASamples;
attr[numattr++] = mode->samples;
}
/* Debugging support for Core profiles to support newer versions of OpenGL */
if (use_core_profile) {
attr[numattr++] = kCGLPFAOpenGLProfile;
attr[numattr++] = kCGLOGLPVersion_3_2_Core;
}
attr[numattr++] = 0;
assert(numattr < MAX_ATTR);
error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
if ((error == kCGLBadAttribute || vsref == 0) && use_core_profile) {
apple_glx_diagnostic
("Trying again without CoreProfile: error=%s, vsref=%d\n", apple_cgl.error_string(error), vsref);
if (!error)
apple_cgl.destroy_pixel_format(*pfobj);
numattr -= 3;
attr[numattr++] = 0;
error = apple_cgl.choose_pixel_format(attr, pfobj, &vsref);
}
if (error) {
snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
"CGLChoosePixelFormat error: %s\n", apple_cgl.error_string(error));
fprintf(stderr, "%s", __crashreporter_info_buff__);
abort();
}
if (!*pfobj) {
snprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__),
"No matching pixelformats found, perhaps try setting LIBGL_ALLOW_SOFTWARE=true\n");
fprintf(stderr, "%s", __crashreporter_info_buff__);
abort();
}
}
+41
View File
@@ -0,0 +1,41 @@
/*
Copyright (c) 2008 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#ifndef APPLE_VISUAL_H
#define APPLE_VISUAL_H
#include <stdbool.h>
#include <OpenGL/CGLTypes.h>
#include "glxconfig.h"
void apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const struct glx_config * mode,
bool * double_buffered, bool * uses_stereo,
bool offscreen);
#endif
+40
View File
@@ -0,0 +1,40 @@
/*
Copyright (c) 2011 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#ifndef APPLE_XGL_API_H
void __applegl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, void *pixels);
void __applegl_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
void __applegl_glDrawBuffer(GLenum mode);
void __applegl_glDrawBuffers(GLsizei n, const GLenum * bufs);
void __applegl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
#endif
+121
View File
@@ -0,0 +1,121 @@
/*
Copyright (c) 2008-2011 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
/*
* This file works with the glXMakeContextCurrent readable drawable.
*
* The way it works is by swapping the currentDrawable for the currentReadable
* drawable if they are different.
*/
#include <stdbool.h>
#include "glxclient.h"
#include "apple_glx_context.h"
#include "apple_xgl_api.h"
#include "glapi.h"
#include "dispatch.h"
extern struct _glapi_table * __ogl_framework_api;
struct apple_xgl_saved_state
{
bool swapped;
};
static void
SetRead(struct apple_xgl_saved_state *saved)
{
struct glx_context *gc = __glXGetCurrentContext();
/*
* By default indicate that the state was not swapped, so that UnsetRead
* functions correctly.
*/
saved->swapped = false;
/*
* If the readable drawable isn't the same as the drawable then
* the user has requested a readable drawable with glXMakeContextCurrent().
* We emulate this behavior by switching the current drawable.
*/
if (None != gc->currentReadable
&& gc->currentReadable != gc->currentDrawable) {
Display *dpy = glXGetCurrentDisplay();
saved->swapped = true;
if (apple_glx_make_current_context(dpy, gc->driContext, gc->driContext,
gc->currentReadable)) {
/* An error occurred, so try to restore the old context state. */
(void) apple_glx_make_current_context(dpy, gc->driContext, gc->driContext,
gc->currentDrawable);
saved->swapped = false;
}
}
}
static void
UnsetRead(struct apple_xgl_saved_state *saved)
{
if (saved->swapped) {
struct glx_context *gc = __glXGetCurrentContext();
Display *dpy = glXGetCurrentDisplay();
if (apple_glx_make_current_context(dpy, gc->driContext, gc->driContext,
gc->currentDrawable)) {
/*
* An error occurred restoring the drawable.
* It's unclear what to do about that.
*/
}
}
}
void
__applegl_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, void *pixels)
{
struct apple_xgl_saved_state saved;
SetRead(&saved);
CALL_ReadPixels(__ogl_framework_api, (x, y, width, height, format, type, pixels));
UnsetRead(&saved);
}
void
__applegl_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
{
struct apple_xgl_saved_state saved;
SetRead(&saved);
CALL_CopyPixels(__ogl_framework_api, (x, y, width, height, type));
UnsetRead(&saved);
}
+125
View File
@@ -0,0 +1,125 @@
/*
Copyright (c) 2009-2011 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
/* This should be removed once stereo hardware bugs are fixed
* <rdar://problem/6729006>
*/
#include <stdbool.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h>
#include "glxclient.h"
#include "apple_glx_context.h"
#include "apple_xgl_api.h"
#include "glapi.h"
#include "dispatch.h"
extern struct _glapi_table * __ogl_framework_api;
/*
* These are special functions for stereoscopic support
* differences in MacOS X.
*/
void
__applegl_glDrawBuffer(GLenum mode)
{
struct glx_context * gc = __glXGetCurrentContext();
if (gc != &dummyContext && apple_glx_context_uses_stereo(gc->driContext)) {
GLenum buf[2];
GLsizei n = 0;
switch (mode) {
case GL_BACK:
buf[0] = GL_BACK_LEFT;
buf[1] = GL_BACK_RIGHT;
n = 2;
break;
case GL_FRONT:
buf[0] = GL_FRONT_LEFT;
buf[1] = GL_FRONT_RIGHT;
n = 2;
break;
default:
buf[0] = mode;
n = 1;
break;
}
CALL_DrawBuffers(__ogl_framework_api, (n, buf));
}
else {
CALL_DrawBuffer(__ogl_framework_api, (mode));
}
}
void
__applegl_glDrawBuffers(GLsizei n, const GLenum * bufs)
{
struct glx_context * gc = __glXGetCurrentContext();
if (gc != &dummyContext && apple_glx_context_uses_stereo(gc->driContext)) {
GLenum newbuf[n + 2];
GLsizei i, outi = 0;
bool have_back = false;
bool have_front = false;
for (i = 0; i < n; ++i) {
if (GL_BACK == bufs[i]) {
have_back = true;
}
else if (GL_FRONT == bufs[i]) {
have_back = true;
}
else {
newbuf[outi++] = bufs[i];
}
}
if (have_back) {
newbuf[outi++] = GL_BACK_LEFT;
newbuf[outi++] = GL_BACK_RIGHT;
}
if (have_front) {
newbuf[outi++] = GL_FRONT_LEFT;
newbuf[outi++] = GL_FRONT_RIGHT;
}
CALL_DrawBuffers(__ogl_framework_api, (outi, newbuf));
}
else {
CALL_DrawBuffers(__ogl_framework_api, (n, bufs));
}
}
+48
View File
@@ -0,0 +1,48 @@
/*
Copyright (c) 2009-2011 Apple Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name(s) of the above
copyright holders shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without
prior written authorization.
*/
#include "glxclient.h"
#include "apple_glx_context.h"
#include "apple_xgl_api.h"
#include "glapi.h"
#include "dispatch.h"
extern struct _glapi_table * __ogl_framework_api;
void
__applegl_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
struct glx_context *gc = __glXGetCurrentContext();
Display *dpy = glXGetCurrentDisplay();
if (gc != &dummyContext && gc->driContext)
apple_glx_context_update(dpy, gc->driContext);
CALL_Viewport(__ogl_framework_api, (x, y, width, height));
}
+450
View File
@@ -0,0 +1,450 @@
/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.12 2001/08/27 17:40:57 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
Copyright (c) 2002, 2008 Apple Computer, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Kevin E. Martin <[email protected]>
* Jens Owen <[email protected]>
* Rickard E. (Rik) Faith <[email protected]>
*
*/
/* THIS IS NOT AN X CONSORTIUM STANDARD */
#include <X11/Xlibint.h>
#include "appledristr.h"
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <stdio.h>
static XExtensionInfo _appledri_info_data;
static XExtensionInfo *appledri_info = &_appledri_info_data;
static char *appledri_extension_name = APPLEDRINAME;
#define AppleDRICheckExtension(dpy,i,val) \
XextCheckExtension (dpy, i, appledri_extension_name, val)
/*****************************************************************************
* *
* private utility routines *
* *
*****************************************************************************/
static int close_display(Display * dpy, XExtCodes * extCodes);
static Bool wire_to_event(Display * dpy, XEvent * re, xEvent * event);
static /* const */ XExtensionHooks appledri_extension_hooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
close_display, /* close_display */
wire_to_event, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
static
XEXT_GENERATE_FIND_DISPLAY(find_display, appledri_info,
appledri_extension_name,
&appledri_extension_hooks,
AppleDRINumberEvents, NULL)
static XEXT_GENERATE_CLOSE_DISPLAY(close_display, appledri_info)
static void (*surface_notify_handler) ();
void *XAppleDRISetSurfaceNotifyHandler(void (*fun) ())
{
void *old = surface_notify_handler;
surface_notify_handler = fun;
return old;
}
static Bool
wire_to_event(Display *dpy, XEvent *re, xEvent *event)
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRINotifyEvent *sevent;
AppleDRICheckExtension(dpy, info, False);
switch ((event->u.u.type & 0x7f) - info->codes->first_event) {
case AppleDRISurfaceNotify:
sevent = (xAppleDRINotifyEvent *) event;
if (surface_notify_handler != NULL) {
(*surface_notify_handler) (dpy, (unsigned int) sevent->arg,
(int) sevent->kind);
}
return False;
}
return False;
}
/*****************************************************************************
* *
* public Apple-DRI Extension routines *
* *
*****************************************************************************/
#if 0
#include <stdio.h>
#define TRACE(msg) fprintf(stderr, "AppleDRI%s\n", msg);
#else
#define TRACE(msg)
#endif
Bool
XAppleDRIQueryExtension(dpy, event_basep, error_basep)
Display *dpy;
int *event_basep, *error_basep;
{
XExtDisplayInfo *info = find_display(dpy);
TRACE("QueryExtension...");
if (XextHasExtension(info)) {
*event_basep = info->codes->first_event;
*error_basep = info->codes->first_error;
TRACE("QueryExtension... return True");
return True;
}
else {
TRACE("QueryExtension... return False");
return False;
}
}
Bool
XAppleDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
Display *dpy;
int *majorVersion;
int *minorVersion;
int *patchVersion;
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRIQueryVersionReply rep;
xAppleDRIQueryVersionReq *req;
TRACE("QueryVersion...");
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRIQueryVersion, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRIQueryVersion;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryVersion... return False");
return False;
}
*majorVersion = rep.majorVersion;
*minorVersion = rep.minorVersion;
*patchVersion = rep.patchVersion;
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryVersion... return True");
return True;
}
Bool
XAppleDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
Display *dpy;
int screen;
Bool *isCapable;
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRIQueryDirectRenderingCapableReply rep;
xAppleDRIQueryDirectRenderingCapableReq *req;
TRACE("QueryDirectRenderingCapable...");
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRIQueryDirectRenderingCapable, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRIQueryDirectRenderingCapable;
req->screen = screen;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryDirectRenderingCapable... return False");
return False;
}
*isCapable = rep.isCapable;
UnlockDisplay(dpy);
SyncHandle();
TRACE("QueryDirectRenderingCapable... return True");
return True;
}
Bool
XAppleDRIAuthConnection(dpy, screen, magic)
Display *dpy;
int screen;
unsigned int magic;
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRIAuthConnectionReq *req;
xAppleDRIAuthConnectionReply rep;
TRACE("AuthConnection...");
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRIAuthConnection, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRIAuthConnection;
req->screen = screen;
req->magic = magic;
rep.authenticated = 0;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("AuthConnection... return False");
return False;
}
UnlockDisplay(dpy);
SyncHandle();
TRACE("AuthConnection... return True");
return True;
}
Bool
XAppleDRICreateSurface(dpy, screen, drawable, client_id, key, uid)
Display *dpy;
int screen;
Drawable drawable;
unsigned int client_id;
unsigned int *key;
unsigned int *uid;
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRICreateSurfaceReply rep;
xAppleDRICreateSurfaceReq *req;
TRACE("CreateSurface...");
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRICreateSurface, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRICreateSurface;
req->screen = screen;
req->drawable = drawable;
req->client_id = client_id;
rep.key_0 = rep.key_1 = rep.uid = 0;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.key_0) {
UnlockDisplay(dpy);
SyncHandle();
TRACE("CreateSurface... return False");
return False;
}
key[0] = rep.key_0;
key[1] = rep.key_1;
*uid = rep.uid;
UnlockDisplay(dpy);
SyncHandle();
TRACE("CreateSurface... return True");
return True;
}
Bool
XAppleDRIDestroySurface(dpy, screen, drawable)
Display *dpy;
int screen;
Drawable drawable;
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRIDestroySurfaceReq *req;
TRACE("DestroySurface...");
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRIDestroySurface, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRIDestroySurface;
req->screen = screen;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
TRACE("DestroySurface... return True");
return True;
}
Bool
XAppleDRICreateSharedBuffer(Display * dpy, int screen, Drawable drawable,
Bool doubleSwap, char *path, size_t pathlen,
int *width, int *height)
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRICreateSharedBufferReq *req;
xAppleDRICreateSharedBufferReply rep;
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRICreateSharedBuffer, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRICreateSharedBuffer;
req->screen = screen;
req->drawable = drawable;
req->doubleSwap = doubleSwap;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
puts("REPLY ERROR");
UnlockDisplay(dpy);
SyncHandle();
return False;
}
/* printf("rep.stringLength %d\n", (int) rep.stringLength); */
if (rep.stringLength > 0 && rep.stringLength <= pathlen) {
_XReadPad(dpy, path, rep.stringLength);
/* printf("path: %s\n", path); */
*width = rep.width;
*height = rep.height;
UnlockDisplay(dpy);
SyncHandle();
return True;
}
UnlockDisplay(dpy);
SyncHandle();
return False;
}
Bool
XAppleDRISwapBuffers(Display * dpy, int screen, Drawable drawable)
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRISwapBuffersReq *req;
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRISwapBuffers, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRISwapBuffers;
req->screen = screen;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
return True;
}
Bool
XAppleDRICreatePixmap(Display * dpy, int screen, Drawable drawable,
int *width, int *height, int *pitch, int *bpp,
size_t * size, char *bufname, size_t bufnamesize)
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRICreatePixmapReq *req;
xAppleDRICreatePixmapReply rep;
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRICreatePixmap, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRICreatePixmap;
req->screen = screen;
req->drawable = drawable;
if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
/*
printf("rep.stringLength %d\n", (int) rep.stringLength);
*/
if (rep.stringLength > 0 && rep.stringLength <= bufnamesize) {
_XReadPad(dpy, bufname, rep.stringLength);
/* printf("path: %s\n", bufname); */
*width = rep.width;
*height = rep.height;
*pitch = rep.pitch;
*bpp = rep.bpp;
*size = rep.size;
UnlockDisplay(dpy);
SyncHandle();
return True;
}
else if (rep.stringLength > 0) {
_XEatData(dpy, rep.stringLength);
}
UnlockDisplay(dpy);
SyncHandle();
return True;
}
/*
* Call it a drawable, because we really don't know what it is
* until it reaches the server, and we should keep that in mind.
*/
Bool
XAppleDRIDestroyPixmap(Display * dpy, Pixmap drawable)
{
XExtDisplayInfo *info = find_display(dpy);
xAppleDRIDestroyPixmapReq *req;
AppleDRICheckExtension(dpy, info, False);
LockDisplay(dpy);
GetReq(AppleDRIDestroyPixmap, req);
req->reqType = info->codes->major_opcode;
req->driReqType = X_AppleDRIDestroyPixmap;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
return True;
}
+124
View File
@@ -0,0 +1,124 @@
/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.7 2000/12/07 20:26:02 dawes Exp $ */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
Copyright (c) 2002, 2008, 2009 Apple Computer, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Kevin E. Martin <[email protected]>
* Jens Owen <[email protected]>
* Rickard E. (Rik) Faith <[email protected]>
*
*/
#ifndef _APPLEDRI_H_
#define _APPLEDRI_H_
#include <X11/Xlib.h>
#include <X11/Xfuncproto.h>
#define X_AppleDRIQueryVersion 0
#define X_AppleDRIQueryDirectRenderingCapable 1
#define X_AppleDRICreateSurface 2
#define X_AppleDRIDestroySurface 3
#define X_AppleDRIAuthConnection 4
#define X_AppleDRICreateSharedBuffer 5
#define X_AppleDRISwapBuffers 6
#define X_AppleDRICreatePixmap 7
#define X_AppleDRIDestroyPixmap 8
/* Requests up to and including 18 were used in a previous version */
/* Events */
#define AppleDRIObsoleteEvent1 0
#define AppleDRIObsoleteEvent2 1
#define AppleDRIObsoleteEvent3 2
#define AppleDRISurfaceNotify 3
#define AppleDRINumberEvents 4
/* Errors */
#define AppleDRIClientNotLocal 0
#define AppleDRIOperationNotSupported 1
#define AppleDRINumberErrors (AppleDRIOperationNotSupported + 1)
/* Kinds of SurfaceNotify events: */
#define AppleDRISurfaceNotifyChanged 0
#define AppleDRISurfaceNotifyDestroyed 1
#ifndef _APPLEDRI_SERVER_
typedef struct
{
int type; /* of event */
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
Window window; /* window of event */
Time time; /* server timestamp when event happened */
int kind; /* subtype of event */
int arg;
} XAppleDRINotifyEvent;
_XFUNCPROTOBEGIN
Bool XAppleDRIQueryExtension(Display * dpy, int *event_base,
int *error_base);
Bool XAppleDRIQueryVersion(Display * dpy, int *majorVersion,
int *minorVersion, int *patchVersion);
Bool XAppleDRIQueryDirectRenderingCapable(Display * dpy, int screen,
Bool * isCapable);
void *XAppleDRISetSurfaceNotifyHandler(void (*fun) (Display * dpy,
unsigned uid, int kind));
Bool XAppleDRIAuthConnection(Display * dpy, int screen, unsigned int magic);
Bool XAppleDRICreateSurface(Display * dpy, int screen, Drawable drawable,
unsigned int client_id, unsigned int key[2],
unsigned int *uid);
Bool XAppleDRIDestroySurface(Display * dpy, int screen, Drawable drawable);
Bool XAppleDRISynchronizeSurfaces(Display * dpy);
Bool XAppleDRICreateSharedBuffer(Display * dpy, int screen, Drawable drawable,
Bool doubleSwap, char *path, size_t pathlen,
int *width, int *height);
Bool XAppleDRISwapBuffers(Display * dpy, int screen, Drawable drawable);
Bool XAppleDRICreatePixmap(Display * dpy, int screen, Drawable drawable,
int *width, int *height, int *pitch, int *bpp,
size_t * size, char *bufname, size_t bufnamesize);
Bool XAppleDRIDestroyPixmap(Display * dpy, Pixmap pixmap);
_XFUNCPROTOEND
#endif /* _APPLEDRI_SERVER_ */
#endif /* _APPLEDRI_H_ */
+266
View File
@@ -0,0 +1,266 @@
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc.
Copyright (c) 2002, 2008, 2009 Apple Computer, Inc.
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sub license, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Kevin E. Martin <[email protected]>
* Jens Owen <[email protected]>
* Rickard E. (Rik) Fiath <[email protected]>
*
*/
#ifndef _APPLEDRISTR_H_
#define _APPLEDRISTR_H_
#include "appledri.h"
#define APPLEDRINAME "Apple-DRI"
#define APPLE_DRI_MAJOR_VERSION 1 /* current version numbers */
#define APPLE_DRI_MINOR_VERSION 0
#define APPLE_DRI_PATCH_VERSION 0
typedef struct _AppleDRIQueryVersion
{
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIQueryVersion */
CARD16 length B16;
} xAppleDRIQueryVersionReq;
#define sz_xAppleDRIQueryVersionReq 4
typedef struct
{
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD16 majorVersion B16; /* major version of DRI protocol */
CARD16 minorVersion B16; /* minor version of DRI protocol */
CARD32 patchVersion B32; /* patch version of DRI protocol */
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRIQueryVersionReply;
#define sz_xAppleDRIQueryVersionReply 32
typedef struct _AppleDRIQueryDirectRenderingCapable
{
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
CARD16 length B16;
CARD32 screen B32;
} xAppleDRIQueryDirectRenderingCapableReq;
#define sz_xAppleDRIQueryDirectRenderingCapableReq 8
typedef struct
{
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
BOOL isCapable;
BOOL pad2;
BOOL pad3;
BOOL pad4;
CARD32 pad5 B32;
CARD32 pad6 B32;
CARD32 pad7 B32;
CARD32 pad8 B32;
CARD32 pad9 B32;
} xAppleDRIQueryDirectRenderingCapableReply;
#define sz_xAppleDRIQueryDirectRenderingCapableReply 32
typedef struct _AppleDRIAuthConnection
{
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICloseConnection */
CARD16 length B16;
CARD32 screen B32;
CARD32 magic B32;
} xAppleDRIAuthConnectionReq;
#define sz_xAppleDRIAuthConnectionReq 12
typedef struct
{
BYTE type;
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 authenticated B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRIAuthConnectionReply;
#define zx_xAppleDRIAuthConnectionReply 32
typedef struct _AppleDRICreateSurface
{
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRICreateSurface */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
CARD32 client_id B32;
} xAppleDRICreateSurfaceReq;
#define sz_xAppleDRICreateSurfaceReq 16
typedef struct
{
BYTE type; /* X_Reply */
BOOL pad1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 key_0 B32;
CARD32 key_1 B32;
CARD32 uid B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRICreateSurfaceReply;
#define sz_xAppleDRICreateSurfaceReply 32
typedef struct _AppleDRIDestroySurface
{
CARD8 reqType; /* always DRIReqCode */
CARD8 driReqType; /* always X_DRIDestroySurface */
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xAppleDRIDestroySurfaceReq;
#define sz_xAppleDRIDestroySurfaceReq 12
typedef struct _AppleDRINotify
{
BYTE type; /* always eventBase + event type */
BYTE kind;
CARD16 sequenceNumber B16;
CARD32 time B32; /* time of change */
CARD32 pad1 B32;
CARD32 arg B32;
CARD32 pad3 B32;
CARD32 pad4 B32;
CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRINotifyEvent;
#define sz_xAppleDRINotifyEvent 32
typedef struct
{
CARD8 reqType;
CARD8 driReqType;
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
BOOL doubleSwap;
CARD8 pad1, pad2, pad3;
} xAppleDRICreateSharedBufferReq;
#define sz_xAppleDRICreateSharedBufferReq 16
typedef struct
{
BYTE type;
BYTE data1;
CARD16 sequenceNumber B16;
CARD32 length B32;
CARD32 stringLength B32; /* 0 on error */
CARD32 width B32;
CARD32 height B32;
CARD32 pad1 B32;
CARD32 pad2 B32;
CARD32 pad3 B32;
} xAppleDRICreateSharedBufferReply;
#define sz_xAppleDRICreateSharedBufferReply 32
typedef struct
{
CARD8 reqType;
CARD8 driReqType;
CARD16 length B16;
CARD32 screen B32;
CARD32 drawable B32;
} xAppleDRISwapBuffersReq;
#define sz_xAppleDRISwapBuffersReq 12
typedef struct
{
CARD8 reqType; /*1 */
CARD8 driReqType; /*2 */
CARD16 length B16; /*4 */
CARD32 screen B32; /*8 */
CARD32 drawable B32; /*12 */
} xAppleDRICreatePixmapReq;
#define sz_xAppleDRICreatePixmapReq 12
typedef struct
{
BYTE type; /*1 */
BOOL pad1; /*2 */
CARD16 sequenceNumber B16; /*4 */
CARD32 length B32; /*8 */
CARD32 width B32; /*12 */
CARD32 height B32; /*16 */
CARD32 pitch B32; /*20 */
CARD32 bpp B32; /*24 */
CARD32 size B32; /*28 */
CARD32 stringLength B32; /*32 */
} xAppleDRICreatePixmapReply;
#define sz_xAppleDRICreatePixmapReply 32
typedef struct
{
CARD8 reqType; /*1 */
CARD8 driReqType; /*2 */
CARD16 length B16; /*4 */
CARD32 drawable B32; /*8 */
} xAppleDRIDestroyPixmapReq;
#define sz_xAppleDRIDestroyPixmapReq 8
#ifdef _APPLEDRI_SERVER_
void AppleDRISendEvent(
#if NeedFunctionPrototypes
int /* type */ ,
unsigned int /* mask */ ,
int /* which */ ,
int /* arg */
#endif
);
#endif /* _APPLEDRI_SERVER_ */
#endif /* _APPLEDRISTR_H_ */
+231
View File
@@ -0,0 +1,231 @@
#include "glxclient.h"
#include "glxextensions.h"
#include "glxconfig.h"
/*
** GLX_SGI_swap_control
*/
int
glXSwapIntervalSGI(int interval)
{
(void) interval;
return 0;
}
/*
** GLX_MESA_swap_control
*/
int
glXSwapIntervalMESA(unsigned int interval)
{
(void) interval;
return GLX_BAD_CONTEXT;
}
int
glXGetSwapIntervalMESA(void)
{
return 0;
}
/*
** GLX_SGI_video_sync
*/
int
glXGetVideoSyncSGI(unsigned int *count)
{
(void) count;
return GLX_BAD_CONTEXT;
}
int
glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
(void) count;
return GLX_BAD_CONTEXT;
}
/*
** GLX_OML_sync_control
*/
Bool
glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
int64_t * ust, int64_t * msc, int64_t * sbc)
{
(void) dpy;
(void) drawable;
(void) ust;
(void) msc;
(void) sbc;
return False;
}
int64_t
glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
int64_t target_msc, int64_t divisor, int64_t remainder)
{
(void) dpy;
(void) drawable;
(void) target_msc;
(void) divisor;
(void) remainder;
return 0;
}
Bool
glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t * ust,
int64_t * msc, int64_t * sbc)
{
(void) dpy;
(void) drawable;
(void) target_msc;
(void) divisor;
(void) remainder;
(void) ust;
(void) msc;
(void) sbc;
return False;
}
Bool
glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
int64_t target_sbc, int64_t * ust,
int64_t * msc, int64_t * sbc)
{
(void) dpy;
(void) drawable;
(void) target_sbc;
(void) ust;
(void) msc;
(void) sbc;
return False;
}
Bool
glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
{
(void) dpy;
(void) d;
return False;
}
_X_EXPORT GLXPixmap
glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
Pixmap pixmap, Colormap cmap)
{
(void) dpy;
(void) visual;
(void) pixmap;
(void) cmap;
return 0;
}
/**
* GLX_MESA_copy_sub_buffer
*/
void
glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
int x, int y, int width, int height)
{
(void) dpy;
(void) drawable;
(void) x;
(void) y;
(void) width;
(void) height;
}
_X_EXPORT void
glXQueryGLXPbufferSGIX(Display * dpy, GLXDrawable drawable,
int attribute, unsigned int *value)
{
(void) dpy;
(void) drawable;
(void) attribute;
(void) value;
}
_X_EXPORT GLXDrawable
glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfig config,
unsigned int width, unsigned int height,
int *attrib_list)
{
(void) dpy;
(void) config;
(void) width;
(void) height;
(void) attrib_list;
return None;
}
#if 0
/* GLX_SGIX_fbconfig */
_X_EXPORT int
glXGetFBConfigAttribSGIX(Display * dpy, void *config, int a, int *b)
{
(void) dpy;
(void) config;
(void) a;
(void) b;
return 0;
}
_X_EXPORT void *
glXChooseFBConfigSGIX(Display * dpy, int a, int *b, int *c)
{
(void) dpy;
(void) a;
(void) b;
(void) c;
return NULL;
}
_X_EXPORT GLXPixmap
glXCreateGLXPixmapWithConfigSGIX(Display * dpy, void *config, Pixmap p)
{
(void) dpy;
(void) config;
(void) p;
return None;
}
_X_EXPORT GLXContext
glXCreateContextWithConfigSGIX(Display * dpy, void *config, int a,
GLXContext b, Bool c)
{
(void) dpy;
(void) config;
(void) a;
(void) b;
(void) c;
return NULL;
}
_X_EXPORT XVisualInfo *
glXGetVisualFromFBConfigSGIX(Display * dpy, void *config)
{
(void) dpy;
(void) config;
return NULL;
}
_X_EXPORT void *
glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * visinfo)
{
(void) dpy;
(void) visinfo;
return NULL;
}
#endif
+44
View File
@@ -0,0 +1,44 @@
# Copyright © 2017 Jon Turney
# SPDX-License-Identifier: MIT
# library for native GL on macos
files_libappleglx = files(
'apple_cgl.c',
'apple_cgl.h',
'appledri.c',
'appledri.h',
'appledristr.h',
'apple_glapi.c',
'apple_glx.c',
'apple_glx_context.c',
'apple_glx_context.h',
'apple_glx_drawable.c',
'apple_glx_drawable.h',
'apple_glx.h',
'apple_glx_log.c',
'apple_glx_log.h',
'apple_glx_pbuffer.c',
'apple_glx_pixmap.c',
'apple_glx_surface.c',
'apple_visual.c',
'apple_visual.h',
'apple_xgl_api.h',
'apple_xgl_api_read.c',
'apple_xgl_api_stereo.c',
'apple_xgl_api_viewport.c',
'glx_empty.c',
)
dep_xplugin = null_dep
if with_dri_platform == 'apple'
dep_xplugin = meson.get_compiler('c').find_library('Xplugin')
endif
libappleglx = static_library(
'glxapple',
[files_libappleglx, main_dispatch_h],
include_directories: [inc_mesa, inc_glx, inc_src, inc_include, inc_glapi, inc_gallium, inc_loader],
dependencies: [dep_xext, dep_xplugin],
gnu_symbol_visibility : 'hidden',
build_by_default: false,
)