dri_context.c revision d61f07318c8678901b948fdaa8ccdf37aa3203e9
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 "dri_screen.h"
33
34#include "dri_drawable.h"
35#include "state_tracker/drm_api.h"
36#include "state_tracker/dri1_api.h"
37#include "state_tracker/st_public.h"
38#include "state_tracker/st_context.h"
39#include "pipe/p_context.h"
40
41#include "dri_context.h"
42
43#include "util/u_memory.h"
44
45GLboolean
46dri_create_context(const __GLcontextModes * visual,
47		   __DRIcontext * cPriv, void *sharedContextPrivate)
48{
49   __DRIscreen *sPriv = cPriv->driScreenPriv;
50   struct dri_screen *screen = dri_screen(sPriv);
51   struct dri_context *ctx = NULL;
52   struct st_context *st_share = NULL;
53
54   if (sharedContextPrivate) {
55      st_share = ((struct dri_context *)sharedContextPrivate)->st;
56   }
57
58   ctx = CALLOC_STRUCT(dri_context);
59   if (ctx == NULL)
60      goto fail;
61
62   cPriv->driverPrivate = ctx;
63   ctx->cPriv = cPriv;
64   ctx->sPriv = sPriv;
65   ctx->lock = screen->drmLock;
66   ctx->d_stamp = -1;
67   ctx->r_stamp = -1;
68
69   driParseConfigFiles(&ctx->optionCache,
70		       &screen->optionCache, sPriv->myNum, "dri");
71
72   ctx->pipe = screen->api->create_context(screen->api, screen->pipe_screen);
73
74   if (ctx->pipe == NULL)
75      goto fail;
76
77   /* used in dri_flush_frontbuffer */
78   ctx->pipe->priv = ctx;
79
80   ctx->st = st_create_context(ctx->pipe, visual, st_share);
81   if (ctx->st == NULL)
82      goto fail;
83
84   dri_init_extensions(ctx);
85
86   return GL_TRUE;
87
88 fail:
89   if (ctx && ctx->st)
90      st_destroy_context(ctx->st);
91
92   if (ctx && ctx->pipe)
93      ctx->pipe->destroy(ctx->pipe);
94
95   FREE(ctx);
96   return FALSE;
97}
98
99void
100dri_destroy_context(__DRIcontext * cPriv)
101{
102   struct dri_context *ctx = dri_context(cPriv);
103
104   /* No particular reason to wait for command completion before
105    * destroying a context, but it is probably worthwhile flushing it
106    * to avoid having to add code elsewhere to cope with flushing a
107    * partially destroyed context.
108    */
109   st_flush(ctx->st, 0, NULL);
110
111   /* Also frees ctx->pipe?
112    */
113   st_destroy_context(ctx->st);
114
115   FREE(ctx);
116}
117
118GLboolean
119dri_unbind_context(__DRIcontext * cPriv)
120{
121   if (cPriv) {
122      struct dri_context *ctx = dri_context(cPriv);
123
124      if (--ctx->bind_count == 0) {
125	 if (ctx->st && ctx->st == st_get_current()) {
126	    st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
127	    st_make_current(NULL, NULL, NULL);
128	 }
129      }
130   }
131
132   return GL_TRUE;
133}
134
135GLboolean
136dri_make_current(__DRIcontext * cPriv,
137		 __DRIdrawable * driDrawPriv,
138		 __DRIdrawable * driReadPriv)
139{
140   if (cPriv) {
141      struct dri_context *ctx = dri_context(cPriv);
142      struct dri_drawable *draw = dri_drawable(driDrawPriv);
143      struct dri_drawable *read = dri_drawable(driReadPriv);
144      struct st_context *old_st = st_get_current();
145
146      if (old_st && old_st != ctx->st)
147	 st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
148
149      ++ctx->bind_count;
150
151      if (ctx->dPriv != driDrawPriv) {
152	 ctx->dPriv = driDrawPriv;
153	 ctx->d_stamp = driDrawPriv->lastStamp - 1;
154      }
155      if (ctx->rPriv != driReadPriv) {
156	 ctx->rPriv = driReadPriv;
157	 ctx->r_stamp = driReadPriv->lastStamp - 1;
158      }
159
160      st_make_current(ctx->st, draw->stfb, read->stfb);
161
162      if (__dri1_api_hooks) {
163	 dri1_update_drawables(ctx, draw, read);
164      } else {
165	 if (driDrawPriv)
166	    dri_get_buffers(driDrawPriv);
167	 if (driDrawPriv != driReadPriv && driReadPriv)
168	    dri_get_buffers(driReadPriv);
169      }
170   } else {
171      st_make_current(NULL, NULL, NULL);
172   }
173
174   return GL_TRUE;
175}
176
177static void
178st_dri_lock(struct pipe_context *pipe)
179{
180   dri_lock((struct dri_context *)pipe->priv);
181}
182
183static void
184st_dri_unlock(struct pipe_context *pipe)
185{
186   dri_unlock((struct dri_context *)pipe->priv);
187}
188
189static boolean
190st_dri_is_locked(struct pipe_context *pipe)
191{
192   return ((struct dri_context *)pipe->priv)->isLocked;
193}
194
195static boolean
196st_dri_lost_lock(struct pipe_context *pipe)
197{
198   return ((struct dri_context *)pipe->priv)->wsLostLock;
199}
200
201static void
202st_dri_clear_lost_lock(struct pipe_context *pipe)
203{
204   ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
205}
206
207struct dri1_api_lock_funcs dri1_lf = {
208   .lock = st_dri_lock,
209   .unlock = st_dri_unlock,
210   .is_locked = st_dri_is_locked,
211   .is_lock_lost = st_dri_lost_lock,
212   .clear_lost_lock = st_dri_clear_lost_lock
213};
214
215/* vim: set sw=3 ts=8 sts=3 expandtab: */
216