stw_context.c revision 33cf477c37535e39858b26caa282e167f1ab04d8
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      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
125static void
126stw_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
139DHGLRC APIENTRY
140DrvCreateContext(
141   HDC hdc )
142{
143   return DrvCreateLayerContext( hdc, 0 );
144}
145
146DHGLRC APIENTRY
147DrvCreateLayerContext(
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
198no_hglrc:
199   st_destroy_context(ctx->st);
200   goto no_pipe; /* st_context_destroy already destroys pipe */
201no_st_ctx:
202   pipe->destroy( pipe );
203no_pipe:
204   FREE(ctx);
205no_ctx:
206   return 0;
207}
208
209BOOL APIENTRY
210DrvDeleteContext(
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 );
230
231      st_destroy_context(ctx->st);
232      FREE(ctx);
233
234      ret = TRUE;
235   }
236
237   return ret;
238}
239
240BOOL APIENTRY
241DrvReleaseContext(
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
270DHGLRC
271stw_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
282HDC
283stw_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
294BOOL
295stw_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 );
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 ))
356      goto fail;
357
358success:
359   assert(fb);
360   if(fb) {
361      stw_framebuffer_update(fb);
362      stw_framebuffer_release(fb);
363   }
364
365   return TRUE;
366
367fail:
368   if(fb)
369      stw_framebuffer_release(fb);
370   st_make_current( NULL, NULL, NULL );
371   return FALSE;
372}
373
374/**
375 * Although WGL allows different dispatch entrypoints per context
376 */
377static 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
720PGLCLTPROCTABLE APIENTRY
721DrvSetContext(
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}
733