1848b8605Smrg/* 2848b8605Smrg Copyright (c) 2009 Apple Inc. 3848b8605Smrg 4848b8605Smrg Permission is hereby granted, free of charge, to any person 5848b8605Smrg obtaining a copy of this software and associated documentation files 6848b8605Smrg (the "Software"), to deal in the Software without restriction, 7848b8605Smrg including without limitation the rights to use, copy, modify, merge, 8848b8605Smrg publish, distribute, sublicense, and/or sell copies of the Software, 9848b8605Smrg and to permit persons to whom the Software is furnished to do so, 10848b8605Smrg subject to the following conditions: 11848b8605Smrg 12848b8605Smrg The above copyright notice and this permission notice shall be 13848b8605Smrg included in all copies or substantial portions of the Software. 14848b8605Smrg 15848b8605Smrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16848b8605Smrg EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17848b8605Smrg MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18848b8605Smrg NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT 19848b8605Smrg HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20848b8605Smrg WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21848b8605Smrg OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22848b8605Smrg DEALINGS IN THE SOFTWARE. 23848b8605Smrg 24848b8605Smrg Except as contained in this notice, the name(s) of the above 25848b8605Smrg copyright holders shall not be used in advertising or otherwise to 26848b8605Smrg promote the sale, use or other dealings in this Software without 27848b8605Smrg prior written authorization. 28848b8605Smrg*/ 29848b8605Smrg 30848b8605Smrg#include <stdio.h> 31848b8605Smrg#include <stdlib.h> 32848b8605Smrg#include <pthread.h> 33848b8605Smrg#include <fcntl.h> 34848b8605Smrg#include <sys/types.h> 35848b8605Smrg#include <sys/mman.h> 36848b8605Smrg#include <unistd.h> 37848b8605Smrg#include <assert.h> 38848b8605Smrg#include "apple_glx.h" 39848b8605Smrg#include "apple_cgl.h" 40848b8605Smrg#include "apple_visual.h" 41848b8605Smrg#include "apple_glx_drawable.h" 42848b8605Smrg#include "appledri.h" 43848b8605Smrg#include "glxconfig.h" 44848b8605Smrg 45848b8605Smrgstatic bool pixmap_make_current(struct apple_glx_context *ac, 46848b8605Smrg struct apple_glx_drawable *d); 47848b8605Smrg 48848b8605Smrgstatic void pixmap_destroy(Display * dpy, struct apple_glx_drawable *d); 49848b8605Smrg 50848b8605Smrgstatic struct apple_glx_drawable_callbacks callbacks = { 51848b8605Smrg .type = APPLE_GLX_DRAWABLE_PIXMAP, 52848b8605Smrg .make_current = pixmap_make_current, 53848b8605Smrg .destroy = pixmap_destroy 54848b8605Smrg}; 55848b8605Smrg 56848b8605Smrgstatic bool 57848b8605Smrgpixmap_make_current(struct apple_glx_context *ac, 58848b8605Smrg struct apple_glx_drawable *d) 59848b8605Smrg{ 60848b8605Smrg CGLError cglerr; 61848b8605Smrg struct apple_glx_pixmap *p = &d->types.pixmap; 62848b8605Smrg 63848b8605Smrg assert(APPLE_GLX_DRAWABLE_PIXMAP == d->type); 64848b8605Smrg 65848b8605Smrg cglerr = apple_cgl.set_current_context(p->context_obj); 66848b8605Smrg 67848b8605Smrg if (kCGLNoError != cglerr) { 68848b8605Smrg fprintf(stderr, "set current context: %s\n", 69848b8605Smrg apple_cgl.error_string(cglerr)); 70848b8605Smrg return true; 71848b8605Smrg } 72848b8605Smrg 73848b8605Smrg cglerr = apple_cgl.set_off_screen(p->context_obj, p->width, p->height, 74848b8605Smrg p->pitch, p->buffer); 75848b8605Smrg 76848b8605Smrg if (kCGLNoError != cglerr) { 77848b8605Smrg fprintf(stderr, "set off screen: %s\n", apple_cgl.error_string(cglerr)); 78848b8605Smrg 79848b8605Smrg return true; 80848b8605Smrg } 81848b8605Smrg 82848b8605Smrg if (!ac->made_current) { 83848b8605Smrg apple_glapi_oglfw_viewport_scissor(0, 0, p->width, p->height); 84848b8605Smrg ac->made_current = true; 85848b8605Smrg } 86848b8605Smrg 87848b8605Smrg return false; 88848b8605Smrg} 89848b8605Smrg 90848b8605Smrgstatic void 91848b8605Smrgpixmap_destroy(Display * dpy, struct apple_glx_drawable *d) 92848b8605Smrg{ 93848b8605Smrg struct apple_glx_pixmap *p = &d->types.pixmap; 94848b8605Smrg 95848b8605Smrg if (p->pixel_format_obj) 96848b8605Smrg (void) apple_cgl.destroy_pixel_format(p->pixel_format_obj); 97848b8605Smrg 98848b8605Smrg if (p->context_obj) 99848b8605Smrg (void) apple_cgl.destroy_context(p->context_obj); 100848b8605Smrg 101848b8605Smrg XAppleDRIDestroyPixmap(dpy, p->xpixmap); 102848b8605Smrg 103848b8605Smrg if (p->buffer) { 104848b8605Smrg if (munmap(p->buffer, p->size)) 105848b8605Smrg perror("munmap"); 106848b8605Smrg 107848b8605Smrg if (-1 == close(p->fd)) 108848b8605Smrg perror("close"); 109848b8605Smrg 110848b8605Smrg if (shm_unlink(p->path)) 111848b8605Smrg perror("shm_unlink"); 112848b8605Smrg } 113848b8605Smrg 114848b8605Smrg apple_glx_diagnostic("destroyed pixmap buffer for: 0x%lx\n", d->drawable); 115848b8605Smrg} 116848b8605Smrg 117848b8605Smrg/* Return true if an error occurred. */ 118848b8605Smrgbool 119848b8605Smrgapple_glx_pixmap_create(Display * dpy, int screen, Pixmap pixmap, 120848b8605Smrg const void *mode) 121848b8605Smrg{ 122848b8605Smrg struct apple_glx_drawable *d; 123848b8605Smrg struct apple_glx_pixmap *p; 124848b8605Smrg bool double_buffered; 125848b8605Smrg bool uses_stereo; 126848b8605Smrg CGLError error; 127848b8605Smrg const struct glx_config *cmodes = mode; 128848b8605Smrg 129848b8605Smrg if (apple_glx_drawable_create(dpy, screen, pixmap, &d, &callbacks)) 130848b8605Smrg return true; 131848b8605Smrg 132848b8605Smrg /* d is locked and referenced at this point. */ 133848b8605Smrg 134848b8605Smrg p = &d->types.pixmap; 135848b8605Smrg 136848b8605Smrg p->xpixmap = pixmap; 137848b8605Smrg p->buffer = NULL; 138848b8605Smrg 139848b8605Smrg if (!XAppleDRICreatePixmap(dpy, screen, pixmap, 140848b8605Smrg &p->width, &p->height, &p->pitch, &p->bpp, 141848b8605Smrg &p->size, p->path, PATH_MAX)) { 142848b8605Smrg d->unlock(d); 143848b8605Smrg d->destroy(d); 144848b8605Smrg return true; 145848b8605Smrg } 146848b8605Smrg 147848b8605Smrg p->fd = shm_open(p->path, O_RDWR, 0); 148848b8605Smrg 149848b8605Smrg if (p->fd < 0) { 150848b8605Smrg perror("shm_open"); 151848b8605Smrg d->unlock(d); 152848b8605Smrg d->destroy(d); 153848b8605Smrg return true; 154848b8605Smrg } 155848b8605Smrg 156848b8605Smrg p->buffer = mmap(NULL, p->size, PROT_READ | PROT_WRITE, 157848b8605Smrg MAP_FILE | MAP_SHARED, p->fd, 0); 158848b8605Smrg 159848b8605Smrg if (MAP_FAILED == p->buffer) { 160848b8605Smrg perror("mmap"); 161848b8605Smrg d->unlock(d); 162848b8605Smrg d->destroy(d); 163848b8605Smrg return true; 164848b8605Smrg } 165848b8605Smrg 166848b8605Smrg apple_visual_create_pfobj(&p->pixel_format_obj, mode, &double_buffered, 167848b8605Smrg &uses_stereo, /*offscreen */ true); 168848b8605Smrg 169848b8605Smrg error = apple_cgl.create_context(p->pixel_format_obj, NULL, 170848b8605Smrg &p->context_obj); 171848b8605Smrg 172848b8605Smrg if (kCGLNoError != error) { 173848b8605Smrg d->unlock(d); 174848b8605Smrg d->destroy(d); 175848b8605Smrg return true; 176848b8605Smrg } 177848b8605Smrg 178848b8605Smrg p->fbconfigID = cmodes->fbconfigID; 179848b8605Smrg 180848b8605Smrg d->unlock(d); 181848b8605Smrg 182848b8605Smrg apple_glx_diagnostic("created: pixmap buffer for 0x%lx\n", d->drawable); 183848b8605Smrg 184848b8605Smrg return false; 185848b8605Smrg} 186848b8605Smrg 187848b8605Smrgbool 188848b8605Smrgapple_glx_pixmap_query(GLXPixmap pixmap, int attr, unsigned int *value) 189848b8605Smrg{ 190848b8605Smrg struct apple_glx_drawable *d; 191848b8605Smrg struct apple_glx_pixmap *p; 192848b8605Smrg bool result = false; 193848b8605Smrg 194848b8605Smrg d = apple_glx_drawable_find_by_type(pixmap, APPLE_GLX_DRAWABLE_PIXMAP, 195848b8605Smrg APPLE_GLX_DRAWABLE_LOCK); 196848b8605Smrg 197848b8605Smrg if (d) { 198848b8605Smrg p = &d->types.pixmap; 199848b8605Smrg 200848b8605Smrg switch (attr) { 201848b8605Smrg case GLX_WIDTH: 202848b8605Smrg *value = p->width; 203848b8605Smrg result = true; 204848b8605Smrg break; 205848b8605Smrg 206848b8605Smrg case GLX_HEIGHT: 207848b8605Smrg *value = p->height; 208848b8605Smrg result = true; 209848b8605Smrg break; 210848b8605Smrg 211848b8605Smrg case GLX_FBCONFIG_ID: 212848b8605Smrg *value = p->fbconfigID; 213848b8605Smrg result = true; 214848b8605Smrg break; 215848b8605Smrg } 216848b8605Smrg 217848b8605Smrg d->unlock(d); 218848b8605Smrg } 219848b8605Smrg 220848b8605Smrg return result; 221848b8605Smrg} 222848b8605Smrg 223848b8605Smrg/* Return true if the type is valid for pixmap. */ 224848b8605Smrgbool 225848b8605Smrgapple_glx_pixmap_destroy(Display * dpy, GLXPixmap pixmap) 226848b8605Smrg{ 227848b8605Smrg return !apple_glx_drawable_destroy_by_type(dpy, pixmap, 228848b8605Smrg APPLE_GLX_DRAWABLE_PIXMAP); 229848b8605Smrg} 230