1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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 TUNGSTEN GRAPHICS 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.
26 **************************************************************************/
30 #include "pipe/p_compiler.h"
31 #include "pipe/p_context.h"
32 #include "pipe/p_state.h"
33 #include "util/u_memory.h"
34 #include "state_tracker/st_api.h"
37 #include "stw_device.h"
38 #include "stw_winsys.h"
39 #include "stw_framebuffer.h"
40 #include "stw_pixelformat.h"
41 #include "stw_context.h"
45 static INLINE struct stw_context *
46 stw_current_context(void)
48 struct st_context_iface *st;
50 st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
52 return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
61 struct stw_context *src;
62 struct stw_context *dst;
68 pipe_mutex_lock( stw_dev->ctx_mutex );
70 src = stw_lookup_context_locked( dhrcSource );
71 dst = stw_lookup_context_locked( dhrcDest );
81 pipe_mutex_unlock( stw_dev->ctx_mutex );
91 struct stw_context *ctx1;
92 struct stw_context *ctx2;
98 pipe_mutex_lock( stw_dev->ctx_mutex );
100 ctx1 = stw_lookup_context_locked( dhglrc1 );
101 ctx2 = stw_lookup_context_locked( dhglrc2 );
103 if (ctx1 && ctx2 && ctx2->st->share)
104 ret = ctx2->st->share(ctx2->st, ctx1->st);
106 pipe_mutex_unlock( stw_dev->ctx_mutex );
115 return DrvCreateLayerContext( hdc, 0 );
119 DrvCreateLayerContext(
124 const struct stw_pixelformat_info *pfi;
125 struct st_context_attribs attribs;
126 struct stw_context *ctx = NULL;
131 if (iLayerPlane != 0)
134 iPixelFormat = GetPixelFormat(hdc);
138 pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
140 ctx = CALLOC_STRUCT( stw_context );
145 ctx->iPixelFormat = iPixelFormat;
147 memset(&attribs, 0, sizeof(attribs));
148 attribs.profile = ST_PROFILE_DEFAULT;
149 attribs.visual = pfi->stvis;
151 ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
152 stw_dev->smapi, &attribs, NULL);
156 ctx->st->st_manager_private = (void *) ctx;
158 pipe_mutex_lock( stw_dev->ctx_mutex );
159 ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
160 pipe_mutex_unlock( stw_dev->ctx_mutex );
167 ctx->st->destroy(ctx->st);
178 struct stw_context *ctx ;
184 pipe_mutex_lock( stw_dev->ctx_mutex );
185 ctx = stw_lookup_context_locked(dhglrc);
186 handle_table_remove(stw_dev->ctx_table, dhglrc);
187 pipe_mutex_unlock( stw_dev->ctx_mutex );
190 struct stw_context *curctx = stw_current_context();
192 /* Unbind current if deleting current context. */
194 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
196 ctx->st->destroy(ctx->st);
209 struct stw_context *ctx;
214 pipe_mutex_lock( stw_dev->ctx_mutex );
215 ctx = stw_lookup_context_locked( dhglrc );
216 pipe_mutex_unlock( stw_dev->ctx_mutex );
221 /* The expectation is that ctx is the same context which is
222 * current for this thread. We should check that and return False
225 if (ctx != stw_current_context())
228 if (stw_make_current( NULL, 0 ) == FALSE)
236 stw_get_current_context( void )
238 struct stw_context *ctx;
240 ctx = stw_current_context();
248 stw_get_current_dc( void )
250 struct stw_context *ctx;
252 ctx = stw_current_context();
264 struct stw_context *curctx = NULL;
265 struct stw_context *ctx = NULL;
266 struct stw_framebuffer *fb = NULL;
272 curctx = stw_current_context();
273 if (curctx != NULL) {
274 if (curctx->dhglrc == dhglrc) {
275 if (curctx->hdc == hdc) {
276 /* Return if already current. */
280 curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
285 pipe_mutex_lock( stw_dev->ctx_mutex );
286 ctx = stw_lookup_context_locked( dhglrc );
287 pipe_mutex_unlock( stw_dev->ctx_mutex );
292 fb = stw_framebuffer_from_hdc( hdc );
294 stw_framebuffer_update(fb);
297 /* Applications should call SetPixelFormat before creating a context,
298 * but not all do, and the opengl32 runtime seems to use a default pixel
299 * format in some cases, so we must create a framebuffer for those here
301 int iPixelFormat = GetPixelFormat(hdc);
303 fb = stw_framebuffer_create( hdc, iPixelFormat );
308 if (fb->iPixelFormat != ctx->iPixelFormat) {
309 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
313 /* Bind the new framebuffer */
316 ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb);
317 stw_framebuffer_reference(&ctx->current_framebuffer, fb);
319 ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
325 stw_framebuffer_release(fb);
328 /* On failure, make the thread's current rendering context not current
329 * before returning */
331 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
335 /* Unreference the previous framebuffer if any. It must be done after
336 * make_current, as it can be referenced inside.
338 if (curctx && curctx != ctx) {
339 stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
346 * Flush the current context if it is bound to the framebuffer.
349 stw_flush_current_locked( struct stw_framebuffer *fb )
351 struct stw_context *ctx = stw_current_context();
353 if (ctx && ctx->current_framebuffer == fb) {
354 ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
359 * Notify the current context that the framebuffer has become invalid.
362 stw_notify_current_locked( struct stw_framebuffer *fb )
364 struct stw_context *ctx = stw_current_context();
366 if (ctx && ctx->current_framebuffer == fb)
367 ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb);
371 * Although WGL allows different dispatch entrypoints per context
373 static const GLCLTPROCTABLE cpt =
375 OPENGL_VERSION_110_ENTRIES,
651 &glGetPolygonStipple,
659 &glGetTexParameterfv,
660 &glGetTexParameteriv,
661 &glGetTexLevelParameterfv,
662 &glGetTexLevelParameteriv,
686 &glDisableClientState,
690 &glEnableClientState,
694 &glInterleavedArrays,
699 &glAreTexturesResident,
702 &glCopyTexSubImage1D,
703 &glCopyTexSubImage2D,
708 &glPrioritizeTextures,
716 PGLCLTPROCTABLE APIENTRY
720 PFN_SETPROCTABLE pfnSetProcTable )
722 PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
724 if (!stw_make_current( hdc, dhglrc ))