~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/wgl/stw_context.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2008 VMware, Inc.
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 VMWARE 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
 
#define WGL_WGLEXT_PROTOTYPES
31
 
 
32
 
#include <GL/gl.h>
33
 
#include <GL/wglext.h>
34
 
 
35
 
#include "pipe/p_compiler.h"
36
 
#include "pipe/p_context.h"
37
 
#include "pipe/p_state.h"
38
 
#include "util/compiler.h"
39
 
#include "util/u_memory.h"
40
 
#include "util/u_atomic.h"
41
 
#include "hud/hud_context.h"
42
 
 
43
 
#include "gldrv.h"
44
 
#include "stw_device.h"
45
 
#include "stw_winsys.h"
46
 
#include "stw_framebuffer.h"
47
 
#include "stw_pixelformat.h"
48
 
#include "stw_context.h"
49
 
#include "stw_tls.h"
50
 
 
51
 
 
52
 
struct stw_context *
53
 
stw_current_context(void)
54
 
{
55
 
   struct st_context_iface *st;
56
 
 
57
 
   st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;
58
 
 
59
 
   return (struct stw_context *) ((st) ? st->st_manager_private : NULL);
60
 
}
61
 
 
62
 
 
63
 
BOOL APIENTRY
64
 
DrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask)
65
 
{
66
 
   struct stw_context *src;
67
 
   struct stw_context *dst;
68
 
   BOOL ret = FALSE;
69
 
 
70
 
   if (!stw_dev)
71
 
      return FALSE;
72
 
 
73
 
   stw_lock_contexts(stw_dev);
74
 
 
75
 
   src = stw_lookup_context_locked( dhrcSource );
76
 
   dst = stw_lookup_context_locked( dhrcDest );
77
 
 
78
 
   if (src && dst) {
79
 
      /* FIXME */
80
 
      assert(0);
81
 
      (void) src;
82
 
      (void) dst;
83
 
      (void) fuMask;
84
 
   }
85
 
 
86
 
   stw_unlock_contexts(stw_dev);
87
 
 
88
 
   return ret;
89
 
}
90
 
 
91
 
 
92
 
BOOL APIENTRY
93
 
DrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2)
94
 
{
95
 
   struct stw_context *ctx1;
96
 
   struct stw_context *ctx2;
97
 
   BOOL ret = FALSE;
98
 
 
99
 
   if (!stw_dev)
100
 
      return FALSE;
101
 
 
102
 
   stw_lock_contexts(stw_dev);
103
 
 
104
 
   ctx1 = stw_lookup_context_locked( dhglrc1 );
105
 
   ctx2 = stw_lookup_context_locked( dhglrc2 );
106
 
 
107
 
   if (ctx1 && ctx2 && ctx2->st->share) {
108
 
      ret = ctx2->st->share(ctx2->st, ctx1->st);
109
 
      ctx1->shared = TRUE;
110
 
      ctx2->shared = TRUE;
111
 
   }
112
 
 
113
 
   stw_unlock_contexts(stw_dev);
114
 
 
115
 
   return ret;
116
 
}
117
 
 
118
 
 
119
 
DHGLRC APIENTRY
120
 
DrvCreateContext(HDC hdc)
121
 
{
122
 
   return DrvCreateLayerContext( hdc, 0 );
123
 
}
124
 
 
125
 
 
126
 
DHGLRC APIENTRY
127
 
DrvCreateLayerContext(HDC hdc, INT iLayerPlane)
128
 
{
129
 
   struct stw_context *ctx = stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,
130
 
                                                        WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
131
 
                                                        0);
132
 
   if (!ctx)
133
 
      return 0;
134
 
 
135
 
   DHGLRC ret = stw_create_context_handle(ctx, 0);
136
 
   if (!ret)
137
 
      stw_destroy_context(ctx);
138
 
 
139
 
   return ret;
140
 
}
141
 
 
142
 
 
143
 
/**
144
 
 * Return the stw pixel format that most closely matches the pixel format
145
 
 * on HDC.
146
 
 * Used to get a pixel format when SetPixelFormat() hasn't been called before.
147
 
 */
148
 
static int
149
 
get_matching_pixel_format(HDC hdc)
150
 
{
151
 
   int iPixelFormat = GetPixelFormat(hdc);
152
 
   PIXELFORMATDESCRIPTOR pfd;
153
 
 
154
 
   if (!iPixelFormat)
155
 
      return 0;
156
 
   if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd))
157
 
      return 0;
158
 
   return stw_pixelformat_choose(hdc, &pfd);
