Path: blob/21.2-virgl/src/glx/apple/apple_glx_pixmap.c
4560 views
/*1Copyright (c) 2009 Apple Inc.23Permission is hereby granted, free of charge, to any person4obtaining a copy of this software and associated documentation files5(the "Software"), to deal in the Software without restriction,6including without limitation the rights to use, copy, modify, merge,7publish, distribute, sublicense, and/or sell copies of the Software,8and to permit persons to whom the Software is furnished to do so,9subject to the following conditions:1011The above copyright notice and this permission notice shall be12included in all copies or substantial portions of the Software.1314THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT18HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,19WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21DEALINGS IN THE SOFTWARE.2223Except as contained in this notice, the name(s) of the above24copyright holders shall not be used in advertising or otherwise to25promote the sale, use or other dealings in this Software without26prior written authorization.27*/2829#include <stdio.h>30#include <stdlib.h>31#include <pthread.h>32#include <fcntl.h>33#include <sys/types.h>34#include <sys/mman.h>35#include <unistd.h>36#include <assert.h>37#include "apple_glx.h"38#include "apple_cgl.h"39#include "apple_visual.h"40#include "apple_glx_drawable.h"41#include "appledri.h"42#include "glxconfig.h"4344static bool pixmap_make_current(struct apple_glx_context *ac,45struct apple_glx_drawable *d);4647static void pixmap_destroy(Display * dpy, struct apple_glx_drawable *d);4849static struct apple_glx_drawable_callbacks callbacks = {50.type = APPLE_GLX_DRAWABLE_PIXMAP,51.make_current = pixmap_make_current,52.destroy = pixmap_destroy53};5455static bool56pixmap_make_current(struct apple_glx_context *ac,57struct apple_glx_drawable *d)58{59CGLError cglerr;60struct apple_glx_pixmap *p = &d->types.pixmap;6162assert(APPLE_GLX_DRAWABLE_PIXMAP == d->type);6364cglerr = apple_cgl.set_current_context(p->context_obj);6566if (kCGLNoError != cglerr) {67fprintf(stderr, "set current context: %s\n",68apple_cgl.error_string(cglerr));69return true;70}7172cglerr = apple_cgl.set_off_screen(p->context_obj, p->width, p->height,73p->pitch, p->buffer);7475if (kCGLNoError != cglerr) {76fprintf(stderr, "set off screen: %s\n", apple_cgl.error_string(cglerr));7778return true;79}8081if (!ac->made_current) {82apple_glapi_oglfw_viewport_scissor(0, 0, p->width, p->height);83ac->made_current = true;84}8586return false;87}8889static void90pixmap_destroy(Display * dpy, struct apple_glx_drawable *d)91{92struct apple_glx_pixmap *p = &d->types.pixmap;9394if (p->pixel_format_obj)95(void) apple_cgl.destroy_pixel_format(p->pixel_format_obj);9697if (p->context_obj)98(void) apple_cgl.destroy_context(p->context_obj);99100XAppleDRIDestroyPixmap(dpy, p->xpixmap);101102if (p->buffer) {103if (munmap(p->buffer, p->size))104perror("munmap");105106if (-1 == close(p->fd))107perror("close");108109if (shm_unlink(p->path))110perror("shm_unlink");111}112113apple_glx_diagnostic("destroyed pixmap buffer for: 0x%lx\n", d->drawable);114}115116/* Return true if an error occurred. */117bool118apple_glx_pixmap_create(Display * dpy, int screen, Pixmap pixmap,119const void *mode)120{121struct apple_glx_drawable *d;122struct apple_glx_pixmap *p;123bool double_buffered;124bool uses_stereo;125CGLError error;126const struct glx_config *cmodes = mode;127128if (apple_glx_drawable_create(dpy, screen, pixmap, &d, &callbacks))129return true;130131/* d is locked and referenced at this point. */132133p = &d->types.pixmap;134135p->xpixmap = pixmap;136p->buffer = NULL;137138if (!XAppleDRICreatePixmap(dpy, screen, pixmap,139&p->width, &p->height, &p->pitch, &p->bpp,140&p->size, p->path, PATH_MAX)) {141d->unlock(d);142d->destroy(d);143return true;144}145146p->fd = shm_open(p->path, O_RDWR, 0);147148if (p->fd < 0) {149perror("shm_open");150d->unlock(d);151d->destroy(d);152return true;153}154155p->buffer = mmap(NULL, p->size, PROT_READ | PROT_WRITE,156MAP_FILE | MAP_SHARED, p->fd, 0);157158if (MAP_FAILED == p->buffer) {159perror("mmap");160d->unlock(d);161d->destroy(d);162return true;163}164165apple_visual_create_pfobj(&p->pixel_format_obj, mode, &double_buffered,166&uses_stereo, /*offscreen */ true);167168error = apple_cgl.create_context(p->pixel_format_obj, NULL,169&p->context_obj);170171if (kCGLNoError != error) {172d->unlock(d);173d->destroy(d);174return true;175}176177p->fbconfigID = cmodes->fbconfigID;178179d->unlock(d);180181apple_glx_diagnostic("created: pixmap buffer for 0x%lx\n", d->drawable);182183return false;184}185186bool187apple_glx_pixmap_query(GLXPixmap pixmap, int attr, unsigned int *value)188{189struct apple_glx_drawable *d;190struct apple_glx_pixmap *p;191bool result = false;192193d = apple_glx_drawable_find_by_type(pixmap, APPLE_GLX_DRAWABLE_PIXMAP,194APPLE_GLX_DRAWABLE_LOCK);195196if (d) {197p = &d->types.pixmap;198199switch (attr) {200case GLX_WIDTH:201*value = p->width;202result = true;203break;204205case GLX_HEIGHT:206*value = p->height;207result = true;208break;209210case GLX_FBCONFIG_ID:211*value = p->fbconfigID;212result = true;213break;214}215216d->unlock(d);217}218219return result;220}221222/* Return true if the type is valid for pixmap. */223bool224apple_glx_pixmap_destroy(Display * dpy, GLXPixmap pixmap)225{226return !apple_glx_drawable_destroy_by_type(dpy, pixmap,227APPLE_GLX_DRAWABLE_PIXMAP);228}229230231