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