Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / state_trackers / wgl / stw_context.c
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
45 static INLINE struct stw_context *
46 stw_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
55 BOOL APIENTRY
56 DrvCopyContext(
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
86 BOOL APIENTRY
87 DrvShareLists(
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
111 DHGLRC APIENTRY
112 DrvCreateContext(
113    HDC hdc )
114 {
115    return DrvCreateLayerContext( hdc, 0 );
116 }
117
118 DHGLRC APIENTRY
119 DrvCreateLayerContext(
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
166 no_hglrc:
167    ctx->st->destroy(ctx->st);
168 no_st_ctx:
169    FREE(ctx);
170 no_ctx:
171    return 0;
172 }
173
174 BOOL APIENTRY
175 DrvDeleteContext(
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
205 BOOL APIENTRY
206 DrvReleaseContext(
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
235 DHGLRC
236 stw_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
247 HDC
248 stw_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
259 BOOL
260 stw_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    BOOL ret = FALSE;
268
269    if (!stw_dev)
270       return FALSE;
271
272    curctx = stw_current_context();
273    if (curctx != NULL) {
274       if (curctx->dhglrc == dhglrc) {
275          if (curctx->hdc == hdc) {
276             /* Return if already current. */
277             return TRUE;
278          }
279       } else {
280          curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
281       }
282    }
283
284    if (dhglrc) {
285       pipe_mutex_lock( stw_dev->ctx_mutex );
286       ctx = stw_lookup_context_locked( dhglrc );
287       pipe_mutex_unlock( stw_dev->ctx_mutex );
288       if (!ctx) {
289          goto fail;
290       }
291
292       fb = stw_framebuffer_from_hdc( hdc );
293       if (fb) {
294          stw_framebuffer_update(fb);
295       }
296       else {
297          /* Applications should call SetPixelFormat before creating a context,
298           * but not all do, and the opengl32 runtime seems to use a default pixel
299           * format in some cases, so we must create a framebuffer for those here
300           */
301          int iPixelFormat = GetPixelFormat(hdc);
302          if (iPixelFormat)
303             fb = stw_framebuffer_create( hdc, iPixelFormat );
304          if (!fb)
305             goto fail;
306       }
307    
308       if (fb->iPixelFormat != ctx->iPixelFormat) {
309          SetLastError(ERROR_INVALID_PIXEL_FORMAT);
310          goto fail;
311       }
312
313       /* Bind the new framebuffer */
314       ctx->hdc = hdc;
315
316       ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb);
317       stw_framebuffer_reference(&ctx->current_framebuffer, fb);
318    } else {
319       ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
320    }
321    
322 fail:
323
324    if (fb) {
325       stw_framebuffer_release(fb);
326    }
327
328    /* On failure, make the thread's current rendering context not current
329     * before returning */
330    if (!ret) {
331       stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
332       ctx = NULL;
333    }
334
335    /* Unreference the previous framebuffer if any. It must be done after
336     * make_current, as it can be referenced inside.
337     */
338    if (curctx && curctx != ctx) {
339       stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
340    }
341
342    return ret;
343 }
344
345 /**
346  * Flush the current context if it is bound to the framebuffer.
347  */
348 void
349 stw_flush_current_locked( struct stw_framebuffer *fb )
350 {
351    struct stw_context *ctx = stw_current_context();
352
353    if (ctx && ctx->current_framebuffer == fb) {
354       ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
355    }
356 }
357
358 /**
359  * Notify the current context that the framebuffer has become invalid.
360  */
361 void
362 stw_notify_current_locked( struct stw_framebuffer *fb )
363 {
364    struct stw_context *ctx = stw_current_context();
365
366    if (ctx && ctx->current_framebuffer == fb)
367       ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb);
368 }
369
370 /**
371  * Although WGL allows different dispatch entrypoints per context
372  */
373 static const GLCLTPROCTABLE cpt =
374 {
375    OPENGL_VERSION_110_ENTRIES,
376    {
377       &glNewList,
378       &glEndList,
379       &glCallList,
380       &glCallLists,
381       &glDeleteLists,
382       &glGenLists,
383       &glListBase,
384       &glBegin,
385       &glBitmap,
386       &glColor3b,
387       &glColor3bv,
388       &glColor3d,
389       &glColor3dv,
390       &glColor3f,
391       &glColor3fv,
392       &glColor3i,
393       &glColor3iv,
394       &glColor3s,
395       &glColor3sv,
396       &glColor3ub,
397       &glColor3ubv,
398       &glColor3ui,
399       &glColor3uiv,
400       &glColor3us,
401       &glColor3usv,
402       &glColor4b,
403       &glColor4bv,
404       &glColor4d,
405       &glColor4dv,
406       &glColor4f,
407       &glColor4fv,
408       &glColor4i,
409       &glColor4iv,
410       &glColor4s,
411       &glColor4sv,
412       &glColor4ub,
413       &glColor4ubv,
414       &glColor4ui,
415       &glColor4uiv,
416       &glColor4us,
417       &glColor4usv,
418       &glEdgeFlag,
419       &glEdgeFlagv,
420       &glEnd,
421       &glIndexd,
422       &glIndexdv,
423       &glIndexf,
424       &glIndexfv,
425       &glIndexi,
426       &glIndexiv,
427       &glIndexs,
428       &glIndexsv,
429       &glNormal3b,
430       &glNormal3bv,
431       &glNormal3d,
432       &glNormal3dv,
433       &glNormal3f,
434       &glNormal3fv,
435       &glNormal3i,
436       &glNormal3iv,
437       &glNormal3s,
438       &glNormal3sv,
439       &glRasterPos2d,
440       &glRasterPos2dv,
441       &glRasterPos2f,
442       &glRasterPos2fv,
443       &glRasterPos2i,
444       &glRasterPos2iv,
445       &glRasterPos2s,
446       &glRasterPos2sv,
447       &glRasterPos3d,
448       &glRasterPos3dv,
449       &glRasterPos3f,
450       &glRasterPos3fv,
451       &glRasterPos3i,
452       &glRasterPos3iv,
453       &glRasterPos3s,
454       &glRasterPos3sv,
455       &glRasterPos4d,
456       &glRasterPos4dv,
457       &glRasterPos4f,
458       &glRasterPos4fv,
459       &glRasterPos4i,
460       &glRasterPos4iv,
461       &glRasterPos4s,
462       &glRasterPos4sv,
463       &glRectd,
464       &glRectdv,
465       &glRectf,
466       &glRectfv,
467       &glRecti,
468       &glRectiv,
469       &glRects,
470       &glRectsv,
471       &glTexCoord1d,
472       &glTexCoord1dv,
473       &glTexCoord1f,
474       &glTexCoord1fv,
475       &glTexCoord1i,
476       &glTexCoord1iv,
477       &glTexCoord1s,
478       &glTexCoord1sv,
479       &glTexCoord2d,
480       &glTexCoord2dv,
481       &glTexCoord2f,
482       &glTexCoord2fv,
483       &glTexCoord2i,
484       &glTexCoord2iv,
485       &glTexCoord2s,
486       &glTexCoord2sv,
487       &glTexCoord3d,
488       &glTexCoord3dv,
489       &glTexCoord3f,
490       &glTexCoord3fv,
491       &glTexCoord3i,
492       &glTexCoord3iv,
493       &glTexCoord3s,
494       &glTexCoord3sv,
495       &glTexCoord4d,
496       &glTexCoord4dv,
497       &glTexCoord4f,
498       &glTexCoord4fv,
499       &glTexCoord4i,
500       &glTexCoord4iv,
501       &glTexCoord4s,
502       &glTexCoord4sv,
503       &glVertex2d,
504       &glVertex2dv,
505       &glVertex2f,
506       &glVertex2fv,
507       &glVertex2i,
508       &glVertex2iv,
509       &glVertex2s,
510       &glVertex2sv,
511       &glVertex3d,
512       &glVertex3dv,
513       &glVertex3f,
514       &glVertex3fv,
515       &glVertex3i,
516       &glVertex3iv,
517       &glVertex3s,
518       &glVertex3sv,
519       &glVertex4d,
520       &glVertex4dv,
521       &glVertex4f,
522       &glVertex4fv,
523       &glVertex4i,
524       &glVertex4iv,
525       &glVertex4s,
526       &glVertex4sv,
527       &glClipPlane,
528       &glColorMaterial,
529       &glCullFace,
530       &glFogf,
531       &glFogfv,
532       &glFogi,
533       &glFogiv,
534       &glFrontFace,
535       &glHint,
536       &glLightf,
537       &glLightfv,
538       &glLighti,
539       &glLightiv,
540       &glLightModelf,
541       &glLightModelfv,
542       &glLightModeli,
543       &glLightModeliv,
544       &glLineStipple,
545       &glLineWidth,
546       &glMaterialf,
547       &glMaterialfv,
548       &glMateriali,
549       &glMaterialiv,
550       &glPointSize,
551       &glPolygonMode,
552       &glPolygonStipple,
553       &glScissor,
554       &glShadeModel,
555       &glTexParameterf,
556       &glTexParameterfv,
557       &glTexParameteri,
558       &glTexParameteriv,
559       &glTexImage1D,
560       &glTexImage2D,
561       &glTexEnvf,
562       &glTexEnvfv,
563       &glTexEnvi,
564       &glTexEnviv,
565       &glTexGend,
566       &glTexGendv,
567       &glTexGenf,
568       &glTexGenfv,
569       &glTexGeni,
570       &glTexGeniv,
571       &glFeedbackBuffer,
572       &glSelectBuffer,
573       &glRenderMode,
574       &glInitNames,
575       &glLoadName,
576       &glPassThrough,
577       &glPopName,
578       &glPushName,
579       &glDrawBuffer,
580       &glClear,
581       &glClearAccum,
582       &glClearIndex,
583       &glClearColor,
584       &glClearStencil,
585       &glClearDepth,
586       &glStencilMask,
587       &glColorMask,
588       &glDepthMask,
589       &glIndexMask,
590       &glAccum,
591       &glDisable,
592       &glEnable,
593       &glFinish,
594       &glFlush,
595       &glPopAttrib,
596       &glPushAttrib,
597       &glMap1d,
598       &glMap1f,
599       &glMap2d,
600       &glMap2f,
601       &glMapGrid1d,
602       &glMapGrid1f,
603       &glMapGrid2d,
604       &glMapGrid2f,
605       &glEvalCoord1d,
606       &glEvalCoord1dv,
607       &glEvalCoord1f,
608       &glEvalCoord1fv,
609       &glEvalCoord2d,
610       &glEvalCoord2dv,
611       &glEvalCoord2f,
612       &glEvalCoord2fv,
613       &glEvalMesh1,
614       &glEvalPoint1,
615       &glEvalMesh2,
616       &glEvalPoint2,
617       &glAlphaFunc,
618       &glBlendFunc,
619       &glLogicOp,
620       &glStencilFunc,
621       &glStencilOp,
622       &glDepthFunc,
623       &glPixelZoom,
624       &glPixelTransferf,
625       &glPixelTransferi,
626       &glPixelStoref,
627       &glPixelStorei,
628       &glPixelMapfv,
629       &glPixelMapuiv,
630       &glPixelMapusv,
631       &glReadBuffer,
632       &glCopyPixels,
633       &glReadPixels,
634       &glDrawPixels,
635       &glGetBooleanv,
636       &glGetClipPlane,
637       &glGetDoublev,
638       &glGetError,
639       &glGetFloatv,
640       &glGetIntegerv,
641       &glGetLightfv,
642       &glGetLightiv,
643       &glGetMapdv,
644       &glGetMapfv,
645       &glGetMapiv,
646       &glGetMaterialfv,
647       &glGetMaterialiv,
648       &glGetPixelMapfv,
649       &glGetPixelMapuiv,
650       &glGetPixelMapusv,
651       &glGetPolygonStipple,
652       &glGetString,
653       &glGetTexEnvfv,
654       &glGetTexEnviv,
655       &glGetTexGendv,
656       &glGetTexGenfv,
657       &glGetTexGeniv,
658       &glGetTexImage,
659       &glGetTexParameterfv,
660       &glGetTexParameteriv,
661       &glGetTexLevelParameterfv,
662       &glGetTexLevelParameteriv,
663       &glIsEnabled,
664       &glIsList,
665       &glDepthRange,
666       &glFrustum,
667       &glLoadIdentity,
668       &glLoadMatrixf,
669       &glLoadMatrixd,
670       &glMatrixMode,
671       &glMultMatrixf,
672       &glMultMatrixd,
673       &glOrtho,
674       &glPopMatrix,
675       &glPushMatrix,
676       &glRotated,
677       &glRotatef,
678       &glScaled,
679       &glScalef,
680       &glTranslated,
681       &glTranslatef,
682       &glViewport,
683       &glArrayElement,
684       &glBindTexture,
685       &glColorPointer,
686       &glDisableClientState,
687       &glDrawArrays,
688       &glDrawElements,
689       &glEdgeFlagPointer,
690       &glEnableClientState,
691       &glIndexPointer,
692       &glIndexub,
693       &glIndexubv,
694       &glInterleavedArrays,
695       &glNormalPointer,
696       &glPolygonOffset,
697       &glTexCoordPointer,
698       &glVertexPointer,
699       &glAreTexturesResident,
700       &glCopyTexImage1D,
701       &glCopyTexImage2D,
702       &glCopyTexSubImage1D,
703       &glCopyTexSubImage2D,
704       &glDeleteTextures,
705       &glGenTextures,
706       &glGetPointerv,
707       &glIsTexture,
708       &glPrioritizeTextures,
709       &glTexSubImage1D,
710       &glTexSubImage2D,
711       &glPopClientAttrib,
712       &glPushClientAttrib
713    }
714 };
715
716 PGLCLTPROCTABLE APIENTRY
717 DrvSetContext(
718    HDC hdc,
719    DHGLRC dhglrc,
720    PFN_SETPROCTABLE pfnSetProcTable )
721 {
722    PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
723
724    if (!stw_make_current( hdc, dhglrc ))
725       r = NULL;
726
727    return r;
728 }