stw_context.c revision 192f06adca5e79b4824d92dc41186592ed57f71e
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/context.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
47static INLINE struct stw_context *
48stw_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
57BOOL APIENTRY
58DrvCopyContext(
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
88BOOL APIENTRY
89DrvShareLists(
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
118DHGLRC APIENTRY
119DrvCreateContext(
120   HDC hdc )
121{
122   return DrvCreateLayerContext( hdc, 0 );
123}
124
125DHGLRC APIENTRY
126DrvCreateLayerContext(
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
168no_hglrc:
169   ctx->st->destroy(ctx->st);
170no_st_ctx:
171   FREE(ctx);
172no_ctx:
173   return 0;
174}
175
176BOOL APIENTRY
177DrvDeleteContext(
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
207BOOL APIENTRY
208DrvReleaseContext(
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
237DHGLRC
238stw_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
249HDC
250stw_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
261BOOL
262stw_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(&curctx->current_framebuffer, fb);
324
325success:
326   assert(fb);
327   if(fb) {
328      stw_framebuffer_release(fb);
329   }
330
331   return TRUE;
332
333fail:
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 */
343void
344stw_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 */
360void
361stw_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 */
372static 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
715PGLCLTPROCTABLE APIENTRY
716DrvSetContext(
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}
728