159
 
}
160
 
 
161
 
 
162
 
/**
163
 
 * Called via DrvCreateContext(), DrvCreateLayerContext() and
164
 
 * wglCreateContextAttribsARB() to actually create a rendering context.
165
 
 */
166
 
struct stw_context *
167
 
stw_create_context_attribs(HDC hdc, INT iLayerPlane, struct stw_context *shareCtx,
168
 
                           int majorVersion, int minorVersion,
169
 
                           int contextFlags, int profileMask,
170
 
                           int iPixelFormat)
171
 
{
172
 
   const struct stw_pixelformat_info *pfi;
173
 
   struct st_context_attribs attribs;
174
 
   struct stw_context *ctx = NULL;
175
 
   enum st_context_error ctx_err = 0;
176
 
 
177
 
   if (!stw_dev)
178
 
      return 0;
179
 
 
180
 
   if (iLayerPlane != 0)
181
 
      return 0;
182
 
 
183
 
   if (!iPixelFormat) {
184
 
      /*
185
 
       * GDI only knows about displayable pixel formats, so determine the pixel
186
 
       * format from the framebuffer.
187
 
       *
188
 
       * This also allows to use a OpenGL DLL / ICD without installing.
189
 
       */
190
 
      struct stw_framebuffer *fb;
191
 
      fb = stw_framebuffer_from_hdc(hdc);
192
 
      if (fb) {
193
 
         iPixelFormat = fb->iPixelFormat;
194
 
         stw_framebuffer_unlock(fb);
195
 
      }
196
 
      else {
197
 
         /* Applications should call SetPixelFormat before creating a context,
198
 
          * but not all do, and the opengl32 runtime seems to use a default
199
 
          * pixel format in some cases, so use that.
200
 
          */
201
 
         iPixelFormat = get_matching_pixel_format(hdc);
202
 
         if (!iPixelFormat)
203
 
            return 0;
204
 
      }
205
 
   }
206
 
 
207
 
   pfi = stw_pixelformat_get_info( iPixelFormat );
208
 
 
209
 
   if (shareCtx != NULL)
210
 
      shareCtx->shared = TRUE;
211
 
 
212
 
   ctx = CALLOC_STRUCT( stw_context );
213
 
   if (ctx == NULL)
214
 
      goto no_ctx;
215
 
 
216
 
   ctx->hDrawDC = hdc;
217
 
   ctx->hReadDC = hdc;
218
 
   ctx->iPixelFormat = iPixelFormat;
219
 
   ctx->shared = shareCtx != NULL;
220
 
 
221
 
   memset(&attribs, 0, sizeof(attribs));
222
 
   attribs.visual = pfi->stvis;
223
 
   attribs.major = majorVersion;
224
 
   attribs.minor = minorVersion;
225
 
   if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
226
 
      attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
227
 
   if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)
228
 
      attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
229
 
 
230
 
   switch (profileMask) {
231
 
   case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
232
 
      /* There are no profiles before OpenGL 3.2.  The
233
 
       * WGL_ARB_create_context_profile spec says:
234
 
       *
235
 
       *     "If the requested OpenGL version is less than 3.2,
236
 
       *     WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality
237
 
       *     of the context is determined solely by the requested version."
238
 
       */
239
 
      if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {
240
 
         attribs.profile = ST_PROFILE_OPENGL_CORE;
241
 
         break;
242
 
      }
243
 
      FALLTHROUGH;
244
 
   case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
245
 
      /*
246
 
       * The spec also says:
247
 
       *
248
 
       *     "If version 3.1 is requested, the context returned may implement
249
 
       *     any of the following versions:
250
 
       *
251
 
       *       * Version 3.1. The GL_ARB_compatibility extension may or may not
252
 
       *         be implemented, as determined by the implementation.
253
 
       *       * The core profile of version 3.2 or greater."
254
 
       *
255
 
       * But Mesa doesn't support GL_ARB_compatibility, while most prevalent
256
 
       * Windows OpenGL implementations do, and unfortunately many Windows
257
 
       * applications don't check whether they receive or not a context with
258
 
       * GL_ARB_compatibility, so returning a core profile here does more harm
259
 
       * than good.
260
 
       */
261
 
      attribs.profile = ST_PROFILE_DEFAULT;
262
 
      break;
263
 
   case WGL_CONTEXT_ES_PROFILE_BIT_EXT:
264
 
      if (majorVersion >= 2) {
265
 
         attribs.profile = ST_PROFILE_OPENGL_ES2;
266
 
      } else {
267
 
         attribs.profile = ST_PROFILE_OPENGL_ES1;
268
 
      }
269
 
      break;
270
 
   default:
271
 
      assert(0);
272
 
      goto no_st_ctx;
273
 
   }
