17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2008 VMware, Inc. 47ec681f3Smrg * All Rights Reserved. 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the 87ec681f3Smrg * "Software"), to deal in the Software without restriction, including 97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 127ec681f3Smrg * the following conditions: 137ec681f3Smrg * 147ec681f3Smrg * The above copyright notice and this permission notice (including the 157ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 167ec681f3Smrg * of the Software. 177ec681f3Smrg * 187ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 207ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 217ec681f3Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 227ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 237ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 247ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 267ec681f3Smrg **************************************************************************/ 277ec681f3Smrg 287ec681f3Smrg#include <windows.h> 297ec681f3Smrg 307ec681f3Smrg#define WGL_WGLEXT_PROTOTYPES 317ec681f3Smrg 327ec681f3Smrg#include <GL/gl.h> 337ec681f3Smrg#include <GL/wglext.h> 347ec681f3Smrg 357ec681f3Smrg#include "pipe/p_compiler.h" 367ec681f3Smrg#include "pipe/p_context.h" 377ec681f3Smrg#include "pipe/p_state.h" 387ec681f3Smrg#include "util/compiler.h" 397ec681f3Smrg#include "util/u_memory.h" 407ec681f3Smrg#include "util/u_atomic.h" 417ec681f3Smrg#include "hud/hud_context.h" 427ec681f3Smrg 437ec681f3Smrg#include "gldrv.h" 447ec681f3Smrg#include "stw_device.h" 457ec681f3Smrg#include "stw_winsys.h" 467ec681f3Smrg#include "stw_framebuffer.h" 477ec681f3Smrg#include "stw_pixelformat.h" 487ec681f3Smrg#include "stw_context.h" 497ec681f3Smrg#include "stw_tls.h" 507ec681f3Smrg 517ec681f3Smrg 527ec681f3Smrgstruct stw_context * 537ec681f3Smrgstw_current_context(void) 547ec681f3Smrg{ 557ec681f3Smrg struct st_context_iface *st; 567ec681f3Smrg 577ec681f3Smrg st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL; 587ec681f3Smrg 597ec681f3Smrg return (struct stw_context *) ((st) ? st->st_manager_private : NULL); 607ec681f3Smrg} 617ec681f3Smrg 627ec681f3Smrg 637ec681f3SmrgBOOL APIENTRY 647ec681f3SmrgDrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask) 657ec681f3Smrg{ 667ec681f3Smrg struct stw_context *src; 677ec681f3Smrg struct stw_context *dst; 687ec681f3Smrg BOOL ret = FALSE; 697ec681f3Smrg 707ec681f3Smrg if (!stw_dev) 717ec681f3Smrg return FALSE; 727ec681f3Smrg 737ec681f3Smrg stw_lock_contexts(stw_dev); 747ec681f3Smrg 757ec681f3Smrg src = stw_lookup_context_locked( dhrcSource ); 767ec681f3Smrg dst = stw_lookup_context_locked( dhrcDest ); 777ec681f3Smrg 787ec681f3Smrg if (src && dst) { 797ec681f3Smrg /* FIXME */ 807ec681f3Smrg assert(0); 817ec681f3Smrg (void) src; 827ec681f3Smrg (void) dst; 837ec681f3Smrg (void) fuMask; 847ec681f3Smrg } 857ec681f3Smrg 867ec681f3Smrg stw_unlock_contexts(stw_dev); 877ec681f3Smrg 887ec681f3Smrg return ret; 897ec681f3Smrg} 907ec681f3Smrg 917ec681f3Smrg 927ec681f3SmrgBOOL APIENTRY 937ec681f3SmrgDrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2) 947ec681f3Smrg{ 957ec681f3Smrg struct stw_context *ctx1; 967ec681f3Smrg struct stw_context *ctx2; 977ec681f3Smrg BOOL ret = FALSE; 987ec681f3Smrg 997ec681f3Smrg if (!stw_dev) 1007ec681f3Smrg return FALSE; 1017ec681f3Smrg 1027ec681f3Smrg stw_lock_contexts(stw_dev); 1037ec681f3Smrg 1047ec681f3Smrg ctx1 = stw_lookup_context_locked( dhglrc1 ); 1057ec681f3Smrg ctx2 = stw_lookup_context_locked( dhglrc2 ); 1067ec681f3Smrg 1077ec681f3Smrg if (ctx1 && ctx2 && ctx2->st->share) { 1087ec681f3Smrg ret = ctx2->st->share(ctx2->st, ctx1->st); 1097ec681f3Smrg ctx1->shared = TRUE; 1107ec681f3Smrg ctx2->shared = TRUE; 1117ec681f3Smrg } 1127ec681f3Smrg 1137ec681f3Smrg stw_unlock_contexts(stw_dev); 1147ec681f3Smrg 1157ec681f3Smrg return ret; 1167ec681f3Smrg} 1177ec681f3Smrg 1187ec681f3Smrg 1197ec681f3SmrgDHGLRC APIENTRY 1207ec681f3SmrgDrvCreateContext(HDC hdc) 1217ec681f3Smrg{ 1227ec681f3Smrg return DrvCreateLayerContext( hdc, 0 ); 1237ec681f3Smrg} 1247ec681f3Smrg 1257ec681f3Smrg 1267ec681f3SmrgDHGLRC APIENTRY 1277ec681f3SmrgDrvCreateLayerContext(HDC hdc, INT iLayerPlane) 1287ec681f3Smrg{ 1297ec681f3Smrg struct stw_context *ctx = stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0, 1307ec681f3Smrg WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 1317ec681f3Smrg 0); 1327ec681f3Smrg if (!ctx) 1337ec681f3Smrg return 0; 1347ec681f3Smrg 1357ec681f3Smrg DHGLRC ret = stw_create_context_handle(ctx, 0); 1367ec681f3Smrg if (!ret) 1377ec681f3Smrg stw_destroy_context(ctx); 1387ec681f3Smrg 1397ec681f3Smrg return ret; 1407ec681f3Smrg} 1417ec681f3Smrg 1427ec681f3Smrg 1437ec681f3Smrg/** 1447ec681f3Smrg * Return the stw pixel format that most closely matches the pixel format 1457ec681f3Smrg * on HDC. 1467ec681f3Smrg * Used to get a pixel format when SetPixelFormat() hasn't been called before. 1477ec681f3Smrg */ 1487ec681f3Smrgstatic int 1497ec681f3Smrgget_matching_pixel_format(HDC hdc) 1507ec681f3Smrg{ 1517ec681f3Smrg int iPixelFormat = GetPixelFormat(hdc); 1527ec681f3Smrg PIXELFORMATDESCRIPTOR pfd; 1537ec681f3Smrg 1547ec681f3Smrg if (!iPixelFormat) 1557ec681f3Smrg return 0; 1567ec681f3Smrg if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd)) 1577ec681f3Smrg return 0; 1587ec681f3Smrg return stw_pixelformat_choose(hdc, &pfd); 1597ec681f3Smrg} 1607ec681f3Smrg 1617ec681f3Smrg 1627ec681f3Smrg/** 1637ec681f3Smrg * Called via DrvCreateContext(), DrvCreateLayerContext() and 1647ec681f3Smrg * wglCreateContextAttribsARB() to actually create a rendering context. 1657ec681f3Smrg */ 1667ec681f3Smrgstruct stw_context * 1677ec681f3Smrgstw_create_context_attribs(HDC hdc, INT iLayerPlane, struct stw_context *shareCtx, 1687ec681f3Smrg int majorVersion, int minorVersion, 1697ec681f3Smrg int contextFlags, int profileMask, 1707ec681f3Smrg int iPixelFormat) 1717ec681f3Smrg{ 1727ec681f3Smrg const struct stw_pixelformat_info *pfi; 1737ec681f3Smrg struct st_context_attribs attribs; 1747ec681f3Smrg struct stw_context *ctx = NULL; 1757ec681f3Smrg enum st_context_error ctx_err = 0; 1767ec681f3Smrg 1777ec681f3Smrg if (!stw_dev) 1787ec681f3Smrg return 0; 1797ec681f3Smrg 1807ec681f3Smrg if (iLayerPlane != 0) 1817ec681f3Smrg return 0; 1827ec681f3Smrg 1837ec681f3Smrg if (!iPixelFormat) { 1847ec681f3Smrg /* 1857ec681f3Smrg * GDI only knows about displayable pixel formats, so determine the pixel 1867ec681f3Smrg * format from the framebuffer. 1877ec681f3Smrg * 1887ec681f3Smrg * This also allows to use a OpenGL DLL / ICD without installing. 1897ec681f3Smrg */ 1907ec681f3Smrg struct stw_framebuffer *fb; 1917ec681f3Smrg fb = stw_framebuffer_from_hdc(hdc); 1927ec681f3Smrg if (fb) { 1937ec681f3Smrg iPixelFormat = fb->iPixelFormat; 1947ec681f3Smrg stw_framebuffer_unlock(fb); 1957ec681f3Smrg } 1967ec681f3Smrg else { 1977ec681f3Smrg /* Applications should call SetPixelFormat before creating a context, 1987ec681f3Smrg * but not all do, and the opengl32 runtime seems to use a default 1997ec681f3Smrg * pixel format in some cases, so use that. 2007ec681f3Smrg */ 2017ec681f3Smrg iPixelFormat = get_matching_pixel_format(hdc); 2027ec681f3Smrg if (!iPixelFormat) 2037ec681f3Smrg return 0; 2047ec681f3Smrg } 2057ec681f3Smrg } 2067ec681f3Smrg 2077ec681f3Smrg pfi = stw_pixelformat_get_info( iPixelFormat ); 2087ec681f3Smrg 2097ec681f3Smrg if (shareCtx != NULL) 2107ec681f3Smrg shareCtx->shared = TRUE; 2117ec681f3Smrg 2127ec681f3Smrg ctx = CALLOC_STRUCT( stw_context ); 2137ec681f3Smrg if (ctx == NULL) 2147ec681f3Smrg goto no_ctx; 2157ec681f3Smrg 2167ec681f3Smrg ctx->hDrawDC = hdc; 2177ec681f3Smrg ctx->hReadDC = hdc; 2187ec681f3Smrg ctx->iPixelFormat = iPixelFormat; 2197ec681f3Smrg ctx->shared = shareCtx != NULL; 2207ec681f3Smrg 2217ec681f3Smrg memset(&attribs, 0, sizeof(attribs)); 2227ec681f3Smrg attribs.visual = pfi->stvis; 2237ec681f3Smrg attribs.major = majorVersion; 2247ec681f3Smrg attribs.minor = minorVersion; 2257ec681f3Smrg if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) 2267ec681f3Smrg attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; 2277ec681f3Smrg if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB) 2287ec681f3Smrg attribs.flags |= ST_CONTEXT_FLAG_DEBUG; 2297ec681f3Smrg 2307ec681f3Smrg switch (profileMask) { 2317ec681f3Smrg case WGL_CONTEXT_CORE_PROFILE_BIT_ARB: 2327ec681f3Smrg /* There are no profiles before OpenGL 3.2. The 2337ec681f3Smrg * WGL_ARB_create_context_profile spec says: 2347ec681f3Smrg * 2357ec681f3Smrg * "If the requested OpenGL version is less than 3.2, 2367ec681f3Smrg * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality 2377ec681f3Smrg * of the context is determined solely by the requested version." 2387ec681f3Smrg */ 2397ec681f3Smrg if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) { 2407ec681f3Smrg attribs.profile = ST_PROFILE_OPENGL_CORE; 2417ec681f3Smrg break; 2427ec681f3Smrg } 2437ec681f3Smrg FALLTHROUGH; 2447ec681f3Smrg case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: 2457ec681f3Smrg /* 2467ec681f3Smrg * The spec also says: 2477ec681f3Smrg * 2487ec681f3Smrg * "If version 3.1 is requested, the context returned may implement 2497ec681f3Smrg * any of the following versions: 2507ec681f3Smrg * 2517ec681f3Smrg * * Version 3.1. The GL_ARB_compatibility extension may or may not 2527ec681f3Smrg * be implemented, as determined by the implementation. 2537ec681f3Smrg * * The core profile of version 3.2 or greater." 2547ec681f3Smrg * 2557ec681f3Smrg * But Mesa doesn't support GL_ARB_compatibility, while most prevalent 2567ec681f3Smrg * Windows OpenGL implementations do, and unfortunately many Windows 2577ec681f3Smrg * applications don't check whether they receive or not a context with 2587ec681f3Smrg * GL_ARB_compatibility, so returning a core profile here does more harm 2597ec681f3Smrg * than good. 2607ec681f3Smrg */ 2617ec681f3Smrg attribs.profile = ST_PROFILE_DEFAULT; 2627ec681f3Smrg break; 2637ec681f3Smrg case WGL_CONTEXT_ES_PROFILE_BIT_EXT: 2647ec681f3Smrg if (majorVersion >= 2) { 2657ec681f3Smrg attribs.profile = ST_PROFILE_OPENGL_ES2; 2667ec681f3Smrg } else { 2677ec681f3Smrg attribs.profile = ST_PROFILE_OPENGL_ES1; 2687ec681f3Smrg } 2697ec681f3Smrg break; 2707ec681f3Smrg default: 2717ec681f3Smrg assert(0); 2727ec681f3Smrg goto no_st_ctx; 2737ec681f3Smrg } 2747ec681f3Smrg 2757ec681f3Smrg attribs.options = stw_dev->st_options; 2767ec681f3Smrg 2777ec681f3Smrg ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, 2787ec681f3Smrg stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL); 2797ec681f3Smrg if (ctx->st == NULL) 2807ec681f3Smrg goto no_st_ctx; 2817ec681f3Smrg 2827ec681f3Smrg ctx->st->st_manager_private = (void *) ctx; 2837ec681f3Smrg 2847ec681f3Smrg if (ctx->st->cso_context) { 2857ec681f3Smrg ctx->hud = hud_create(ctx->st->cso_context, ctx->st, NULL); 2867ec681f3Smrg } 2877ec681f3Smrg 2887ec681f3Smrg return ctx; 2897ec681f3Smrg 2907ec681f3Smrgno_st_ctx: 2917ec681f3Smrg FREE(ctx); 2927ec681f3Smrgno_ctx: 2937ec681f3Smrg return NULL; 2947ec681f3Smrg} 2957ec681f3Smrg 2967ec681f3SmrgDHGLRC 2977ec681f3Smrgstw_create_context_handle(struct stw_context *ctx, DHGLRC handle) 2987ec681f3Smrg{ 2997ec681f3Smrg assert(ctx->dhglrc == 0); 3007ec681f3Smrg 3017ec681f3Smrg stw_lock_contexts(stw_dev); 3027ec681f3Smrg if (handle) { 3037ec681f3Smrg /* We're replacing the context data for this handle. See the 3047ec681f3Smrg * wglCreateContextAttribsARB() function. 3057ec681f3Smrg */ 3067ec681f3Smrg struct stw_context *old_ctx = 3077ec681f3Smrg stw_lookup_context_locked((unsigned) handle); 3087ec681f3Smrg if (old_ctx) { 3097ec681f3Smrg stw_destroy_context(old_ctx); 3107ec681f3Smrg } 3117ec681f3Smrg 3127ec681f3Smrg /* replace table entry */ 3137ec681f3Smrg handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx); 3147ec681f3Smrg } 3157ec681f3Smrg else { 3167ec681f3Smrg /* create new table entry */ 3177ec681f3Smrg handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx); 3187ec681f3Smrg } 3197ec681f3Smrg 3207ec681f3Smrg ctx->dhglrc = handle; 3217ec681f3Smrg 3227ec681f3Smrg stw_unlock_contexts(stw_dev); 3237ec681f3Smrg 3247ec681f3Smrg return ctx->dhglrc; 3257ec681f3Smrg} 3267ec681f3Smrg 3277ec681f3Smrgvoid 3287ec681f3Smrgstw_destroy_context(struct stw_context *ctx) 3297ec681f3Smrg{ 3307ec681f3Smrg if (ctx->hud) { 3317ec681f3Smrg hud_destroy(ctx->hud, NULL); 3327ec681f3Smrg } 3337ec681f3Smrg 3347ec681f3Smrg ctx->st->destroy(ctx->st); 3357ec681f3Smrg FREE(ctx); 3367ec681f3Smrg} 3377ec681f3Smrg 3387ec681f3Smrg 3397ec681f3SmrgBOOL APIENTRY 3407ec681f3SmrgDrvDeleteContext(DHGLRC dhglrc) 3417ec681f3Smrg{ 3427ec681f3Smrg struct stw_context *ctx ; 3437ec681f3Smrg BOOL ret = FALSE; 3447ec681f3Smrg 3457ec681f3Smrg if (!stw_dev) 3467ec681f3Smrg return FALSE; 3477ec681f3Smrg 3487ec681f3Smrg stw_lock_contexts(stw_dev); 3497ec681f3Smrg ctx = stw_lookup_context_locked(dhglrc); 3507ec681f3Smrg handle_table_remove(stw_dev->ctx_table, dhglrc); 3517ec681f3Smrg stw_unlock_contexts(stw_dev); 3527ec681f3Smrg 3537ec681f3Smrg if (ctx) { 3547ec681f3Smrg struct stw_context *curctx = stw_current_context(); 3557ec681f3Smrg 3567ec681f3Smrg /* Unbind current if deleting current context. */ 3577ec681f3Smrg if (curctx == ctx) 3587ec681f3Smrg stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 3597ec681f3Smrg 3607ec681f3Smrg stw_destroy_context(ctx); 3617ec681f3Smrg ret = TRUE; 3627ec681f3Smrg } 3637ec681f3Smrg 3647ec681f3Smrg return ret; 3657ec681f3Smrg} 3667ec681f3Smrg 3677ec681f3SmrgBOOL 3687ec681f3Smrgstw_unbind_context(struct stw_context *ctx) 3697ec681f3Smrg{ 3707ec681f3Smrg if (!ctx) 3717ec681f3Smrg return FALSE; 3727ec681f3Smrg 3737ec681f3Smrg /* The expectation is that ctx is the same context which is 3747ec681f3Smrg * current for this thread. We should check that and return False 3757ec681f3Smrg * if not the case. 3767ec681f3Smrg */ 3777ec681f3Smrg if (ctx != stw_current_context()) 3787ec681f3Smrg return FALSE; 3797ec681f3Smrg 3807ec681f3Smrg if (stw_make_current( NULL, NULL, NULL ) == FALSE) 3817ec681f3Smrg return FALSE; 3827ec681f3Smrg 3837ec681f3Smrg return TRUE; 3847ec681f3Smrg} 3857ec681f3Smrg 3867ec681f3SmrgBOOL APIENTRY 3877ec681f3SmrgDrvReleaseContext(DHGLRC dhglrc) 3887ec681f3Smrg{ 3897ec681f3Smrg struct stw_context *ctx; 3907ec681f3Smrg 3917ec681f3Smrg if (!stw_dev) 3927ec681f3Smrg return FALSE; 3937ec681f3Smrg 3947ec681f3Smrg stw_lock_contexts(stw_dev); 3957ec681f3Smrg ctx = stw_lookup_context_locked( dhglrc ); 3967ec681f3Smrg stw_unlock_contexts(stw_dev); 3977ec681f3Smrg 3987ec681f3Smrg return stw_unbind_context(ctx); 3997ec681f3Smrg} 4007ec681f3Smrg 4017ec681f3Smrg 4027ec681f3SmrgDHGLRC 4037ec681f3Smrgstw_get_current_context( void ) 4047ec681f3Smrg{ 4057ec681f3Smrg struct stw_context *ctx; 4067ec681f3Smrg 4077ec681f3Smrg ctx = stw_current_context(); 4087ec681f3Smrg if (!ctx) 4097ec681f3Smrg return 0; 4107ec681f3Smrg 4117ec681f3Smrg return ctx->dhglrc; 4127ec681f3Smrg} 4137ec681f3Smrg 4147ec681f3Smrg 4157ec681f3SmrgHDC 4167ec681f3Smrgstw_get_current_dc( void ) 4177ec681f3Smrg{ 4187ec681f3Smrg struct stw_context *ctx; 4197ec681f3Smrg 4207ec681f3Smrg ctx = stw_current_context(); 4217ec681f3Smrg if (!ctx) 4227ec681f3Smrg return NULL; 4237ec681f3Smrg 4247ec681f3Smrg return ctx->hDrawDC; 4257ec681f3Smrg} 4267ec681f3Smrg 4277ec681f3SmrgHDC 4287ec681f3Smrgstw_get_current_read_dc( void ) 4297ec681f3Smrg{ 4307ec681f3Smrg struct stw_context *ctx; 4317ec681f3Smrg 4327ec681f3Smrg ctx = stw_current_context(); 4337ec681f3Smrg if (!ctx) 4347ec681f3Smrg return NULL; 4357ec681f3Smrg 4367ec681f3Smrg return ctx->hReadDC; 4377ec681f3Smrg} 4387ec681f3Smrg 4397ec681f3Smrgstatic void 4407ec681f3Smrgrelease_old_framebuffers(struct stw_framebuffer *old_fb, struct stw_framebuffer *old_fbRead, 4417ec681f3Smrg struct stw_context *old_ctx) 4427ec681f3Smrg{ 4437ec681f3Smrg if (old_fb || old_fbRead) { 4447ec681f3Smrg stw_lock_framebuffers(stw_dev); 4457ec681f3Smrg if (old_fb) { 4467ec681f3Smrg stw_framebuffer_lock(old_fb); 4477ec681f3Smrg stw_framebuffer_release_locked(old_fb, old_ctx->st); 4487ec681f3Smrg } 4497ec681f3Smrg if (old_fbRead) { 4507ec681f3Smrg stw_framebuffer_lock(old_fbRead); 4517ec681f3Smrg stw_framebuffer_release_locked(old_fbRead, old_ctx->st); 4527ec681f3Smrg } 4537ec681f3Smrg stw_unlock_framebuffers(stw_dev); 4547ec681f3Smrg } 4557ec681f3Smrg} 4567ec681f3Smrg 4577ec681f3SmrgBOOL 4587ec681f3Smrgstw_make_current(struct stw_framebuffer *fb, struct stw_framebuffer *fbRead, struct stw_context *ctx) 4597ec681f3Smrg{ 4607ec681f3Smrg struct stw_context *old_ctx = NULL; 4617ec681f3Smrg BOOL ret = FALSE; 4627ec681f3Smrg 4637ec681f3Smrg if (!stw_dev) 4647ec681f3Smrg return FALSE; 4657ec681f3Smrg 4667ec681f3Smrg old_ctx = stw_current_context(); 4677ec681f3Smrg if (old_ctx != NULL) { 4687ec681f3Smrg if (old_ctx == ctx) { 4697ec681f3Smrg if (old_ctx->current_framebuffer == fb && old_ctx->current_read_framebuffer == fbRead) { 4707ec681f3Smrg /* Return if already current. */ 4717ec681f3Smrg return TRUE; 4727ec681f3Smrg } 4737ec681f3Smrg } else { 4747ec681f3Smrg if (old_ctx->shared) { 4757ec681f3Smrg if (old_ctx->current_framebuffer) { 4767ec681f3Smrg stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb, 4777ec681f3Smrg ST_FLUSH_FRONT | ST_FLUSH_WAIT); 4787ec681f3Smrg } else { 4797ec681f3Smrg struct pipe_fence_handle *fence = NULL; 4807ec681f3Smrg old_ctx->st->flush(old_ctx->st, 4817ec681f3Smrg ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence, 4827ec681f3Smrg NULL, NULL); 4837ec681f3Smrg } 4847ec681f3Smrg } else { 4857ec681f3Smrg if (old_ctx->current_framebuffer) 4867ec681f3Smrg stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb, 4877ec681f3Smrg ST_FLUSH_FRONT); 4887ec681f3Smrg else 4897ec681f3Smrg old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL); 4907ec681f3Smrg } 4917ec681f3Smrg } 4927ec681f3Smrg } 4937ec681f3Smrg 4947ec681f3Smrg if (ctx) { 4957ec681f3Smrg if (!fb || !fbRead) 4967ec681f3Smrg goto fail; 4977ec681f3Smrg 4987ec681f3Smrg if (fb->iPixelFormat != ctx->iPixelFormat) { 4997ec681f3Smrg SetLastError(ERROR_INVALID_PIXEL_FORMAT); 5007ec681f3Smrg goto fail; 5017ec681f3Smrg } 5027ec681f3Smrg if (fbRead->iPixelFormat != ctx->iPixelFormat) { 5037ec681f3Smrg SetLastError(ERROR_INVALID_PIXEL_FORMAT); 5047ec681f3Smrg goto fail; 5057ec681f3Smrg } 5067ec681f3Smrg 5077ec681f3Smrg stw_framebuffer_lock(fb); 5087ec681f3Smrg stw_framebuffer_update(fb); 5097ec681f3Smrg stw_framebuffer_reference_locked(fb); 5107ec681f3Smrg stw_framebuffer_unlock(fb); 5117ec681f3Smrg 5127ec681f3Smrg stw_framebuffer_lock(fbRead); 5137ec681f3Smrg if (fbRead != fb) 5147ec681f3Smrg stw_framebuffer_update(fbRead); 5157ec681f3Smrg stw_framebuffer_reference_locked(fbRead); 5167ec681f3Smrg stw_framebuffer_unlock(fbRead); 5177ec681f3Smrg 5187ec681f3Smrg struct stw_framebuffer *old_fb = ctx->current_framebuffer; 5197ec681f3Smrg struct stw_framebuffer *old_fbRead = ctx->current_read_framebuffer; 5207ec681f3Smrg ctx->current_framebuffer = fb; 5217ec681f3Smrg ctx->current_read_framebuffer = fbRead; 5227ec681f3Smrg 5237ec681f3Smrg ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, 5247ec681f3Smrg fb->stfb, fbRead->stfb); 5257ec681f3Smrg 5267ec681f3Smrg /* Release the old framebuffers from this context. */ 5277ec681f3Smrg release_old_framebuffers(old_fb, old_fbRead, ctx); 5287ec681f3Smrg 5297ec681f3Smrgfail: 5307ec681f3Smrg /* fb and fbRead must be unlocked at this point. */ 5317ec681f3Smrg if (fb) 5327ec681f3Smrg assert(!stw_own_mutex(&fb->mutex)); 5337ec681f3Smrg if (fbRead) 5347ec681f3Smrg assert(!stw_own_mutex(&fbRead->mutex)); 5357ec681f3Smrg 5367ec681f3Smrg /* On failure, make the thread's current rendering context not current 5377ec681f3Smrg * before returning. 5387ec681f3Smrg */ 5397ec681f3Smrg if (!ret) { 5407ec681f3Smrg stw_make_current(NULL, NULL, NULL); 5417ec681f3Smrg } 5427ec681f3Smrg } else { 5437ec681f3Smrg ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 5447ec681f3Smrg } 5457ec681f3Smrg 5467ec681f3Smrg /* Unreference the previous framebuffer if any. It must be done after 5477ec681f3Smrg * make_current, as it can be referenced inside. 5487ec681f3Smrg */ 5497ec681f3Smrg if (old_ctx && old_ctx != ctx) { 5507ec681f3Smrg release_old_framebuffers(old_ctx->current_framebuffer, old_ctx->current_read_framebuffer, old_ctx); 5517ec681f3Smrg old_ctx->current_framebuffer = NULL; 5527ec681f3Smrg old_ctx->current_read_framebuffer = NULL; 5537ec681f3Smrg } 5547ec681f3Smrg 5557ec681f3Smrg return ret; 5567ec681f3Smrg} 5577ec681f3Smrg 5587ec681f3Smrgstatic struct stw_framebuffer * 5597ec681f3Smrgget_unlocked_refd_framebuffer_from_dc(HDC hDC) 5607ec681f3Smrg{ 5617ec681f3Smrg if (!hDC) 5627ec681f3Smrg return NULL; 5637ec681f3Smrg 5647ec681f3Smrg /* This call locks fb's mutex */ 5657ec681f3Smrg struct stw_framebuffer *fb = stw_framebuffer_from_hdc(hDC); 5667ec681f3Smrg if (!fb) { 5677ec681f3Smrg /* Applications should call SetPixelFormat before creating a context, 5687ec681f3Smrg * but not all do, and the opengl32 runtime seems to use a default 5697ec681f3Smrg * pixel format in some cases, so we must create a framebuffer for 5707ec681f3Smrg * those here. 5717ec681f3Smrg */ 5727ec681f3Smrg int iPixelFormat = get_matching_pixel_format(hDC); 5737ec681f3Smrg if (iPixelFormat) 5747ec681f3Smrg fb = stw_framebuffer_create(WindowFromDC(hDC), iPixelFormat, STW_FRAMEBUFFER_WGL_WINDOW); 5757ec681f3Smrg if (!fb) 5767ec681f3Smrg return NULL; 5777ec681f3Smrg } 5787ec681f3Smrg stw_framebuffer_reference_locked(fb); 5797ec681f3Smrg stw_framebuffer_unlock(fb); 5807ec681f3Smrg return fb; 5817ec681f3Smrg} 5827ec681f3Smrg 5837ec681f3SmrgBOOL 5847ec681f3Smrgstw_make_current_by_handles(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc) 5857ec681f3Smrg{ 5867ec681f3Smrg struct stw_context *ctx = stw_lookup_context(dhglrc); 5877ec681f3Smrg if (dhglrc && !ctx) { 5887ec681f3Smrg stw_make_current_by_handles(NULL, NULL, 0); 5897ec681f3Smrg return FALSE; 5907ec681f3Smrg } 5917ec681f3Smrg 5927ec681f3Smrg struct stw_framebuffer *fb = get_unlocked_refd_framebuffer_from_dc(hDrawDC); 5937ec681f3Smrg if (ctx && !fb) { 5947ec681f3Smrg stw_make_current_by_handles(NULL, NULL, 0); 5957ec681f3Smrg return FALSE; 5967ec681f3Smrg } 5977ec681f3Smrg 5987ec681f3Smrg struct stw_framebuffer *fbRead = (hDrawDC == hReadDC || hReadDC == NULL) ? 5997ec681f3Smrg fb : get_unlocked_refd_framebuffer_from_dc(hReadDC); 6007ec681f3Smrg if (ctx && !fbRead) { 6017ec681f3Smrg release_old_framebuffers(fb, NULL, ctx); 6027ec681f3Smrg stw_make_current_by_handles(NULL, NULL, 0); 6037ec681f3Smrg return FALSE; 6047ec681f3Smrg } 6057ec681f3Smrg 6067ec681f3Smrg BOOL success = stw_make_current(fb, fbRead, ctx); 6077ec681f3Smrg 6087ec681f3Smrg if (ctx) { 6097ec681f3Smrg if (success) { 6107ec681f3Smrg ctx->hDrawDC = hDrawDC; 6117ec681f3Smrg ctx->hReadDC = hReadDC; 6127ec681f3Smrg } else { 6137ec681f3Smrg ctx->hDrawDC = NULL; 6147ec681f3Smrg ctx->hReadDC = NULL; 6157ec681f3Smrg } 6167ec681f3Smrg 6177ec681f3Smrg assert(fb && fbRead); 6187ec681f3Smrg /* In the success case, the context took extra references on these framebuffers, 6197ec681f3Smrg * so release our local references. 6207ec681f3Smrg */ 6217ec681f3Smrg stw_lock_framebuffers(stw_dev); 6227ec681f3Smrg stw_framebuffer_lock(fb); 6237ec681f3Smrg stw_framebuffer_release_locked(fb, ctx->st); 6247ec681f3Smrg if (fb != fbRead) { 6257ec681f3Smrg stw_framebuffer_lock(fbRead); 6267ec681f3Smrg stw_framebuffer_release_locked(fbRead, ctx->st); 6277ec681f3Smrg } 6287ec681f3Smrg stw_unlock_framebuffers(stw_dev); 6297ec681f3Smrg } 6307ec681f3Smrg return success; 6317ec681f3Smrg} 6327ec681f3Smrg 6337ec681f3Smrg 6347ec681f3Smrg/** 6357ec681f3Smrg * Notify the current context that the framebuffer has become invalid. 6367ec681f3Smrg */ 6377ec681f3Smrgvoid 6387ec681f3Smrgstw_notify_current_locked( struct stw_framebuffer *fb ) 6397ec681f3Smrg{ 6407ec681f3Smrg p_atomic_inc(&fb->stfb->stamp); 6417ec681f3Smrg} 6427ec681f3Smrg 6437ec681f3Smrg 6447ec681f3Smrg/** 6457ec681f3Smrg * Although WGL allows different dispatch entrypoints per context 6467ec681f3Smrg */ 6477ec681f3Smrgstatic const GLCLTPROCTABLE cpt = 6487ec681f3Smrg{ 6497ec681f3Smrg OPENGL_VERSION_110_ENTRIES, 6507ec681f3Smrg { 6517ec681f3Smrg &glNewList, 6527ec681f3Smrg &glEndList, 6537ec681f3Smrg &glCallList, 6547ec681f3Smrg &glCallLists, 6557ec681f3Smrg &glDeleteLists, 6567ec681f3Smrg &glGenLists, 6577ec681f3Smrg &glListBase, 6587ec681f3Smrg &glBegin, 6597ec681f3Smrg &glBitmap, 6607ec681f3Smrg &glColor3b, 6617ec681f3Smrg &glColor3bv, 6627ec681f3Smrg &glColor3d, 6637ec681f3Smrg &glColor3dv, 6647ec681f3Smrg &glColor3f, 6657ec681f3Smrg &glColor3fv, 6667ec681f3Smrg &glColor3i, 6677ec681f3Smrg &glColor3iv, 6687ec681f3Smrg &glColor3s, 6697ec681f3Smrg &glColor3sv, 6707ec681f3Smrg &glColor3ub, 6717ec681f3Smrg &glColor3ubv, 6727ec681f3Smrg &glColor3ui, 6737ec681f3Smrg &glColor3uiv, 6747ec681f3Smrg &glColor3us, 6757ec681f3Smrg &glColor3usv, 6767ec681f3Smrg &glColor4b, 6777ec681f3Smrg &glColor4bv, 6787ec681f3Smrg &glColor4d, 6797ec681f3Smrg &glColor4dv, 6807ec681f3Smrg &glColor4f, 6817ec681f3Smrg &glColor4fv, 6827ec681f3Smrg &glColor4i, 6837ec681f3Smrg &glColor4iv, 6847ec681f3Smrg &glColor4s, 6857ec681f3Smrg &glColor4sv, 6867ec681f3Smrg &glColor4ub, 6877ec681f3Smrg &glColor4ubv, 6887ec681f3Smrg &glColor4ui, 6897ec681f3Smrg &glColor4uiv, 6907ec681f3Smrg &glColor4us, 6917ec681f3Smrg &glColor4usv, 6927ec681f3Smrg &glEdgeFlag, 6937ec681f3Smrg &glEdgeFlagv, 6947ec681f3Smrg &glEnd, 6957ec681f3Smrg &glIndexd, 6967ec681f3Smrg &glIndexdv, 6977ec681f3Smrg &glIndexf, 6987ec681f3Smrg &glIndexfv, 6997ec681f3Smrg &glIndexi, 7007ec681f3Smrg &glIndexiv, 7017ec681f3Smrg &glIndexs, 7027ec681f3Smrg &glIndexsv, 7037ec681f3Smrg &glNormal3b, 7047ec681f3Smrg &glNormal3bv, 7057ec681f3Smrg &glNormal3d, 7067ec681f3Smrg &glNormal3dv, 7077ec681f3Smrg &glNormal3f, 7087ec681f3Smrg &glNormal3fv, 7097ec681f3Smrg &glNormal3i, 7107ec681f3Smrg &glNormal3iv, 7117ec681f3Smrg &glNormal3s, 7127ec681f3Smrg &glNormal3sv, 7137ec681f3Smrg &glRasterPos2d, 7147ec681f3Smrg &glRasterPos2dv, 7157ec681f3Smrg &glRasterPos2f, 7167ec681f3Smrg &glRasterPos2fv, 7177ec681f3Smrg &glRasterPos2i, 7187ec681f3Smrg &glRasterPos2iv, 7197ec681f3Smrg &glRasterPos2s, 7207ec681f3Smrg &glRasterPos2sv, 7217ec681f3Smrg &glRasterPos3d, 7227ec681f3Smrg &glRasterPos3dv, 7237ec681f3Smrg &glRasterPos3f, 7247ec681f3Smrg &glRasterPos3fv, 7257ec681f3Smrg &glRasterPos3i, 7267ec681f3Smrg &glRasterPos3iv, 7277ec681f3Smrg &glRasterPos3s, 7287ec681f3Smrg &glRasterPos3sv, 7297ec681f3Smrg &glRasterPos4d, 7307ec681f3Smrg &glRasterPos4dv, 7317ec681f3Smrg &glRasterPos4f, 7327ec681f3Smrg &glRasterPos4fv, 7337ec681f3Smrg &glRasterPos4i, 7347ec681f3Smrg &glRasterPos4iv, 7357ec681f3Smrg &glRasterPos4s, 7367ec681f3Smrg &glRasterPos4sv, 7377ec681f3Smrg &glRectd, 7387ec681f3Smrg &glRectdv, 7397ec681f3Smrg &glRectf, 7407ec681f3Smrg &glRectfv, 7417ec681f3Smrg &glRecti, 7427ec681f3Smrg &glRectiv, 7437ec681f3Smrg &glRects, 7447ec681f3Smrg &glRectsv, 7457ec681f3Smrg &glTexCoord1d, 7467ec681f3Smrg &glTexCoord1dv, 7477ec681f3Smrg &glTexCoord1f, 7487ec681f3Smrg &glTexCoord1fv, 7497ec681f3Smrg &glTexCoord1i, 7507ec681f3Smrg &glTexCoord1iv, 7517ec681f3Smrg &glTexCoord1s, 7527ec681f3Smrg &glTexCoord1sv, 7537ec681f3Smrg &glTexCoord2d, 7547ec681f3Smrg &glTexCoord2dv, 7557ec681f3Smrg &glTexCoord2f, 7567ec681f3Smrg &glTexCoord2fv, 7577ec681f3Smrg &glTexCoord2i, 7587ec681f3Smrg &glTexCoord2iv, 7597ec681f3Smrg &glTexCoord2s, 7607ec681f3Smrg &glTexCoord2sv, 7617ec681f3Smrg &glTexCoord3d, 7627ec681f3Smrg &glTexCoord3dv, 7637ec681f3Smrg &glTexCoord3f, 7647ec681f3Smrg &glTexCoord3fv, 7657ec681f3Smrg &glTexCoord3i, 7667ec681f3Smrg &glTexCoord3iv, 7677ec681f3Smrg &glTexCoord3s, 7687ec681f3Smrg &glTexCoord3sv, 7697ec681f3Smrg &glTexCoord4d, 7707ec681f3Smrg &glTexCoord4dv, 7717ec681f3Smrg &glTexCoord4f, 7727ec681f3Smrg &glTexCoord4fv, 7737ec681f3Smrg &glTexCoord4i, 7747ec681f3Smrg &glTexCoord4iv, 7757ec681f3Smrg &glTexCoord4s, 7767ec681f3Smrg &glTexCoord4sv, 7777ec681f3Smrg &glVertex2d, 7787ec681f3Smrg &glVertex2dv, 7797ec681f3Smrg &glVertex2f, 7807ec681f3Smrg &glVertex2fv, 7817ec681f3Smrg &glVertex2i, 7827ec681f3Smrg &glVertex2iv, 7837ec681f3Smrg &glVertex2s, 7847ec681f3Smrg &glVertex2sv, 7857ec681f3Smrg &glVertex3d, 7867ec681f3Smrg &glVertex3dv, 7877ec681f3Smrg &glVertex3f, 7887ec681f3Smrg &glVertex3fv, 7897ec681f3Smrg &glVertex3i, 7907ec681f3Smrg &glVertex3iv, 7917ec681f3Smrg &glVertex3s, 7927ec681f3Smrg &glVertex3sv, 7937ec681f3Smrg &glVertex4d, 7947ec681f3Smrg &glVertex4dv, 7957ec681f3Smrg &glVertex4f, 7967ec681f3Smrg &glVertex4fv, 7977ec681f3Smrg &glVertex4i, 7987ec681f3Smrg &glVertex4iv, 7997ec681f3Smrg &glVertex4s, 8007ec681f3Smrg &glVertex4sv, 8017ec681f3Smrg &glClipPlane, 8027ec681f3Smrg &glColorMaterial, 8037ec681f3Smrg &glCullFace, 8047ec681f3Smrg &glFogf, 8057ec681f3Smrg &glFogfv, 8067ec681f3Smrg &glFogi, 8077ec681f3Smrg &glFogiv, 8087ec681f3Smrg &glFrontFace, 8097ec681f3Smrg &glHint, 8107ec681f3Smrg &glLightf, 8117ec681f3Smrg &glLightfv, 8127ec681f3Smrg &glLighti, 8137ec681f3Smrg &glLightiv, 8147ec681f3Smrg &glLightModelf, 8157ec681f3Smrg &glLightModelfv, 8167ec681f3Smrg &glLightModeli, 8177ec681f3Smrg &glLightModeliv, 8187ec681f3Smrg &glLineStipple, 8197ec681f3Smrg &glLineWidth, 8207ec681f3Smrg &glMaterialf, 8217ec681f3Smrg &glMaterialfv, 8227ec681f3Smrg &glMateriali, 8237ec681f3Smrg &glMaterialiv, 8247ec681f3Smrg &glPointSize, 8257ec681f3Smrg &glPolygonMode, 8267ec681f3Smrg &glPolygonStipple, 8277ec681f3Smrg &glScissor, 8287ec681f3Smrg &glShadeModel, 8297ec681f3Smrg &glTexParameterf, 8307ec681f3Smrg &glTexParameterfv, 8317ec681f3Smrg &glTexParameteri, 8327ec681f3Smrg &glTexParameteriv, 8337ec681f3Smrg &glTexImage1D, 8347ec681f3Smrg &glTexImage2D, 8357ec681f3Smrg &glTexEnvf, 8367ec681f3Smrg &glTexEnvfv, 8377ec681f3Smrg &glTexEnvi, 8387ec681f3Smrg &glTexEnviv, 8397ec681f3Smrg &glTexGend, 8407ec681f3Smrg &glTexGendv, 8417ec681f3Smrg &glTexGenf, 8427ec681f3Smrg &glTexGenfv, 8437ec681f3Smrg &glTexGeni, 8447ec681f3Smrg &glTexGeniv, 8457ec681f3Smrg &glFeedbackBuffer, 8467ec681f3Smrg &glSelectBuffer, 8477ec681f3Smrg &glRenderMode, 8487ec681f3Smrg &glInitNames, 8497ec681f3Smrg &glLoadName, 8507ec681f3Smrg &glPassThrough, 8517ec681f3Smrg &glPopName, 8527ec681f3Smrg &glPushName, 8537ec681f3Smrg &glDrawBuffer, 8547ec681f3Smrg &glClear, 8557ec681f3Smrg &glClearAccum, 8567ec681f3Smrg &glClearIndex, 8577ec681f3Smrg &glClearColor, 8587ec681f3Smrg &glClearStencil, 8597ec681f3Smrg &glClearDepth, 8607ec681f3Smrg &glStencilMask, 8617ec681f3Smrg &glColorMask, 8627ec681f3Smrg &glDepthMask, 8637ec681f3Smrg &glIndexMask, 8647ec681f3Smrg &glAccum, 8657ec681f3Smrg &glDisable, 8667ec681f3Smrg &glEnable, 8677ec681f3Smrg &glFinish, 8687ec681f3Smrg &glFlush, 8697ec681f3Smrg &glPopAttrib, 8707ec681f3Smrg &glPushAttrib, 8717ec681f3Smrg &glMap1d, 8727ec681f3Smrg &glMap1f, 8737ec681f3Smrg &glMap2d, 8747ec681f3Smrg &glMap2f, 8757ec681f3Smrg &glMapGrid1d, 8767ec681f3Smrg &glMapGrid1f, 8777ec681f3Smrg &glMapGrid2d, 8787ec681f3Smrg &glMapGrid2f, 8797ec681f3Smrg &glEvalCoord1d, 8807ec681f3Smrg &glEvalCoord1dv, 8817ec681f3Smrg &glEvalCoord1f, 8827ec681f3Smrg &glEvalCoord1fv, 8837ec681f3Smrg &glEvalCoord2d, 8847ec681f3Smrg &glEvalCoord2dv, 8857ec681f3Smrg &glEvalCoord2f, 8867ec681f3Smrg &glEvalCoord2fv, 8877ec681f3Smrg &glEvalMesh1, 8887ec681f3Smrg &glEvalPoint1, 8897ec681f3Smrg &glEvalMesh2, 8907ec681f3Smrg &glEvalPoint2, 8917ec681f3Smrg &glAlphaFunc, 8927ec681f3Smrg &glBlendFunc, 8937ec681f3Smrg &glLogicOp, 8947ec681f3Smrg &glStencilFunc, 8957ec681f3Smrg &glStencilOp, 8967ec681f3Smrg &glDepthFunc, 8977ec681f3Smrg &glPixelZoom, 8987ec681f3Smrg &glPixelTransferf, 8997ec681f3Smrg &glPixelTransferi, 9007ec681f3Smrg &glPixelStoref, 9017ec681f3Smrg &glPixelStorei, 9027ec681f3Smrg &glPixelMapfv, 9037ec681f3Smrg &glPixelMapuiv, 9047ec681f3Smrg &glPixelMapusv, 9057ec681f3Smrg &glReadBuffer, 9067ec681f3Smrg &glCopyPixels, 9077ec681f3Smrg &glReadPixels, 9087ec681f3Smrg &glDrawPixels, 9097ec681f3Smrg &glGetBooleanv, 9107ec681f3Smrg &glGetClipPlane, 9117ec681f3Smrg &glGetDoublev, 9127ec681f3Smrg &glGetError, 9137ec681f3Smrg &glGetFloatv, 9147ec681f3Smrg &glGetIntegerv, 9157ec681f3Smrg &glGetLightfv, 9167ec681f3Smrg &glGetLightiv, 9177ec681f3Smrg &glGetMapdv, 9187ec681f3Smrg &glGetMapfv, 9197ec681f3Smrg &glGetMapiv, 9207ec681f3Smrg &glGetMaterialfv, 9217ec681f3Smrg &glGetMaterialiv, 9227ec681f3Smrg &glGetPixelMapfv, 9237ec681f3Smrg &glGetPixelMapuiv, 9247ec681f3Smrg &glGetPixelMapusv, 9257ec681f3Smrg &glGetPolygonStipple, 9267ec681f3Smrg &glGetString, 9277ec681f3Smrg &glGetTexEnvfv, 9287ec681f3Smrg &glGetTexEnviv, 9297ec681f3Smrg &glGetTexGendv, 9307ec681f3Smrg &glGetTexGenfv, 9317ec681f3Smrg &glGetTexGeniv, 9327ec681f3Smrg &glGetTexImage, 9337ec681f3Smrg &glGetTexParameterfv, 9347ec681f3Smrg &glGetTexParameteriv, 9357ec681f3Smrg &glGetTexLevelParameterfv, 9367ec681f3Smrg &glGetTexLevelParameteriv, 9377ec681f3Smrg &glIsEnabled, 9387ec681f3Smrg &glIsList, 9397ec681f3Smrg &glDepthRange, 9407ec681f3Smrg &glFrustum, 9417ec681f3Smrg &glLoadIdentity, 9427ec681f3Smrg &glLoadMatrixf, 9437ec681f3Smrg &glLoadMatrixd, 9447ec681f3Smrg &glMatrixMode, 9457ec681f3Smrg &glMultMatrixf, 9467ec681f3Smrg &glMultMatrixd, 9477ec681f3Smrg &glOrtho, 9487ec681f3Smrg &glPopMatrix, 9497ec681f3Smrg &glPushMatrix, 9507ec681f3Smrg &glRotated, 9517ec681f3Smrg &glRotatef, 9527ec681f3Smrg &glScaled, 9537ec681f3Smrg &glScalef, 9547ec681f3Smrg &glTranslated, 9557ec681f3Smrg &glTranslatef, 9567ec681f3Smrg &glViewport, 9577ec681f3Smrg &glArrayElement, 9587ec681f3Smrg &glBindTexture, 9597ec681f3Smrg &glColorPointer, 9607ec681f3Smrg &glDisableClientState, 9617ec681f3Smrg &glDrawArrays, 9627ec681f3Smrg &glDrawElements, 9637ec681f3Smrg &glEdgeFlagPointer, 9647ec681f3Smrg &glEnableClientState, 9657ec681f3Smrg &glIndexPointer, 9667ec681f3Smrg &glIndexub, 9677ec681f3Smrg &glIndexubv, 9687ec681f3Smrg &glInterleavedArrays, 9697ec681f3Smrg &glNormalPointer, 9707ec681f3Smrg &glPolygonOffset, 9717ec681f3Smrg &glTexCoordPointer, 9727ec681f3Smrg &glVertexPointer, 9737ec681f3Smrg &glAreTexturesResident, 9747ec681f3Smrg &glCopyTexImage1D, 9757ec681f3Smrg &glCopyTexImage2D, 9767ec681f3Smrg &glCopyTexSubImage1D, 9777ec681f3Smrg &glCopyTexSubImage2D, 9787ec681f3Smrg &glDeleteTextures, 9797ec681f3Smrg &glGenTextures, 9807ec681f3Smrg &glGetPointerv, 9817ec681f3Smrg &glIsTexture, 9827ec681f3Smrg &glPrioritizeTextures, 9837ec681f3Smrg &glTexSubImage1D, 9847ec681f3Smrg &glTexSubImage2D, 9857ec681f3Smrg &glPopClientAttrib, 9867ec681f3Smrg &glPushClientAttrib 9877ec681f3Smrg } 9887ec681f3Smrg}; 9897ec681f3Smrg 9907ec681f3Smrg 9917ec681f3SmrgPGLCLTPROCTABLE APIENTRY 9927ec681f3SmrgDrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable) 9937ec681f3Smrg{ 9947ec681f3Smrg PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt; 9957ec681f3Smrg 9967ec681f3Smrg if (!stw_make_current_by_handles(hdc, hdc, dhglrc)) 9977ec681f3Smrg r = NULL; 9987ec681f3Smrg 9997ec681f3Smrg return r; 10007ec681f3Smrg} 1001