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