274
 
 
275
 
   attribs.options = stw_dev->st_options;
276
 
 
277
 
   ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,
278
 
         stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);
279
 
   if (ctx->st == NULL)
280
 
      goto no_st_ctx;
281
 
 
282
 
   ctx->st->st_manager_private = (void *) ctx;
283
 
 
284
 
   if (ctx->st->cso_context) {
285
 
      ctx->hud = hud_create(ctx->st->cso_context, ctx->st, NULL);
286
 
   }
287
 
 
288
 
   return ctx;
289
 
 
290
 
no_st_ctx:
291
 
   FREE(ctx);
292
 
no_ctx:
293
 
   return NULL;
294
 
}
295
 
 
296
 
DHGLRC
297
 
stw_create_context_handle(struct stw_context *ctx, DHGLRC handle)
298
 
{
299
 
   assert(ctx->dhglrc == 0);
300
 
 
301
 
   stw_lock_contexts(stw_dev);
302
 
   if (handle) {
303
 
      /* We're replacing the context data for this handle. See the
304
 
       * wglCreateContextAttribsARB() function.
305
 
       */
306
 
      struct stw_context *old_ctx =
307
 
         stw_lookup_context_locked((unsigned) handle);
308
 
      if (old_ctx) {
309
 
         stw_destroy_context(old_ctx);
310
 
      }
311
 
 
312
 
      /* replace table entry */
313
 
      handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);
314
 
   }
315
 
   else {
316
 
      /* create new table entry */
317
 
      handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);
318
 
   }
319
 
 
320
 
   ctx->dhglrc = handle;
321
 
 
322
 
   stw_unlock_contexts(stw_dev);
323
 
 
324
 
   return ctx->dhglrc;
325
 
}
326
 
 
327
 
void
328
 
stw_destroy_context(struct stw_context *ctx)
329
 
{
330
 
   if (ctx->hud) {
331
 
      hud_destroy(ctx->hud, NULL);
332
 
   }
333
 
 
334
 
   ctx->st->destroy(ctx->st);
335
 
   FREE(ctx);
336
 
}
337
 
 
338
 
 
339
 
BOOL APIENTRY
340
 
DrvDeleteContext(DHGLRC dhglrc)
341
 
{
342
 
   struct stw_context *ctx ;
343
 
   BOOL ret = FALSE;
344
 
 
345
 
   if (!stw_dev)
346
 
      return FALSE;
347
 
 
348
 
   stw_lock_contexts(stw_dev);
349
 
   ctx = stw_lookup_context_locked(dhglrc);
350
 
   handle_table_remove(stw_dev->ctx_table, dhglrc);
351
 
   stw_unlock_contexts(stw_dev);
352
 
 
353
 
   if (ctx) {
354
 
      struct stw_context *curctx = stw_current_context();
355
 
 
356
 
      /* Unbind current if deleting current context. */
357
 
      if (curctx == ctx)
358
 
         stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
359
 
 
360
 
      stw_destroy_context(ctx);
361
 
      ret = TRUE;
362
 
   }
363
 
 
364
 
   return ret;
365
 
}
366
 
 
367
 
BOOL
368
 
stw_unbind_context(struct stw_context *ctx)
369
 
{
370
 
   if (!ctx)
371
 
      return FALSE;
372
 
 
373
 
   /* The expectation is that ctx is the same context which is
374
 
    * current for this thread.  We should check that and return False
375
 
    * if not the case.
376
 
    */
377
 
   if (ctx != stw_current_context())
378
 
      return FALSE;
379
 
 
380
 
   if (stw_make_current( NULL, NULL, NULL ) == FALSE)
381
 
      return FALSE;
382
 
 
383
 
   return TRUE;
384
 
}
385
 
 
386
 
BOOL APIENTRY
387
 
DrvReleaseContext(DHGLRC dhglrc)
388
 
{
389
 
   struct stw_context *ctx;
390
 
 
391
 
   if (!stw_dev)
392
 
      return FALSE;
393
 
 
394
 
   stw_lock_contexts(stw_dev);
395
 
   ctx = stw_lookup_context_locked( dhglrc );
396
 
   stw_unlock_contexts(stw_dev);
397
 
 
398
 
   return stw_unbind_context(ctx);
399
 
}
400
 
 
401
 
 
402
 
DHGLRC
403
 
stw_get_current_context( void )
404
 
