BOOL sw_DeleteContext(DHGLRC dhglrc) { struct sw_context* sw_ctx = (struct sw_context*)dhglrc; /* Those get clobbered by _mesa_free_context_data via _glapi_set{context,dispath_table} */ void* icd_save = IntGetCurrentICDPrivate(); const GLDISPATCHTABLE* table_save = IntGetCurrentDispatchTable(); /* Destroy everything */ _mesa_meta_free( &sw_ctx->mesa ); _swsetup_DestroyContext( &sw_ctx->mesa ); _tnl_DestroyContext( &sw_ctx->mesa ); _vbo_DestroyContext( &sw_ctx->mesa ); _swrast_DestroyContext( &sw_ctx->mesa ); _mesa_free_context_data( &sw_ctx->mesa ); free( sw_ctx ); /* Restore this */ IntSetCurrentDispatchTable(table_save); IntSetCurrentICDPrivate(icd_save); return TRUE; }
BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) { struct wgl_context* ctx = get_context(hglrc); struct wgl_context* old_ctx = get_context(IntGetCurrentRC()); const GLCLTPROCTABLE* apiTable; LONG thread_id = (LONG)GetCurrentThreadId(); if(ctx) { struct wgl_dc_data* dc_data = get_dc_data(hdc); if(!dc_data) { ERR("wglMakeCurrent was passed an invalid DC handle.\n"); SetLastError(ERROR_INVALID_HANDLE); return FALSE; } /* Check compatibility */ if((ctx->icd_data != dc_data->icd_data) || (ctx->pixelformat != dc_data->pixelformat)) { /* That's bad, man */ ERR("HGLRC %p and HDC %p are not compatible.\n", hglrc, hdc); release_dc_data(dc_data); SetLastError(ERROR_INVALID_HANDLE); return FALSE; } /* Set the thread ID */ if(InterlockedCompareExchange(&ctx->thread_id, thread_id, 0) != 0) { /* Already current for a thread. Maybe it's us ? */ release_dc_data(dc_data); if(ctx->thread_id != thread_id) SetLastError(ERROR_BUSY); return (ctx->thread_id == thread_id); } if(old_ctx) { /* Unset it */ if(old_ctx->icd_data) old_ctx->icd_data->DrvReleaseContext(old_ctx->dhglrc); else sw_ReleaseContext(old_ctx->dhglrc); InterlockedExchange(&old_ctx->thread_id, 0); } /* Call the ICD or SW implementation */ if(ctx->icd_data) { apiTable = ctx->icd_data->DrvSetContext(hdc, ctx->dhglrc, set_api_table); if(!apiTable) { ERR("DrvSetContext failed!\n"); /* revert */ InterlockedExchange(&ctx->thread_id, 0); IntSetCurrentDispatchTable(&StubTable.glDispatchTable); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } set_api_table(apiTable); /* Make it current */ IntMakeCurrent(hglrc, hdc, dc_data); } else { /* We must set current before, SW implementation relies on it */ IntMakeCurrent(hglrc, hdc, dc_data); if(!sw_SetContext(dc_data, ctx->dhglrc)) { ERR("sw_SetContext failed!\n"); /* revert */ IntMakeCurrent(NULL, NULL, NULL); InterlockedExchange(&ctx->thread_id, 0); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } } } else if(old_ctx) { if(old_ctx->icd_data) old_ctx->icd_data->DrvReleaseContext(old_ctx->dhglrc); else sw_ReleaseContext(old_ctx->dhglrc); InterlockedExchange(&old_ctx->thread_id, 0); /* Unset it */ IntMakeCurrent(NULL, NULL, NULL); /* Reset the no-op table */ set_api_table(&StubTable); /* Test conformance (extreme cases) */ return hglrc == NULL; } else { /* Winetest conformance */ if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC) { ERR( "Error: hdc is not a DC handle!\n"); SetLastError( ERROR_INVALID_HANDLE ); return FALSE; } } return TRUE; }
void APIENTRY set_api_table(const GLCLTPROCTABLE* table) { IntSetCurrentDispatchTable(&table->glDispatchTable); }