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