{
405
 
   struct stw_context *ctx;
406
 
 
407
 
   ctx = stw_current_context();
408
 
   if (!ctx)
409
 
      return 0;
410
 
 
411
 
   return ctx->dhglrc;
412
 
}
413
 
 
414
 
 
415
 
HDC
416
 
stw_get_current_dc( void )
417
 
{
418
 
   struct stw_context *ctx;
419
 
 
420
 
   ctx = stw_current_context();
421
 
   if (!ctx)
422
 
      return NULL;
423
 
 
424
 
   return ctx->hDrawDC;
425
 
}
426
 
 
427
 
HDC
428
 
stw_get_current_read_dc( void )
429
 
{
430
 
   struct stw_context *ctx;
431
 
 
432
 
   ctx = stw_current_context();
433
 
   if (!ctx)
434
 
      return NULL;
435
 
 
436
 
   return ctx->hReadDC;
437
 
}
438
 
 
439
 
static void
440
 
release_old_framebuffers(struct stw_framebuffer *old_fb, struct stw_framebuffer *old_fbRead,
441
 
                         struct stw_context *old_ctx)
442
 
{
443
 
   if (old_fb || old_fbRead) {
444
 
      stw_lock_framebuffers(stw_dev);
445
 
      if (old_fb) {
446
 
         stw_framebuffer_lock(old_fb);
447
 
         stw_framebuffer_release_locked(old_fb, old_ctx->st);
448
 
      }
449
 
      if (old_fbRead) {
450
 
         stw_framebuffer_lock(old_fbRead);
451
 
         stw_framebuffer_release_locked(old_fbRead, old_ctx->st);
452
 
      }
453
 
      stw_unlock_framebuffers(stw_dev);
454
 
   }
455
 
}
456
 
 
457
 
BOOL
458
 
stw_make_current(struct stw_framebuffer *fb, struct stw_framebuffer *fbRead, struct stw_context *ctx)
459
 
{
460
 
   struct stw_context *old_ctx = NULL;
461
 
   BOOL ret = FALSE;
462
 
 
463
 
   if (!stw_dev)
464
 
      return FALSE;
465
 
 
466
 
   old_ctx = stw_current_context();
467
 
   if (old_ctx != NULL) {
468
 
      if (old_ctx == ctx) {
469
 
         if (old_ctx->current_framebuffer == fb && old_ctx->current_read_framebuffer == fbRead) {
470
 
            /* Return if already current. */
471
 
            return TRUE;
472
 
         }
473
 
      } else {
474
 
         if (old_ctx->shared) {
475
 
            if (old_ctx->current_framebuffer) {
476
 
               stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb,
477
 
                            ST_FLUSH_FRONT | ST_FLUSH_WAIT);
478
 
            } else {
479
 
               struct pipe_fence_handle *fence = NULL;
480
 
               old_ctx->st->flush(old_ctx->st,
481
 
                                  ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence,
482
 
                                  NULL, NULL);
483
 
            }
484
 
         } else {
485
 
            if (old_ctx->current_framebuffer)
486
 
               stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb,
487
 
                            ST_FLUSH_FRONT);
488
 
            else
489
 
               old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL);
490
 
         }
491
 
      }
492
 
   }
493
 
 
494
 
   if (ctx) {
495
 
      if (!fb || !fbRead)
496
 
         goto fail;
497
 
 
498
 
      if (fb->iPixelFormat != ctx->iPixelFormat) {
499
 
         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
500
 
         goto fail;
501
 
      }
502
 
      if (fbRead->iPixelFormat != ctx->iPixelFormat) {
503
 
         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
504
 
         goto fail;
505
 
      }
506
 
 
507
 
      stw_framebuffer_lock(fb);
508
 
      stw_framebuffer_update(fb);
509
 
      stw_framebuffer_reference_locked(fb);
510
 
      stw_framebuffer_unlock(fb);
511
 
 
512
 
      stw_framebuffer_lock(fbRead);
513
 
      if (fbRead != fb)
514
 
         stw_framebuffer_update(fbRead);
515
 
      stw_framebuffer_reference_locked(fbRead);
516
 
      stw_framebuffer_unlock(fbRead);
517
 
 
518
 
      struct stw_framebuffer *old_fb = ctx->current_framebuffer;
519
 
      struct stw_framebuffer *old_fbRead = ctx->current_read_framebuffer;
520
 
      ctx->current_framebuffer = fb;
521
 
      ctx->current_read_framebuffer = fbRead;
522
 
 
523
 
      ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
524
 
                                          fb->stfb, fbRead->stfb);
