Merge commit 'mesa_7_6_branch' into mesa_7_7_branch
[mesa.git] / src / gallium / state_trackers / wgl / stw_context.c
1 /**************************************************************************
2 *
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
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 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.
25 *
26 **************************************************************************/
27
28 #include <windows.h>
29
30 #include "main/mtypes.h"
31 #include "main/context.h"
32 #include "pipe/p_compiler.h"
33 #include "pipe/p_context.h"
34 #include "state_tracker/st_context.h"
35 #include "state_tracker/st_public.h"
36
37 #ifdef DEBUG
38 #include "trace/tr_screen.h"
39 #include "trace/tr_context.h"
40 #endif
41
42 #include "stw_icd.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"
48 #include "stw_tls.h"
49
50
51 static INLINE struct stw_context *
52 stw_context(GLcontext *glctx)
53 {
54 if(!glctx)
55 return NULL;
56 assert(glctx->DriverCtx);
57 return (struct stw_context *)glctx->DriverCtx;
58 }
59
60 static INLINE struct stw_context *
61 stw_current_context(void)
62 {
63 /* We must check if multiple threads are being used or GET_CURRENT_CONTEXT
64 * might return the current context of the thread first seen. */
65 _glapi_check_multithread();
66
67 {
68 GET_CURRENT_CONTEXT( glctx );
69 return stw_context(glctx);
70 }
71 }
72
73 BOOL APIENTRY
74 DrvCopyContext(
75 DHGLRC dhrcSource,
76 DHGLRC dhrcDest,
77 UINT fuMask )
78 {
79 struct stw_context *src;
80 struct stw_context *dst;
81 BOOL ret = FALSE;
82
83 pipe_mutex_lock( stw_dev->ctx_mutex );
84
85 src = stw_lookup_context_locked( dhrcSource );
86 dst = stw_lookup_context_locked( dhrcDest );
87
88 if (src && dst) {
89 /* FIXME */
90 assert(0);
91 (void) src;
92 (void) dst;
93 (void) fuMask;
94 }
95
96 pipe_mutex_unlock( stw_dev->ctx_mutex );
97
98 return ret;
99 }
100
101 BOOL APIENTRY
102 DrvShareLists(
103 DHGLRC dhglrc1,
104 DHGLRC dhglrc2 )
105 {
106 struct stw_context *ctx1;
107 struct stw_context *ctx2;
108 BOOL ret = FALSE;
109
110 pipe_mutex_lock( stw_dev->ctx_mutex );
111
112 ctx1 = stw_lookup_context_locked( dhglrc1 );
113 ctx2 = stw_lookup_context_locked( dhglrc2 );
114
115 if (ctx1 && ctx2 &&
116 ctx1->iPixelFormat == ctx2->iPixelFormat) {
117 ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
118 }
119
120 pipe_mutex_unlock( stw_dev->ctx_mutex );
121
122 return ret;
123 }
124
125 static void
126 stw_viewport(GLcontext * glctx, GLint x, GLint y,
127 GLsizei width, GLsizei height)
128 {
129 struct stw_context *ctx = (struct stw_context *)glctx->DriverCtx;
130 struct stw_framebuffer *fb;
131
132 fb = stw_framebuffer_from_hdc( ctx->hdc );
133 if(fb) {
134 stw_framebuffer_update(fb);
135 stw_framebuffer_release(fb);
136 }
137 }
138
139 DHGLRC APIENTRY
140 DrvCreateContext(
141 HDC hdc )
142 {
143 return DrvCreateLayerContext( hdc, 0 );
144 }
145
146 DHGLRC APIENTRY
147 DrvCreateLayerContext(
148 HDC hdc,
149 INT iLayerPlane )
150 {
151 int iPixelFormat;
152 const struct stw_pixelformat_info *pfi;
153 GLvisual visual;
154 struct stw_context *ctx = NULL;
155 struct pipe_screen *screen = NULL;
156 struct pipe_context *pipe = NULL;
157
158 if(!stw_dev)
159 return 0;
160
161 if (iLayerPlane != 0)
162 return 0;
163
164 iPixelFormat = GetPixelFormat(hdc);
165 if(!iPixelFormat)
166 return 0;
167
168 pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
169 stw_pixelformat_visual(&visual, pfi);
170
171 ctx = CALLOC_STRUCT( stw_context );
172 if (ctx == NULL)
173 goto no_ctx;
174
175 ctx->hdc = hdc;
176 ctx->iPixelFormat = iPixelFormat;
177
178 screen = stw_dev->screen;
179
180 #ifdef DEBUG
181 /* Unwrap screen */
182 if(stw_dev->trace_running)
183 screen = trace_screen(screen)->screen;
184 #endif
185
186 pipe = stw_dev->stw_winsys->create_context( screen );
187 if (pipe == NULL)
188 goto no_pipe;
189
190 #ifdef DEBUG
191 /* Wrap context */
192 if(stw_dev->trace_running)
193 pipe = trace_context_create(stw_dev->screen, pipe);
194 #endif
195
196 /* pass to stw_flush_frontbuffer as context_private */
197 assert(!pipe->priv);
198 pipe->priv = hdc;
199
200 ctx->st = st_create_context( pipe, &visual, NULL );
201 if (ctx->st == NULL)
202 goto no_st_ctx;
203
204 ctx->st->ctx->DriverCtx = ctx;
205 ctx->st->ctx->Driver.Viewport = stw_viewport;
206
207 pipe_mutex_lock( stw_dev->ctx_mutex );
208 ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
209 pipe_mutex_unlock( stw_dev->ctx_mutex );
210 if (!ctx->dhglrc)
211 goto no_hglrc;
212
213 return ctx->dhglrc;
214
215 no_hglrc:
216 st_destroy_context(ctx->st);
217 goto no_pipe; /* st_context_destroy already destroys pipe */
218 no_st_ctx:
219 pipe->destroy( pipe );
220 no_pipe:
221 FREE(ctx);
222 no_ctx:
223 return 0;
224 }
225
226 BOOL APIENTRY
227 DrvDeleteContext(
228 DHGLRC dhglrc )
229 {
230 struct stw_context *ctx ;
231 BOOL ret = FALSE;
232
233 if (!stw_dev)
234 return FALSE;
235
236 pipe_mutex_lock( stw_dev->ctx_mutex );
237 ctx = stw_lookup_context_locked(dhglrc);
238 handle_table_remove(stw_dev->ctx_table, dhglrc);
239 pipe_mutex_unlock( stw_dev->ctx_mutex );
240
241 if (ctx) {
242 struct stw_context *curctx = stw_current_context();
243
244 /* Unbind current if deleting current context. */
245 if (curctx == ctx)
246 st_make_current( NULL, NULL, NULL );
247
248 st_destroy_context(ctx->st);
249 FREE(ctx);
250
251 ret = TRUE;
252 }
253
254 return ret;
255 }
256
257 BOOL APIENTRY
258 DrvReleaseContext(
259 DHGLRC dhglrc )
260 {
261 struct stw_context *ctx;
262
263 if (!stw_dev)
264 return FALSE;
265
266 pipe_mutex_lock( stw_dev->ctx_mutex );
267 ctx = stw_lookup_context_locked( dhglrc );
268 pipe_mutex_unlock( stw_dev->ctx_mutex );
269
270 if (!ctx)
271 return FALSE;
272
273 /* The expectation is that ctx is the same context which is
274 * current for this thread. We should check that and return False
275 * if not the case.
276 */
277 if (ctx != stw_current_context())
278 return FALSE;
279
280 if (stw_make_current( NULL, 0 ) == FALSE)
281 return FALSE;
282
283 return TRUE;
284 }
285
286
287 DHGLRC
288 stw_get_current_context( void )
289 {
290 struct stw_context *ctx;
291
292 ctx = stw_current_context();
293 if(!ctx)
294 return 0;
295
296 return ctx->dhglrc;
297 }
298
299 HDC
300 stw_get_current_dc( void )
301 {
302 struct stw_context *ctx;
303
304 ctx = stw_current_context();
305 if(!ctx)
306 return NULL;
307
308 return ctx->hdc;
309 }
310
311 BOOL
312 stw_make_current(
313 HDC hdc,
314 DHGLRC dhglrc )
315 {
316 struct stw_context *curctx = NULL;
317 struct stw_context *ctx = NULL;
318 struct stw_framebuffer *fb = NULL;
319
320 if (!stw_dev)
321 goto fail;
322
323 curctx = stw_current_context();
324 if (curctx != NULL) {
325 if (curctx->dhglrc != dhglrc)
326 st_flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
327
328 /* Return if already current. */
329 if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
330 ctx = curctx;
331 fb = stw_framebuffer_from_hdc( hdc );
332 goto success;
333 }
334 }
335
336 if (hdc == NULL || dhglrc == 0) {
337 return st_make_current( NULL, NULL, NULL );
338 }
339
340 pipe_mutex_lock( stw_dev->ctx_mutex );
341 ctx = stw_lookup_context_locked( dhglrc );
342 pipe_mutex_unlock( stw_dev->ctx_mutex );
343 if(!ctx)
344 goto fail;
345
346 fb = stw_framebuffer_from_hdc( hdc );
347 if(!fb) {
348 /* Applications should call SetPixelFormat before creating a context,
349 * but not all do, and the opengl32 runtime seems to use a default pixel
350 * format in some cases, so we must create a framebuffer for those here
351 */
352 int iPixelFormat = GetPixelFormat(hdc);
353 if(iPixelFormat)
354 fb = stw_framebuffer_create( hdc, iPixelFormat );
355 if(!fb)
356 goto fail;
357 }
358
359 if(fb->iPixelFormat != ctx->iPixelFormat)
360 goto fail;
361
362 /* Lazy allocation of the frame buffer */
363 if(!stw_framebuffer_allocate(fb))
364 goto fail;
365
366 /* Bind the new framebuffer */
367 ctx->hdc = hdc;
368
369 /* pass to stw_flush_frontbuffer as context_private */
370 ctx->st->pipe->priv = hdc;
371
372 if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
373 goto fail;
374
375 success:
376 assert(fb);
377 if(fb) {
378 stw_framebuffer_update(fb);
379 stw_framebuffer_release(fb);
380 }
381
382 return TRUE;
383
384 fail:
385 if(fb)
386 stw_framebuffer_release(fb);
387 st_make_current( NULL, NULL, NULL );
388 return FALSE;
389 }
390
391 /**
392 * Although WGL allows different dispatch entrypoints per context
393 */
394 static const GLCLTPROCTABLE cpt =
395 {
396 OPENGL_VERSION_110_ENTRIES,
397 {
398 &glNewList,
399 &glEndList,
400 &glCallList,
401 &glCallLists,
402 &glDeleteLists,
403 &glGenLists,
404 &glListBase,
405 &glBegin,
406 &glBitmap,
407 &glColor3b,
408 &glColor3bv,
409 &glColor3d,
410 &glColor3dv,
411 &glColor3f,
412 &glColor3fv,
413 &glColor3i,
414 &glColor3iv,
415 &glColor3s,
416 &glColor3sv,
417 &glColor3ub,
418 &glColor3ubv,
419 &glColor3ui,
420 &glColor3uiv,
421 &glColor3us,
422 &glColor3usv,
423 &glColor4b,
424 &glColor4bv,
425 &glColor4d,
426 &glColor4dv,
427 &glColor4f,
428 &glColor4fv,
429 &glColor4i,
430 &glColor4iv,
431 &glColor4s,
432 &glColor4sv,
433 &glColor4ub,
434 &glColor4ubv,
435 &glColor4ui,
436 &glColor4uiv,
437 &glColor4us,
438 &glColor4usv,
439 &glEdgeFlag,
440 &glEdgeFlagv,
441 &glEnd,
442 &glIndexd,
443 &glIndexdv,
444 &glIndexf,
445 &glIndexfv,
446 &glIndexi,
447 &glIndexiv,
448 &glIndexs,
449 &glIndexsv,
450 &glNormal3b,
451 &glNormal3bv,
452 &glNormal3d,
453 &glNormal3dv,
454 &glNormal3f,
455 &glNormal3fv,
456 &glNormal3i,
457 &glNormal3iv,
458 &glNormal3s,
459 &glNormal3sv,
460 &glRasterPos2d,
461 &glRasterPos2dv,
462 &glRasterPos2f,
463 &glRasterPos2fv,
464 &glRasterPos2i,
465 &glRasterPos2iv,
466 &glRasterPos2s,
467 &glRasterPos2sv,
468 &glRasterPos3d,
469 &glRasterPos3dv,
470 &glRasterPos3f,
471 &glRasterPos3fv,
472 &glRasterPos3i,
473 &glRasterPos3iv,
474 &glRasterPos3s,
475 &glRasterPos3sv,
476 &glRasterPos4d,
477 &glRasterPos4dv,
478 &glRasterPos4f,
479 &glRasterPos4fv,
480 &glRasterPos4i,
481 &glRasterPos4iv,
482 &glRasterPos4s,
483 &glRasterPos4sv,
484 &glRectd,
485 &glRectdv,
486 &glRectf,
487 &glRectfv,
488 &glRecti,
489 &glRectiv,
490 &glRects,
491 &glRectsv,
492 &glTexCoord1d,
493 &glTexCoord1dv,
494 &glTexCoord1f,
495 &glTexCoord1fv,
496 &glTexCoord1i,
497 &glTexCoord1iv,
498 &glTexCoord1s,
499 &glTexCoord1sv,
500 &glTexCoord2d,
501 &glTexCoord2dv,
502 &glTexCoord2f,
503 &glTexCoord2fv,
504 &glTexCoord2i,
505 &glTexCoord2iv,
506 &glTexCoord2s,
507 &glTexCoord2sv,
508 &glTexCoord3d,
509 &glTexCoord3dv,
510 &glTexCoord3f,
511 &glTexCoord3fv,
512 &glTexCoord3i,
513 &glTexCoord3iv,
514 &glTexCoord3s,
515 &glTexCoord3sv,
516 &glTexCoord4d,
517 &glTexCoord4dv,
518 &glTexCoord4f,
519 &glTexCoord4fv,
520 &glTexCoord4i,
521 &glTexCoord4iv,
522 &glTexCoord4s,
523 &glTexCoord4sv,
524 &glVertex2d,
525 &glVertex2dv,
526 &glVertex2f,
527 &glVertex2fv,
528 &glVertex2i,
529 &glVertex2iv,
530 &glVertex2s,
531 &glVertex2sv,
532 &glVertex3d,
533 &glVertex3dv,
534 &glVertex3f,
535 &glVertex3fv,
536 &glVertex3i,
537 &glVertex3iv,
538 &glVertex3s,
539 &glVertex3sv,
540 &glVertex4d,
541 &glVertex4dv,
542 &glVertex4f,
543 &glVertex4fv,
544 &glVertex4i,
545 &glVertex4iv,
546 &glVertex4s,
547 &glVertex4sv,
548 &glClipPlane,
549 &glColorMaterial,
550 &glCullFace,
551 &glFogf,
552 &glFogfv,
553 &glFogi,
554 &glFogiv,
555 &glFrontFace,
556 &glHint,
557 &glLightf,
558 &glLightfv,
559 &glLighti,
560 &glLightiv,
561 &glLightModelf,
562 &glLightModelfv,
563 &glLightModeli,
564 &glLightModeliv,
565 &glLineStipple,
566 &glLineWidth,
567 &glMaterialf,
568 &glMaterialfv,
569 &glMateriali,
570 &glMaterialiv,
571 &glPointSize,
572 &glPolygonMode,
573 &glPolygonStipple,
574 &glScissor,
575 &glShadeModel,
576 &glTexParameterf,
577 &glTexParameterfv,
578 &glTexParameteri,
579 &glTexParameteriv,
580 &glTexImage1D,
581 &glTexImage2D,
582 &glTexEnvf,
583 &glTexEnvfv,
584 &glTexEnvi,
585 &glTexEnviv,
586 &glTexGend,
587 &glTexGendv,
588 &glTexGenf,
589 &glTexGenfv,
590 &glTexGeni,
591 &glTexGeniv,
592 &glFeedbackBuffer,
593 &glSelectBuffer,
594 &glRenderMode,
595 &glInitNames,
596 &glLoadName,
597 &glPassThrough,
598 &glPopName,
599 &glPushName,
600 &glDrawBuffer,
601 &glClear,
602 &glClearAccum,
603 &glClearIndex,
604 &glClearColor,
605 &glClearStencil,
606 &glClearDepth,
607 &glStencilMask,
608 &glColorMask,
609 &glDepthMask,
610 &glIndexMask,
611 &glAccum,
612 &glDisable,
613 &glEnable,
614 &glFinish,
615 &glFlush,
616 &glPopAttrib,
617 &glPushAttrib,
618 &glMap1d,
619 &glMap1f,
620 &glMap2d,
621 &glMap2f,
622 &glMapGrid1d,
623 &glMapGrid1f,
624 &glMapGrid2d,
625 &glMapGrid2f,
626 &glEvalCoord1d,
627 &glEvalCoord1dv,
628 &glEvalCoord1f,
629 &glEvalCoord1fv,
630 &glEvalCoord2d,
631 &glEvalCoord2dv,
632 &glEvalCoord2f,
633 &glEvalCoord2fv,
634 &glEvalMesh1,
635 &glEvalPoint1,
636 &glEvalMesh2,
637 &glEvalPoint2,
638 &glAlphaFunc,
639 &glBlendFunc,
640 &glLogicOp,
641 &glStencilFunc,
642 &glStencilOp,
643 &glDepthFunc,
644 &glPixelZoom,
645 &glPixelTransferf,
646 &glPixelTransferi,
647 &glPixelStoref,
648 &glPixelStorei,
649 &glPixelMapfv,
650 &glPixelMapuiv,
651 &glPixelMapusv,
652 &glReadBuffer,
653 &glCopyPixels,
654 &glReadPixels,
655 &glDrawPixels,
656 &glGetBooleanv,
657 &glGetClipPlane,
658 &glGetDoublev,
659 &glGetError,
660 &glGetFloatv,
661 &glGetIntegerv,
662 &glGetLightfv,
663 &glGetLightiv,
664 &glGetMapdv,
665 &glGetMapfv,
666 &glGetMapiv,
667 &glGetMaterialfv,
668 &glGetMaterialiv,
669 &glGetPixelMapfv,
670 &glGetPixelMapuiv,
671 &glGetPixelMapusv,
672 &glGetPolygonStipple,
673 &glGetString,
674 &glGetTexEnvfv,
675 &glGetTexEnviv,
676 &glGetTexGendv,
677 &glGetTexGenfv,
678 &glGetTexGeniv,
679 &glGetTexImage,
680 &glGetTexParameterfv,
681 &glGetTexParameteriv,
682 &glGetTexLevelParameterfv,
683 &glGetTexLevelParameteriv,
684 &glIsEnabled,
685 &glIsList,
686 &glDepthRange,
687 &glFrustum,
688 &glLoadIdentity,
689 &glLoadMatrixf,
690 &glLoadMatrixd,
691 &glMatrixMode,
692 &glMultMatrixf,
693 &glMultMatrixd,
694 &glOrtho,
695 &glPopMatrix,
696 &glPushMatrix,
697 &glRotated,
698 &glRotatef,
699 &glScaled,
700 &glScalef,
701 &glTranslated,
702 &glTranslatef,
703 &glViewport,
704 &glArrayElement,
705 &glBindTexture,
706 &glColorPointer,
707 &glDisableClientState,
708 &glDrawArrays,
709 &glDrawElements,
710 &glEdgeFlagPointer,
711 &glEnableClientState,
712 &glIndexPointer,
713 &glIndexub,
714 &glIndexubv,
715 &glInterleavedArrays,
716 &glNormalPointer,
717 &glPolygonOffset,
718 &glTexCoordPointer,
719 &glVertexPointer,
720 &glAreTexturesResident,
721 &glCopyTexImage1D,
722 &glCopyTexImage2D,
723 &glCopyTexSubImage1D,
724 &glCopyTexSubImage2D,
725 &glDeleteTextures,
726 &glGenTextures,
727 &glGetPointerv,
728 &glIsTexture,
729 &glPrioritizeTextures,
730 &glTexSubImage1D,
731 &glTexSubImage2D,
732 &glPopClientAttrib,
733 &glPushClientAttrib
734 }
735 };
736
737 PGLCLTPROCTABLE APIENTRY
738 DrvSetContext(
739 HDC hdc,
740 DHGLRC dhglrc,
741 PFN_SETPROCTABLE pfnSetProcTable )
742 {
743 PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
744
745 if (!stw_make_current( hdc, dhglrc ))
746 r = NULL;
747
748 return r;
749 }