Path: blob/21.2-virgl/src/glx/apple/apple_glx_pbuffer.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/* Must be before OpenGL.framework is included. Remove once fixed:30* <rdar://problem/7872773>31*/32#include <GL/gl.h>33#include <GL/glext.h>34#define __gltypes_h_ 13536/* Must be first for:37* <rdar://problem/6953344>38*/39#include "apple_glx_context.h"40#include "apple_glx_drawable.h"4142#include <stdbool.h>43#include <stdlib.h>44#include <pthread.h>45#include <assert.h>46#include "glxclient.h"47#include "apple_glx.h"48#include "glxconfig.h"49#include "apple_cgl.h"50#include "util/debug.h"5152/* mesa defines in glew.h, Apple in glext.h.53* Due to namespace nightmares, just do it here.54*/55#ifndef GL_TEXTURE_RECTANGLE_EXT56#define GL_TEXTURE_RECTANGLE_EXT 0x84F557#endif5859static bool pbuffer_make_current(struct apple_glx_context *ac,60struct apple_glx_drawable *d);6162static void pbuffer_destroy(Display * dpy, struct apple_glx_drawable *d);6364static struct apple_glx_drawable_callbacks callbacks = {65.type = APPLE_GLX_DRAWABLE_PBUFFER,66.make_current = pbuffer_make_current,67.destroy = pbuffer_destroy68};697071/* Return true if an error occurred. */72bool73pbuffer_make_current(struct apple_glx_context *ac,74struct apple_glx_drawable *d)75{76struct apple_glx_pbuffer *pbuf = &d->types.pbuffer;77CGLError cglerr;7879assert(APPLE_GLX_DRAWABLE_PBUFFER == d->type);8081cglerr = apple_cgl.set_pbuffer(ac->context_obj, pbuf->buffer_obj, 0, 0, 0);8283if (kCGLNoError != cglerr) {84fprintf(stderr, "set_pbuffer: %s\n", apple_cgl.error_string(cglerr));85return true;86}8788if (!ac->made_current) {89apple_glapi_oglfw_viewport_scissor(0, 0, pbuf->width, pbuf->height);90ac->made_current = true;91}9293apple_glx_diagnostic("made pbuffer drawable 0x%lx current\n", d->drawable);9495return false;96}9798void99pbuffer_destroy(Display * dpy, struct apple_glx_drawable *d)100{101struct apple_glx_pbuffer *pbuf = &d->types.pbuffer;102103assert(APPLE_GLX_DRAWABLE_PBUFFER == d->type);104105apple_glx_diagnostic("destroying pbuffer for drawable 0x%lx\n",106d->drawable);107108apple_cgl.destroy_pbuffer(pbuf->buffer_obj);109XFreePixmap(dpy, pbuf->xid);110}111112/* Return true if an error occurred. */113bool114apple_glx_pbuffer_destroy(Display * dpy, GLXPbuffer pbuf)115{116return !apple_glx_drawable_destroy_by_type(dpy, pbuf,117APPLE_GLX_DRAWABLE_PBUFFER);118}119120/* Return true if an error occurred. */121bool122apple_glx_pbuffer_create(Display * dpy, GLXFBConfig config,123int width, int height, int *errorcode,124GLXPbuffer * result)125{126struct apple_glx_drawable *d;127struct apple_glx_pbuffer *pbuf = NULL;128CGLError err;129Window root;130int screen;131Pixmap xid;132struct glx_config *modes = (struct glx_config *) config;133134root = DefaultRootWindow(dpy);135screen = DefaultScreen(dpy);136137/*138* This pixmap is only used for a persistent XID.139* The XC-MISC extension cleans up XIDs and reuses them transparently,140* so we need to retain a server-side reference.141*/142xid = XCreatePixmap(dpy, root, (unsigned int) 1,143(unsigned int) 1, DefaultDepth(dpy, screen));144145if (None == xid) {146*errorcode = BadAlloc;147return true;148}149150if (apple_glx_drawable_create(dpy, screen, xid, &d, &callbacks)) {151*errorcode = BadAlloc;152return true;153}154155/* The lock is held in d from create onward. */156pbuf = &d->types.pbuffer;157158pbuf->xid = xid;159pbuf->width = width;160pbuf->height = height;161162err = apple_cgl.create_pbuffer(width, height, GL_TEXTURE_RECTANGLE_EXT,163(modes->alphaBits > 0) ? GL_RGBA : GL_RGB,1640, &pbuf->buffer_obj);165166if (kCGLNoError != err) {167d->unlock(d);168d->destroy(d);169*errorcode = BadMatch;170return true;171}172173pbuf->fbconfigID = modes->fbconfigID;174175pbuf->event_mask = 0;176177*result = pbuf->xid;178179d->unlock(d);180181return false;182}183184185186/* Return true if an error occurred. */187static bool188get_max_size(int *widthresult, int *heightresult)189{190CGLContextObj oldcontext;191GLint ar[2];192193oldcontext = apple_cgl.get_current_context();194195if (!oldcontext) {196/*197* There is no current context, so we need to make one in order198* to call glGetInteger.199*/200CGLPixelFormatObj pfobj;201CGLError err;202CGLPixelFormatAttribute attr[10];203int c = 0;204GLint vsref = 0;205CGLContextObj newcontext;206207attr[c++] = kCGLPFAColorSize;208attr[c++] = 32;209attr[c++] = 0;210211err = apple_cgl.choose_pixel_format(attr, &pfobj, &vsref);212if (kCGLNoError != err) {213DebugMessageF("choose_pixel_format error in %s: %s\n", __func__,214apple_cgl.error_string(err));215216return true;217}218219220err = apple_cgl.create_context(pfobj, NULL, &newcontext);221222if (kCGLNoError != err) {223DebugMessageF("create_context error in %s: %s\n", __func__,224apple_cgl.error_string(err));225226apple_cgl.destroy_pixel_format(pfobj);227228return true;229}230231err = apple_cgl.set_current_context(newcontext);232233if (kCGLNoError != err) {234DebugMessageF("set_current_context error in %s: %s\n", __func__,235apple_cgl.error_string(err));236return true;237}238239240glGetIntegerv(GL_MAX_VIEWPORT_DIMS, ar);241242apple_cgl.set_current_context(oldcontext);243apple_cgl.destroy_context(newcontext);244apple_cgl.destroy_pixel_format(pfobj);245}246else {247/* We have a valid context. */248249glGetIntegerv(GL_MAX_VIEWPORT_DIMS, ar);250}251252*widthresult = ar[0];253*heightresult = ar[1];254255return false;256}257258bool259apple_glx_pbuffer_query(GLXPbuffer p, int attr, unsigned int *value)260{261bool result = false;262struct apple_glx_drawable *d;263struct apple_glx_pbuffer *pbuf;264265d = apple_glx_drawable_find_by_type(p, APPLE_GLX_DRAWABLE_PBUFFER,266APPLE_GLX_DRAWABLE_LOCK);267268if (d) {269pbuf = &d->types.pbuffer;270271switch (attr) {272case GLX_WIDTH:273*value = pbuf->width;274result = true;275break;276277case GLX_HEIGHT:278*value = pbuf->height;279result = true;280break;281282case GLX_PRESERVED_CONTENTS:283*value = true;284result = true;285break;286287case GLX_LARGEST_PBUFFER:{288int width, height;289if (get_max_size(&width, &height)) {290fprintf(stderr, "internal error: "291"unable to find the largest pbuffer!\n");292}293else {294*value = width;295result = true;296}297}298break;299300case GLX_FBCONFIG_ID:301*value = pbuf->fbconfigID;302result = true;303break;304}305306d->unlock(d);307}308309return result;310}311312bool313apple_glx_pbuffer_set_event_mask(GLXDrawable drawable, unsigned long mask)314{315struct apple_glx_drawable *d;316bool result = false;317318d = apple_glx_drawable_find_by_type(drawable, APPLE_GLX_DRAWABLE_PBUFFER,319APPLE_GLX_DRAWABLE_LOCK);320321if (d) {322d->types.pbuffer.event_mask = mask;323result = true;324d->unlock(d);325}326327return result;328}329330bool331apple_glx_pbuffer_get_event_mask(GLXDrawable drawable, unsigned long *mask)332{333struct apple_glx_drawable *d;334bool result = false;335336d = apple_glx_drawable_find_by_type(drawable, APPLE_GLX_DRAWABLE_PBUFFER,337APPLE_GLX_DRAWABLE_LOCK);338if (d) {339*mask = d->types.pbuffer.event_mask;340result = true;341d->unlock(d);342}343344return result;345}346347348