525
 
 
526
 
      /* Release the old framebuffers from this context. */
527
 
      release_old_framebuffers(old_fb, old_fbRead, ctx);
528
 
 
529
 
fail:
530
 
      /* fb and fbRead must be unlocked at this point. */
531
 
      if (fb)
532
 
         assert(!stw_own_mutex(&fb->mutex));
533
 
      if (fbRead)
534
 
         assert(!stw_own_mutex(&fbRead->mutex));
535
 
 
536
 
      /* On failure, make the thread's current rendering context not current
537
 
       * before returning.
538
 
       */
539
 
      if (!ret) {
540
 
         stw_make_current(NULL, NULL, NULL);
541
 
      }
542
 
   } else {
543
 
      ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
544
 
   }
545
 
 
546
 
   /* Unreference the previous framebuffer if any. It must be done after
547
 
    * make_current, as it can be referenced inside.
548
 
    */
549
 
   if (old_ctx && old_ctx != ctx) {
550
 
      release_old_framebuffers(old_ctx->current_framebuffer, old_ctx->current_read_framebuffer, old_ctx);
551
 
      old_ctx->current_framebuffer = NULL;
552
 
      old_ctx->current_read_framebuffer = NULL;
553
 
   }
554
 
 
555
 
   return ret;
556
 
}
557
 
 
558
 
static struct stw_framebuffer *
559
 
get_unlocked_refd_framebuffer_from_dc(HDC hDC)
560
 
{
561
 
   if (!hDC)
562
 
      return NULL;
563
 
 
564
 
   /* This call locks fb's mutex */
565
 
   struct stw_framebuffer *fb = stw_framebuffer_from_hdc(hDC);
566
 
   if (!fb) {
567
 
      /* Applications should call SetPixelFormat before creating a context,
568
 
       * but not all do, and the opengl32 runtime seems to use a default
569
 
       * pixel format in some cases, so we must create a framebuffer for
570
 
       * those here.
571
 
       */
572
 
      int iPixelFormat = get_matching_pixel_format(hDC);
573
 
      if (iPixelFormat)
574
 
         fb = stw_framebuffer_create(WindowFromDC(hDC), iPixelFormat, STW_FRAMEBUFFER_WGL_WINDOW);
575
 
      if (!fb)
576
 
         return NULL;
577
 
   }
578
 
   stw_framebuffer_reference_locked(fb);
579
 
   stw_framebuffer_unlock(fb);
580
 
   return fb;
581
 
}
582
 
 
583
 
BOOL
584
 
stw_make_current_by_handles(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc)
585
 
{
586
 
   struct stw_context *ctx = stw_lookup_context(dhglrc);
587
 
   if (dhglrc && !ctx) {
588
 
      stw_make_current_by_handles(NULL, NULL, 0);
589
 
      return FALSE;
590
 
   }
591
 
 
592
 
   struct stw_framebuffer *fb = get_unlocked_refd_framebuffer_from_dc(hDrawDC);
593
 
   if (ctx && !fb) {
594
 
      stw_make_current_by_handles(NULL, NULL, 0);
595
 
      return FALSE;
596
 
   }
597
 
 
598
 
   struct stw_framebuffer *fbRead = (hDrawDC == hReadDC || hReadDC == NULL) ?
599
 
      fb : get_unlocked_refd_framebuffer_from_dc(hReadDC);
600
 
   if (ctx && !fbRead) {
601
 
      release_old_framebuffers(fb, NULL, ctx);
602
 
      stw_make_current_by_handles(NULL, NULL, 0);
603
 
      return FALSE;
604
 
   }
605
 
 
606
 
   BOOL success = stw_make_current(fb, fbRead, ctx);
607
 
 
608
 
   if (ctx) {
609
 
      if (success) {
610
 
         ctx->hDrawDC = hDrawDC;
611
 
         ctx->hReadDC = hReadDC;
612
 
      } else {
613
 
         ctx->hDrawDC = NULL;
614
 
         ctx->hReadDC = NULL;
615
 
      }
616
 
 
617
 
      assert(fb && fbRead);
618
 
      /* In the success case, the context took extra references on these framebuffers,
619
 
       * so release our local references.
620
 
       */
621
 
      stw_lock_framebuffers(stw_dev);
622
 
      stw_framebuffer_lock(fb);
623
 
      stw_framebuffer_release_locked(fb, ctx->st);
624
 
      if (fb != fbRead) {
625
 
         stw_framebuffer_lock(fbRead);
626
 
         stw_framebuffer_release_locked(fbRead, ctx->st);
627
 
      }
628
 
      stw_unlock_framebuffers(stw_dev);
629
 
   }
630
 
   return success;
631
 
}
632
 
 
633
 
 
634
 
