dri_context.c revision 94ccc31ba4f64ac480137fd90f1ded44d2072f6e
1/************************************************************************** 2 * 3 * Copyright 2009, VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27/* 28 * Author: Keith Whitwell <keithw@vmware.com> 29 * Author: Jakob Bornecrantz <wallbraker@gmail.com> 30 */ 31 32#include "utils.h" 33 34#include "dri_screen.h" 35#include "dri_drawable.h" 36#include "dri_context.h" 37 38#include "pipe/p_context.h" 39#include "state_tracker/st_context.h" 40 41static void 42dri_init_extensions(struct dri_context *ctx) 43{ 44 struct st_context *st = (struct st_context *) ctx->st; 45 46 /* New extensions should be added in mesa/state_tracker/st_extensions.c 47 * and not in this file. */ 48 driInitExtensions(st->ctx, NULL, GL_FALSE); 49} 50 51GLboolean 52dri_create_context(gl_api api, const struct gl_config * visual, 53 __DRIcontext * cPriv, void *sharedContextPrivate) 54{ 55 __DRIscreen *sPriv = cPriv->driScreenPriv; 56 struct dri_screen *screen = dri_screen(sPriv); 57 struct st_api *stapi = screen->st_api; 58 struct dri_context *ctx = NULL; 59 struct st_context_iface *st_share = NULL; 60 struct st_context_attribs attribs; 61 62 memset(&attribs, 0, sizeof(attribs)); 63 switch (api) { 64 case API_OPENGLES: 65 attribs.profile = ST_PROFILE_OPENGL_ES1; 66 break; 67 case API_OPENGLES2: 68 attribs.profile = ST_PROFILE_OPENGL_ES2; 69 break; 70 default: 71 attribs.profile = ST_PROFILE_DEFAULT; 72 break; 73 } 74 75 if (sharedContextPrivate) { 76 st_share = ((struct dri_context *)sharedContextPrivate)->st; 77 } 78 79 ctx = CALLOC_STRUCT(dri_context); 80 if (ctx == NULL) 81 goto fail; 82 83 cPriv->driverPrivate = ctx; 84 ctx->cPriv = cPriv; 85 ctx->sPriv = sPriv; 86 ctx->lock = screen->drmLock; 87 88 driParseConfigFiles(&ctx->optionCache, 89 &screen->optionCache, sPriv->myNum, "dri"); 90 91 dri_fill_st_visual(&attribs.visual, screen, visual); 92 ctx->st = stapi->create_context(stapi, &screen->base, &attribs, st_share); 93 if (ctx->st == NULL) 94 goto fail; 95 ctx->st->st_manager_private = (void *) ctx; 96 ctx->stapi = stapi; 97 98 /* 99 * libmesagallium.a that this state tracker will be linked to expects 100 * OpenGL's _glapi_table. That is, it expects libGL.so instead of 101 * libGLESv1_CM.so or libGLESv2.so. As there is no clean way to know the 102 * shared library the app links to, use the api as a simple check. 103 * It might be as well to simply remove this function call though. 104 */ 105 if (api == API_OPENGL) 106 dri_init_extensions(ctx); 107 108 return GL_TRUE; 109 110 fail: 111 if (ctx && ctx->st) 112 ctx->st->destroy(ctx->st); 113 114 FREE(ctx); 115 return GL_FALSE; 116} 117 118void 119dri_destroy_context(__DRIcontext * cPriv) 120{ 121 struct dri_context *ctx = dri_context(cPriv); 122 123 /* note: we are freeing values and nothing more because 124 * driParseConfigFiles allocated values only - the rest 125 * is owned by screen optionCache. 126 */ 127 FREE(ctx->optionCache.values); 128 129 /* No particular reason to wait for command completion before 130 * destroying a context, but it is probably worthwhile flushing it 131 * to avoid having to add code elsewhere to cope with flushing a 132 * partially destroyed context. 133 */ 134 ctx->st->flush(ctx->st, 0, NULL); 135 ctx->st->destroy(ctx->st); 136 137 FREE(ctx); 138} 139 140GLboolean 141dri_unbind_context(__DRIcontext * cPriv) 142{ 143 /* dri_util.c ensures cPriv is not null */ 144 struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); 145 struct dri_context *ctx = dri_context(cPriv); 146 struct dri_drawable *draw = dri_drawable(ctx->dPriv); 147 struct dri_drawable *read = dri_drawable(ctx->rPriv); 148 struct st_api *stapi = screen->st_api; 149 150 if (--ctx->bind_count == 0) { 151 if (ctx->st == ctx->stapi->get_current(ctx->stapi)) { 152 ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); 153 stapi->make_current(stapi, NULL, NULL, NULL); 154 draw->context = NULL; 155 read->context = NULL; 156 } 157 } 158 159 return GL_TRUE; 160} 161 162GLboolean 163dri_make_current(__DRIcontext * cPriv, 164 __DRIdrawable * driDrawPriv, 165 __DRIdrawable * driReadPriv) 166{ 167 /* dri_util.c ensures cPriv is not null */ 168 struct dri_context *ctx = dri_context(cPriv); 169 struct dri_drawable *draw = dri_drawable(driDrawPriv); 170 struct dri_drawable *read = dri_drawable(driReadPriv); 171 struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi); 172 173 if (old_st && old_st != ctx->st) 174 old_st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL); 175 176 ++ctx->bind_count; 177 178 if (!driDrawPriv && !driReadPriv) 179 return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL); 180 else if (!driDrawPriv || !driReadPriv) 181 return GL_FALSE; 182 183 draw->context = ctx; 184 if (ctx->dPriv != driDrawPriv) { 185 ctx->dPriv = driDrawPriv; 186 draw->texture_stamp = driDrawPriv->lastStamp - 1; 187 } 188 read->context = ctx; 189 if (ctx->rPriv != driReadPriv) { 190 ctx->rPriv = driReadPriv; 191 read->texture_stamp = driReadPriv->lastStamp - 1; 192 } 193 194 ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base); 195 196 return GL_TRUE; 197} 198 199struct dri_context * 200dri_get_current(__DRIscreen *sPriv) 201{ 202 struct dri_screen *screen = dri_screen(sPriv); 203 struct st_api *stapi = screen->st_api; 204 struct st_context_iface *st; 205 206 st = stapi->get_current(stapi); 207 208 return (struct dri_context *) (st) ? st->st_manager_private : NULL; 209} 210 211/* vim: set sw=3 ts=8 sts=3 expandtab: */ 212