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 #define WGL_WGLEXT_PROTOTYPES
33 #include <GL/wglext.h>
35 #include "pipe/p_compiler.h"
36 #include "pipe/p_context.h"
37 #include "pipe/p_state.h"
38 #include "util/u_memory.h"
39 #include "util/u_atomic.h"
40 #include "state_tracker/st_api.h"
43 #include "stw_device.h"
44 #include "stw_winsys.h"
45 #include "stw_framebuffer.h"
46 #include "stw_pixelformat.h"
47 #include "stw_context.h"
51 static INLINE
struct stw_context
*
52 stw_current_context(void)
54 struct st_context_iface
*st
;
56 st
= (stw_dev
) ? stw_dev
->stapi
->get_current(stw_dev
->stapi
) : NULL
;
58 return (struct stw_context
*) ((st
) ? st
->st_manager_private
: NULL
);
67 struct stw_context
*src
;
68 struct stw_context
*dst
;
74 pipe_mutex_lock( stw_dev
->ctx_mutex
);
76 src
= stw_lookup_context_locked( dhrcSource
);
77 dst
= stw_lookup_context_locked( dhrcDest
);
87 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
97 struct stw_context
*ctx1
;
98 struct stw_context
*ctx2
;
104 pipe_mutex_lock( stw_dev
->ctx_mutex
);
106 ctx1
= stw_lookup_context_locked( dhglrc1
);
107 ctx2
= stw_lookup_context_locked( dhglrc2
);
109 if (ctx1
&& ctx2
&& ctx2
->st
->share
)
110 ret
= ctx2
->st
->share(ctx2
->st
, ctx1
->st
);
112 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
121 return DrvCreateLayerContext( hdc
, 0 );
125 DrvCreateLayerContext(
129 return stw_create_context_attribs(hdc
, iLayerPlane
, 0, 1, 0, 0, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
);
133 stw_create_context_attribs(
136 DHGLRC hShareContext
,
137 int majorVersion
, int minorVersion
,
138 int contextFlags
, int profileMask
)
141 const struct stw_pixelformat_info
*pfi
;
142 struct st_context_attribs attribs
;
143 struct stw_context
*ctx
= NULL
;
144 struct stw_context
*shareCtx
= NULL
;
149 if (iLayerPlane
!= 0)
152 iPixelFormat
= GetPixelFormat(hdc
);
156 pfi
= stw_pixelformat_get_info( iPixelFormat
- 1 );
158 if (hShareContext
!= 0) {
159 pipe_mutex_lock( stw_dev
->ctx_mutex
);
160 shareCtx
= stw_lookup_context_locked( hShareContext
);
161 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
164 ctx
= CALLOC_STRUCT( stw_context
);
169 ctx
->iPixelFormat
= iPixelFormat
;
171 memset(&attribs
, 0, sizeof(attribs
));
172 attribs
.visual
= pfi
->stvis
;
173 attribs
.major
= majorVersion
;
174 attribs
.minor
= minorVersion
;
175 if (contextFlags
& WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
)
176 attribs
.flags
|= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE
;
177 if (contextFlags
& WGL_CONTEXT_DEBUG_BIT_ARB
)
178 attribs
.flags
|= ST_CONTEXT_FLAG_DEBUG
;
180 /* There are no profiles before OpenGL 3.2. The
181 * WGL_ARB_create_context_profile spec says:
183 * "If the requested OpenGL version is less than 3.2,
184 * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality of the
185 * context is determined solely by the requested version."
187 * The spec also says:
189 * "The default value for WGL_CONTEXT_PROFILE_MASK_ARB is
190 * WGL_CONTEXT_CORE_PROFILE_BIT_ARB."
192 attribs
.profile
= ST_PROFILE_DEFAULT
;
193 if ((major
> 3 || (major
== 3 && minor
>= 2))
194 && ((profileMask
& WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
) == 0))
195 attribs
.profile
= ST_PROFILE_OPENGL_CORE
;
197 ctx
->st
= stw_dev
->stapi
->create_context(stw_dev
->stapi
,
198 stw_dev
->smapi
, &attribs
, shareCtx
? shareCtx
->st
: NULL
);
202 ctx
->st
->st_manager_private
= (void *) ctx
;
204 pipe_mutex_lock( stw_dev
->ctx_mutex
);
205 ctx
->dhglrc
= handle_table_add(stw_dev
->ctx_table
, ctx
);
206 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
213 ctx
->st
->destroy(ctx
->st
);
224 struct stw_context
*ctx
;
230 pipe_mutex_lock( stw_dev
->ctx_mutex
);
231 ctx
= stw_lookup_context_locked(dhglrc
);
232 handle_table_remove(stw_dev
->ctx_table
, dhglrc
);
233 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
236 struct stw_context
*curctx
= stw_current_context();
238 /* Unbind current if deleting current context. */
240 stw_dev
->stapi
->make_current(stw_dev
->stapi
, NULL
, NULL
, NULL
);
242 ctx
->st
->destroy(ctx
->st
);
255 struct stw_context
*ctx
;
260 pipe_mutex_lock( stw_dev
->ctx_mutex
);
261 ctx
= stw_lookup_context_locked( dhglrc
);
262 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
267 /* The expectation is that ctx is the same context which is
268 * current for this thread. We should check that and return False
271 if (ctx
!= stw_current_context())
274 if (stw_make_current( NULL
, 0 ) == FALSE
)
282 stw_get_current_context( void )
284 struct stw_context
*ctx
;
286 ctx
= stw_current_context();
294 stw_get_current_dc( void )
296 struct stw_context
*ctx
;
298 ctx
= stw_current_context();
310 struct stw_context
*curctx
= NULL
;
311 struct stw_context
*ctx
= NULL
;
312 struct stw_framebuffer
*fb
= NULL
;
318 curctx
= stw_current_context();
319 if (curctx
!= NULL
) {
320 if (curctx
->dhglrc
== dhglrc
) {
321 if (curctx
->hdc
== hdc
) {
322 /* Return if already current. */
326 curctx
->st
->flush(curctx
->st
, ST_FLUSH_FRONT
, NULL
);
331 pipe_mutex_lock( stw_dev
->ctx_mutex
);
332 ctx
= stw_lookup_context_locked( dhglrc
);
333 pipe_mutex_unlock( stw_dev
->ctx_mutex
);
338 fb
= stw_framebuffer_from_hdc( hdc
);
340 stw_framebuffer_update(fb
);
343 /* Applications should call SetPixelFormat before creating a context,
344 * but not all do, and the opengl32 runtime seems to use a default pixel
345 * format in some cases, so we must create a framebuffer for those here
347 int iPixelFormat
= GetPixelFormat(hdc
);
349 fb
= stw_framebuffer_create( hdc
, iPixelFormat
);
354 if (fb
->iPixelFormat
!= ctx
->iPixelFormat
) {
355 SetLastError(ERROR_INVALID_PIXEL_FORMAT
);
359 /* Bind the new framebuffer */
362 ret
= stw_dev
->stapi
->make_current(stw_dev
->stapi
, ctx
->st
, fb
->stfb
, fb
->stfb
);
363 stw_framebuffer_reference(&ctx
->current_framebuffer
, fb
);
365 ret
= stw_dev
->stapi
->make_current(stw_dev
->stapi
, NULL
, NULL
, NULL
);
371 stw_framebuffer_release(fb
);
374 /* On failure, make the thread's current rendering context not current
375 * before returning */
377 stw_dev
->stapi
->make_current(stw_dev
->stapi
, NULL
, NULL
, NULL
);
381 /* Unreference the previous framebuffer if any. It must be done after
382 * make_current, as it can be referenced inside.
384 if (curctx
&& curctx
!= ctx
) {
385 stw_framebuffer_reference(&curctx
->current_framebuffer
, NULL
);
392 * Flush the current context if it is bound to the framebuffer.
395 stw_flush_current_locked( struct stw_framebuffer
*fb
)
397 struct stw_context
*ctx
= stw_current_context();
399 if (ctx
&& ctx
->current_framebuffer
== fb
) {
400 ctx
->st
->flush(ctx
->st
, ST_FLUSH_FRONT
, NULL
);
405 * Notify the current context that the framebuffer has become invalid.
408 stw_notify_current_locked( struct stw_framebuffer
*fb
)
410 p_atomic_inc(&fb
->stfb
->stamp
);
414 * Although WGL allows different dispatch entrypoints per context
416 static const GLCLTPROCTABLE cpt
=
418 OPENGL_VERSION_110_ENTRIES
,
694 &glGetPolygonStipple
,
702 &glGetTexParameterfv
,
703 &glGetTexParameteriv
,
704 &glGetTexLevelParameterfv
,
705 &glGetTexLevelParameteriv
,
729 &glDisableClientState
,
733 &glEnableClientState
,
737 &glInterleavedArrays
,
742 &glAreTexturesResident
,
745 &glCopyTexSubImage1D
,
746 &glCopyTexSubImage2D
,
751 &glPrioritizeTextures
,
759 PGLCLTPROCTABLE APIENTRY
763 PFN_SETPROCTABLE pfnSetProcTable
)
765 PGLCLTPROCTABLE r
= (PGLCLTPROCTABLE
)&cpt
;
767 if (!stw_make_current( hdc
, dhglrc
))