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