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