/**
635
 
 * Notify the current context that the framebuffer has become invalid.
636
 
 */
637
 
void
638
 
stw_notify_current_locked( struct stw_framebuffer *fb )
639
 
{
640
 
   p_atomic_inc(&fb->stfb->stamp);
641
 
}
642
 
 
643
 
 
644
 
/**
645
 
 * Although WGL allows different dispatch entrypoints per context
646
 
 */
647
 
static const GLCLTPROCTABLE cpt =
648
 
{
649
 
   OPENGL_VERSION_110_ENTRIES,
650
 
   {
651
 
      &glNewList,
652
 
      &glEndList,
653
 
      &glCallList,
654
 
      &glCallLists,
655
 
      &glDeleteLists,
656
 
      &glGenLists,
657
 
      &glListBase,
658
 
      &glBegin,
659
 
      &glBitmap,
660
 
      &glColor3b,
661
 
      &glColor3bv,
662
 
      &glColor3d,
663
 
      &glColor3dv,
664
 
      &glColor3f,
665
 
      &glColor3fv,
666
 
      &glColor3i,
667
 
      &glColor3iv,
668
 
      &glColor3s,
669
 
      &glColor3sv,
670
 
      &glColor3ub,
671
 
      &glColor3ubv,
672
 
      &glColor3ui,
673
 
      &glColor3uiv,
674
 
      &glColor3us,
675
 
      &glColor3usv,
676
 
      &glColor4b,
677
 
      &glColor4bv,
678
 
      &glColor4d,
679
 
      &glColor4dv,
680
 
      &glColor4f,
681
 
      &glColor4fv,
682
 
      &glColor4i,
683
 
      &glColor4iv,
684
 
      &glColor4s,
685
 
      &glColor4sv,
686
 
      &glColor4ub,
687
 
      &glColor4ubv,
688
 
      &glColor4ui,
689
 
      &glColor4uiv,
690
 
      &glColor4us,
691
 
      &glColor4usv,
692
 
      &glEdgeFlag,
693
 
      &glEdgeFlagv,
694
 
      &glEnd,
695
 
      &glIndexd,
696
 
      &glIndexdv,
697
 
      &glIndexf,
698
 
      &glIndexfv,
699
 
      &glIndexi,
700
 
      &glIndexiv,
701
 
      &glIndexs,
702
 
      &glIndexsv,
703
 
      &glNormal3b,
704
 
      &glNormal3bv,
705
 
      &glNormal3d,
706
 
      &glNormal3dv,
707
 
      &glNormal3f,
708
 
      &glNormal3fv,
709
 
      &glNormal3i,
710
 
      &glNormal3iv,
711
 
      &glNormal3s,
712
 
      &glNormal3sv,
713
 
      &glRasterPos2d,
714
 
      &glRasterPos2dv,
715
 
      &glRasterPos2f,
716
 
      &glRasterPos2fv,
717
 
      &glRasterPos2i,
718
 
      &glRasterPos2iv,
719
 
      &glRasterPos2s,
720
 
      &glRasterPos2sv,
721
 
      &glRasterPos3d,
722
 
      &glRasterPos3dv,
723
 
      &glRasterPos3f,
724
 
      &glRasterPos3fv,
725
 
      &glRasterPos3i,
726
 
      &glRasterPos3iv,
727
 
      &glRasterPos3s,
728
 
      &glRasterPos3sv,
729
 
      &glRasterPos4d,
730
 
      &glRasterPos4dv,
731
 
      &glRasterPos4f,
732
 
      &glRasterPos4fv,
733
 
      &glRasterPos4i,
734
 
      &glRasterPos4iv,
735
 
      &glRasterPos4s,
736
 
      &glRasterPos4sv,
737
 
      &glRectd,
738
 
      &glRectdv,
739
 
      &glRectf,
740
 
      &glRectfv,
741
 
      &glRecti,
742
 
      &glRectiv,
743
 
      &glRects,
744
 
      &glRectsv,
745
 
      &glTexCoord1d,
746
 
      &glTexCoord1dv,
747
 
      &glTexCoord1f,
748
 
      &glTexCoord1fv,
749
 
      &glTexCoord1i,
750
 
      &glTexCoord1iv,
751
 
      &glTexCoord1s,
752
 
      &glTexCoord1sv,
753
 
      &glTexCoord2d,
754
 
      &glTexCoord2dv,
755
 
      &glTexCoord2f,
756
 
      &glTexCoord2fv,
757
 
      &glTexCoord2i,
758
 
      &glTexCoord2iv,
759
 
      &glTexCoord2s,
760
 
      &glTexCoord2sv,
761
 
      &glTexCoord3d,
762
 
      &glTexCoord3dv,
763
 
      &glTexCoord3f,
764
 
      &glTexCoord3fv,
765
 
      &glTexCoord3i,
766
 
      &glTexCoord3iv,
767
 
      &glTexCoord3s,
768
 
      &glTexCoord3sv,
769
 
      &glTexCoord4d,
770
 
      &glTexCoord4dv,
771
 
      &glTexCoord4f,
772
 
      &glTexCoord4fv,
773
 
      &glTexCoord4i,
774
 
      &glTexCoord4iv,
775
 
      &glTexCoord4s,
776
 
      &glTexCoord4sv,
777
 
      &glVertex2d,
778
 
      &glVertex2dv,
779
 
      &glVertex2f,
780
 
      &glVertex2fv,
781
 
      &glVertex2i,
782
 
      &glVertex2iv,
783
 
      &glVertex2s,
784
 
      &glVertex2sv,
785
 
      &glVertex3d,
786
 
      &glVertex3dv,
787
 
      &glVertex3f,
788
 
      &glVertex3fv,
789
 
      &glVertex3i,
790
 
      &glVertex3iv,
791
 
      &glVertex3s,
792
 
      &glVertex3sv,
793
 
      &glVertex4d,
794
 
      &glVertex4dv,
795
 
      &glVertex4f,
796
 
      &glVertex4fv,
797
 
      &glVertex4i,
798
 
      &glVertex4iv,
799
 
      &glVertex4s,
800
 
      &glVertex4sv,
801
 
      &glClipPlane,
802
 
      &glColorMaterial,
803
 
      &glCullFace,
804
 
      &glFogf,
805
 
      &glFogfv,
806
 
      &glFogi,
807
 
      &glFogiv,
808
 
      &glFrontFace,
809
 
      &glHint,
810
 
      &glLightf,
811
 
      &glLightfv,
812
 
      &glLighti,
813
 
      &glLightiv,
814
 
      &glLightModelf,
815
 
      &glLightModelfv,
816
 
      &glLightModeli,
817
 
      &glLightModeliv,
818
 
      &glLineStipple,
819
 
      &glLineWidth,
820
 
      &glMaterialf,
821
 
      &glMaterialfv,
822
 
      &glMateriali,
823
 
      &glMaterialiv,
824
 
      &glPointSize,
825
 
      &glPolygonMode,
826
 
      &glPolygonStipple,
827
 
      &glScissor,
828
 
      &glShadeModel,
829
 
      &glTexParameterf,
830
 
      &glTexParameterfv,
831
 
      &glTexParameteri,
832
 
      &glTexParameteriv,
833
 
      &glTexImage1D,
834
 
      &glTexImage2D,
835
 
      &glTexEnvf,
836
 
      &glTexEnvfv,
837
 
      &glTexEnvi,
838
 
      &glTexEnviv,
839
 
      &glTexGend,
840
 
      &glTexGendv,
841
 
      &glTexGenf,
842
 
      &glTexGenfv,
843
 
      &glTexGeni,
844
 
      &glTexGeniv,
845
 
      &glFeedbackBuffer,
846
 
      &glSelectBuffer,
847
 
      &glRenderMode,
848
 
      &glInitNames,
849
 
      &glLoadName,
850
 
      &glPassThrough,
851
 
      &glPopName,
852
 
      &glPushName,
853
 
      &glDrawBuffer,
854
 
      &glClear,
855
 
      &glClearAccum,
856
 
      &glClearIndex,
857
 
      &glClearColor,
858
 
      &glClearStencil,
859
 
      &glClearDepth,
860
 
      &glStencilMask,
861
 
      &glColorMask,
862
 
      &glDepthMask,
863
 
      &glIndexMask,
864
 
      &glAccum,
865
 
      &glDisable,
866
 
      &glEnable,
867
 
      &glFinish,
868
 
      &glFlush,
869
 
      &glPopAttrib,
870
 
      &glPushAttrib,
871
 
      &glMap1d,
872
 
      &glMap1f,
873
 
      &glMap2d,
874
 
      &glMap2f,
875
 
      &glMapGrid1d,
876
 
      &glMapGrid1f,
877
 
      &glMapGrid2d,
878
 
      &glMapGrid2f,
879
 
      &glEvalCoord1d,
880
 
      &glEvalCoord1dv,
881
 
      &glEvalCoord1f,
882
 
      &glEvalCoord1fv,
883
 
      &glEvalCoord2d,
884
 
      &glEvalCoord2dv,
885
 
      &glEvalCoord2f,
886
 
      &glEvalCoord2fv,
887
 
      &glEvalMesh1,
888
 
      &glEvalPoint1,
889
 
      &glEvalMesh2,
890
 
      &glEvalPoint2,
891
 
      &glAlphaFunc,
892
 
      &glBlendFunc,
893
 
      &glLogicOp,
894
 
      &glStencilFunc,
895
 
      &glStencilOp,
896
 
      &glDepthFunc,
897
 
      &glPixelZoom,
898
 
      &glPixelTransferf,
899
 
      &glPixelTransferi,
900
 
      &glPixelStoref,
901
 
      &glPixelStorei,
902
 
      &glPixelMapfv,
903
 
      &glPixelMapuiv,
904
 
      &glPixelMapusv,
905
 
      &glReadBuffer,
906
 
      &glCopyPixels,
907
 
      &glReadPixels,
908
 
      &glDrawPixels,
909
 
      &glGetBooleanv,
910
 
      &glGetClipPlane,
911
 
      &glGetDoublev,
912
 
      &glGetError,
913
 
      &glGetFloatv,
914
 
      &glGetIntegerv,
915
 
      &glGetLightfv,
916
 
      &glGetLightiv,
917
 
      &glGetMapdv,
918
 
      &glGetMapfv,
919
 
      &glGetMapiv,
920
 
      &glGetMaterialfv,
921
 
      &glGetMaterialiv,
922
 
      &glGetPixelMapfv,
923
 
      &glGetPixelMapuiv,
924
 
      &glGetPixelMapusv,
925
 
      &glGetPolygonStipple,
926
 
      &glGetString,
927
 
      &glGetTexEnvfv,
928
 
      &glGetTexEnviv,
929
 
      &glGetTexGendv,
930
 
      &glGetTexGenfv,
931
 
      &glGetTexGeniv,
932
 
      &glGetTexImage,
933
 
      &glGetTexParameterfv,
934
 
      &glGetTexParameteriv,
935
 
      &glGetTexLevelParameterfv,
936
 
      &glGetTexLevelParameteriv,
937
 
      &glIsEnabled,
938
 
      &glIsList,
939
 
      &glDepthRange,
940
 
      &glFrustum,
941
 
      &glLoadIdentity,
942
 
      &glLoadMatrixf,
943
 
      &glLoadMatrixd,
944
 
      &glMatrixMode,
945
 
      &glMultMatrixf,
946
 
      &glMultMatrixd,
947
 
      &glOrtho,
948
 
      &glPopMatrix,
949
 
      &glPushMatrix,
950
 
      &glRotated,
951
 
      &glRotatef,
952
 
      &glScaled,
953
 
      &glScalef,
954
 
      &glTranslated,
955
 
      &glTranslatef,
956
 
      &glViewport,
957
 
      &glArrayElement,
958
 
      &glBindTexture,
959
 
      &glColorPointer,
960
 
      &glDisableClientState,
961
 
      &glDrawArrays,
962
 
      &glDrawElements,
963
 
      &glEdgeFlagPointer,
964
 
      &glEnableClientState,
965
 
      &glIndexPointer,
966
 
      &glIndexub,
967
 
      &glIndexubv,
968
 
      &glInterleavedArrays,
969
 
      &glNormalPointer,
970
 
      &glPolygonOffset,
971
 
      &glTexCoordPointer,
972
 
      &glVertexPointer,
973
 
      &glAreTexturesResident,
974
 
      &glCopyTexImage1D,
975
 
      &glCopyTexImage2D,
976
 
      &glCopyTexSubImage1D,
977
 
      &glCopyTexSubImage2D,
978
 
      &glDeleteTextures,
979
 
      &glGenTextures,
980
 
      &glGetPointerv,
981
 
      &glIsTexture,
982
 
      &glPrioritizeTextures,
983
 
      &glTexSubImage1D,
984
 
      &glTexSubImage2D,
985
 
      &glPopClientAttrib,
986
 
      &glPushClientAttrib
987
 
   }
988
 
};
989
 
 
990
 
 
991
 
PGLCLTPROCTABLE APIENTRY
992
 
DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
993
 
{
994
 
   PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
995
 
 
996
 
   if (!stw_make_current_by_handles(hdc, hdc, dhglrc))
997
 
      r = NULL;
998
 
 
999
 
   return r;
1000
 
}