dri_context.c revision 7e302168798907e6e0b08d96141d97f04958a73e
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_pp_query(struct dri_context *ctx) 43{ 44 unsigned int i; 45 46 for (i = 0; i < PP_FILTERS; i++) { 47 ctx->pp_enabled[i] = driQueryOptioni(&ctx->optionCache, pp_filters[i].name); 48 } 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 // Context successfully created. See if post-processing is requested. 99 dri_pp_query(ctx); 100 101 ctx->pp = pp_init(screen->base.screen, ctx->pp_enabled); 102 103 return GL_TRUE; 104 105 fail: 106 if (ctx && ctx->st) 107 ctx->st->destroy(ctx->st); 108 109 FREE(ctx); 110 return GL_FALSE; 111} 112 113void 114dri_destroy_context(__DRIcontext * cPriv) 115{ 116 struct dri_context *ctx = dri_context(cPriv); 117 118 /* note: we are freeing values and nothing more because 119 * driParseConfigFiles allocated values only - the rest 120 * is owned by screen optionCache. 121 */ 122 FREE(ctx->optionCache.values); 123 124 /* No particular reason to wait for command completion before 125 * destroying a context, but it is probably worthwhile flushing it 126 * to avoid having to add code elsewhere to cope with flushing a 127 * partially destroyed context. 128 */ 129 ctx->st->flush(ctx->st, 0, NULL); 130 ctx->st->destroy(ctx->st); 131 132 if (ctx->pp) pp_free(ctx->pp); 133 134 FREE(ctx); 135} 136 137GLboolean 138dri_unbind_context(__DRIcontext * cPriv) 139{ 140 /* dri_util.c ensures cPriv is not null */ 141 struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); 142 struct dri_context *ctx = dri_context(cPriv); 143 struct st_api *stapi = screen->st_api; 144 145 if (--ctx->bind_count == 0) { 146 if (ctx->st == ctx->stapi->get_current(ctx->stapi)) { 147 ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); 148 stapi->make_current(stapi, NULL, NULL, NULL); 149 } 150 } 151 152 return GL_TRUE; 153} 154 155GLboolean 156dri_make_current(__DRIcontext * cPriv, 157 __DRIdrawable * driDrawPriv, 158 __DRIdrawable * driReadPriv) 159{ 160 /* dri_util.c ensures cPriv is not null */ 161 struct dri_context *ctx = dri_context(cPriv); 162 struct dri_drawable *draw = dri_drawable(driDrawPriv); 163 struct dri_drawable *read = dri_drawable(driReadPriv); 164 struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi); 165 166 if (old_st && old_st != ctx->st) 167 old_st->flush(old_st, ST_FLUSH_FRONT, NULL); 168 169 ++ctx->bind_count; 170 171 if (!driDrawPriv && !driReadPriv) 172 return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL); 173 else if (!driDrawPriv || !driReadPriv) 174 return GL_FALSE; 175 176 if (ctx->dPriv != driDrawPriv) { 177 ctx->dPriv = driDrawPriv; 178 draw->texture_stamp = driDrawPriv->lastStamp - 1; 179 } 180 if (ctx->rPriv != driReadPriv) { 181 ctx->rPriv = driReadPriv; 182 read->texture_stamp = driReadPriv->lastStamp - 1; 183 } 184 185 ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base); 186 187 // This is ok to call here. If they are already init, it's a no-op. 188 if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL] 189 && ctx->pp) 190 pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0, 191 draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0, 192 draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]); 193 194 return GL_TRUE; 195} 196 197struct dri_context * 198dri_get_current(__DRIscreen *sPriv) 199{ 200 struct dri_screen *screen = dri_screen(sPriv); 201 struct st_api *stapi = screen->st_api; 202 struct st_context_iface *st; 203 204 st = stapi->get_current(stapi); 205 206 return (struct dri_context *) (st) ? st->st_manager_private : NULL; 207} 208 209/* vim: set sw=3 ts=8 sts=3 expandtab: */ 210