OSDN Git Service

darwin: Build create_context.c
[android-x86/external-mesa.git] / src / glx / create_context.c
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 #include <limits.h>
25 #include "glxclient.h"
26 #include "glx_error.h"
27 #include <xcb/glx.h>
28 #include <X11/Xlib-xcb.h>
29
30 #include <assert.h>
31
32 #if INT_MAX != 2147483647
33 #error This code requires sizeof(uint32_t) == sizeof(int).
34 #endif
35
36 _X_HIDDEN GLXContext
37 glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
38                            GLXContext share_context, Bool direct,
39                            const int *attrib_list)
40 {
41    xcb_connection_t *const c = XGetXCBConnection(dpy);
42    struct glx_config *const cfg = (struct glx_config *) config;
43    struct glx_context *const share = (struct glx_context *) share_context;
44    struct glx_context *gc = NULL;
45    unsigned num_attribs = 0;
46    struct glx_screen *psc;
47    xcb_generic_error_t *err;
48    xcb_void_cookie_t cookie;
49    unsigned dummy_err = 0;
50
51
52    if (dpy == NULL || cfg == NULL)
53       return NULL;
54
55    /* This means that either the caller passed the wrong display pointer or
56     * one of the internal GLX data structures (probably the fbconfig) has an
57     * error.  There is nothing sensible to do, so return an error.
58     */
59    psc = GetGLXScreenConfigs(dpy, cfg->screen);
60    if (psc == NULL)
61       return NULL;
62
63    assert(cfg->screen == psc->scr);
64
65    /* Count the number of attributes specified by the application.  All
66     * attributes appear in pairs, except the terminating None.
67     */
68    if (attrib_list != NULL) {
69       for (/* empty */; attrib_list[num_attribs * 2] != 0; num_attribs++)
70          /* empty */ ;
71    }
72
73    if (direct && psc->vtable->create_context_attribs) {
74       /* GLX drops the error returned by the driver.  The expectation is that
75        * an error will also be returned by the server.  The server's error
76        * will be delivered to the application.
77        */
78       gc = psc->vtable->create_context_attribs(psc, cfg, share, num_attribs,
79                                                (const uint32_t *) attrib_list,
80                                                &dummy_err);
81    }
82
83    if (gc == NULL) {
84 #ifdef GLX_USE_APPLEGL
85       gc = applegl_create_context(psc, cfg, share, 0);
86 #else
87       gc = indirect_create_context(psc, cfg, share, 0);
88 #endif
89    }
90
91    gc->xid = xcb_generate_id(c);
92    gc->share_xid = (share != NULL) ? share->xid : 0;
93
94    /* The manual pages for glXCreateContext and glXCreateNewContext say:
95     *
96     *     "NULL is returned if execution fails on the client side."
97     *
98     * If the server generates an error, the application is supposed to catch
99     * the protocol error and handle it.  Part of handling the error is freeing
100     * the possibly non-NULL value returned by this function.
101     */
102 #ifdef HAVE_XCB_GLX_CREATE_CONTEXT
103    cookie =
104       xcb_glx_create_context_attribs_arb_checked(c,
105                                                  gc->xid,
106                                                  cfg->fbconfigID,
107                                                  cfg->screen,
108                                                  gc->share_xid,
109                                                  gc->isDirect,
110                                                  num_attribs,
111                                                  (const uint32_t *)
112                                                  attrib_list);
113    err = xcb_request_check(c, cookie);
114 #else
115    /* This is a hugely ugly hack to make things compile on systems that lack
116     * the proper XCB version.
117     */
118    memset(&cookie, 0, sizeof(cookie));
119
120    err = calloc(1, sizeof(*err));
121    err->error_code = BadRequest;
122    err->sequence = dpy->request;
123    err->resource_id = gc->xid;
124    err->minor_code = gc->majorOpcode;
125    err->major_code = 34;
126 #endif
127    if (err != NULL) {
128       gc->vtable->destroy(gc);
129       gc = NULL;
130
131       __glXSendErrorForXcb(dpy, err);
132       free(err);
133    }
134
135    return (GLXContext) gc;
136 }