wgl: Share more code between icd and standalone driver.

This commit is contained in:
José Fonseca 2009-02-19 10:52:08 +00:00
parent d98bc1e324
commit d32ae764e9
11 changed files with 220 additions and 446 deletions

View File

@ -14,13 +14,9 @@ if env['platform'] in ['windows']:
env.Append(CPPDEFINES = [
'_GDI32_', # prevent wgl* being declared __declspec(dllimport)
'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
'__GL_EXPORTS',
'_GNU_H_WINDOWS32_DEFINES',
])
sources = [
'stw.c',
'icd/stw_icd.c',
'wgl/stw_wgl.c',

View File

@ -35,77 +35,11 @@
#include "shared/stw_public.h"
#include "icd/stw_icd.h"
#include "stw.h"
#define DRV_CONTEXT_MAX 32
static GLCLTPROCTABLE cpt;
static boolean cpt_initialized = FALSE;
struct stw_icd
{
pipe_mutex mutex;
GLCLTPROCTABLE cpt;
boolean cpt_initialized;
struct {
struct stw_context *ctx;
} ctx_array[DRV_CONTEXT_MAX];
};
static struct stw_icd *stw_icd = NULL;
boolean
stw_icd_init( void )
{
static struct stw_icd stw_icd_storage;
assert(!stw_icd);
stw_icd = &stw_icd_storage;
memset(stw_icd, 0, sizeof *stw_icd);
pipe_mutex_init( stw_icd->mutex );
return TRUE;
}
void
stw_icd_cleanup(void)
{
int i;
if (!stw_icd)
return;
pipe_mutex_lock( stw_icd->mutex );
{
/* Ensure all contexts are destroyed */
for (i = 0; i < DRV_CONTEXT_MAX; i++)
if (stw_icd->ctx_array[i].ctx)
stw_delete_context( stw_icd->ctx_array[i].ctx );
}
pipe_mutex_unlock( stw_icd->mutex );
pipe_mutex_init( stw_icd->mutex );
stw_icd = NULL;
}
static struct stw_context *
lookup_context( struct stw_icd *icd,
DHGLRC dhglrc )
{
if (dhglrc == 0 ||
dhglrc >= DRV_CONTEXT_MAX)
return NULL;
if (icd == NULL)
return NULL;
return icd->ctx_array[dhglrc - 1].ctx;
}
BOOL APIENTRY
DrvCopyContext(
@ -113,63 +47,16 @@ DrvCopyContext(
DHGLRC dhrcDest,
UINT fuMask )
{
BOOL ret = FALSE;
if (!stw_icd)
return FALSE;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *src = lookup_context( stw_icd, dhrcSource );
struct stw_context *dst = lookup_context( stw_icd, dhrcDest );
if (src == NULL || dst == NULL)
goto done;
ret = stw_copy_context( src, dst, fuMask );
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return ret;
return stw_copy_context(dhrcSource, dhrcDest, fuMask);
}
DHGLRC APIENTRY
DrvCreateLayerContext(
HDC hdc,
INT iLayerPlane )
{
DHGLRC handle = 0;
if (!stw_icd)
return handle;
pipe_mutex_lock( stw_icd->mutex );
{
int i;
for (i = 0; i < DRV_CONTEXT_MAX; i++) {
if (stw_icd->ctx_array[i].ctx == NULL)
break;
}
/* No slot available, fail:
*/
if (i == DRV_CONTEXT_MAX)
goto done;
stw_icd->ctx_array[i].ctx = stw_create_context( hdc, iLayerPlane );
if (stw_icd->ctx_array[i].ctx == NULL)
goto done;
/* success:
*/
handle = (DHGLRC) i + 1;
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return handle;
return stw_create_layer_context( hdc, iLayerPlane );
}
DHGLRC APIENTRY
@ -183,30 +70,7 @@ BOOL APIENTRY
DrvDeleteContext(
DHGLRC dhglrc )
{
BOOL ret = FALSE;
if (!stw_icd)
return ret;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *ctx;
ctx = lookup_context( stw_icd, dhglrc );
if (ctx == NULL)
goto done;
if (stw_delete_context( ctx ) == FALSE)
goto done;
stw_icd->ctx_array[dhglrc - 1].ctx = NULL;
ret = TRUE;
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return ret;
return stw_delete_context( dhglrc );
}
BOOL APIENTRY
@ -280,32 +144,7 @@ BOOL APIENTRY
DrvReleaseContext(
DHGLRC dhglrc )
{
BOOL ret = FALSE;
if (!stw_icd)
return ret;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *ctx;
/* XXX: The expectation is that ctx is the same context which is
* current for this thread. We should check that and return False
* if not the case.
*/
ctx = lookup_context( stw_icd, dhglrc );
if (ctx == NULL)
goto done;
if (stw_make_current( NULL, NULL ) == FALSE)
goto done;
ret = TRUE;
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return ret;
return stw_release_context(dhglrc);
}
void APIENTRY
@ -671,38 +510,20 @@ DrvSetContext(
DHGLRC dhglrc,
PFN_SETPROCTABLE pfnSetProcTable )
{
PGLCLTPROCTABLE result = NULL;
debug_printf( "%s( 0x%p, %u, 0x%p )\n",
__FUNCTION__, hdc, dhglrc, pfnSetProcTable );
if (!stw_icd)
return result;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *ctx;
debug_printf( "%s( 0x%p, %u, 0x%p )\n",
__FUNCTION__, hdc, dhglrc, pfnSetProcTable );
/* Although WGL allows different dispatch entrypoints per
*/
if (!stw_icd->cpt_initialized) {
init_proc_table( &stw_icd->cpt );
stw_icd->cpt_initialized = TRUE;
}
ctx = lookup_context( stw_icd, dhglrc );
if (ctx == NULL)
goto done;
if (!stw_make_current( hdc, ctx ))
goto done;
result = &stw_icd->cpt;
/* Although WGL allows different dispatch entrypoints per
*/
if (!cpt_initialized) {
init_proc_table( &cpt );
cpt_initialized = TRUE;
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return result;
if (!stw_make_current( hdc, dhglrc ))
return NULL;
return &cpt;
}
int APIENTRY

View File

@ -40,26 +40,38 @@
#include "stw_public.h"
#include "stw_context.h"
static struct stw_context *ctx_head = NULL;
static HDC current_hdc = NULL;
static struct stw_context *current_hrc = NULL;
static UINT_PTR current_hglrc = 0;
BOOL
stw_copy_context(
struct stw_context *src,
struct stw_context *dst,
UINT_PTR hglrcSrc,
UINT_PTR hglrcDst,
UINT mask )
{
(void) src;
(void) dst;
(void) mask;
struct stw_context *src;
struct stw_context *dst;
BOOL ret = FALSE;
return FALSE;
pipe_mutex_lock( stw_dev->mutex );
src = stw_lookup_context( hglrcSrc );
dst = stw_lookup_context( hglrcDst );
if (src && dst) {
/* FIXME */
(void) src;
(void) dst;
(void) mask;
}
pipe_mutex_unlock( stw_dev->mutex );
return ret;
}
struct stw_context *
stw_create_context(
UINT_PTR
stw_create_layer_context(
HDC hdc,
int iLayerPlane )
{
@ -68,19 +80,23 @@ stw_create_context(
struct stw_context *ctx = NULL;
GLvisual *visual = NULL;
struct pipe_context *pipe = NULL;
UINT_PTR hglrc;
if(!stw_dev)
return 0;
if (iLayerPlane != 0)
return NULL;
return 0;
pfi = stw_pixelformat_get( hdc );
if (pfi == 0)
return NULL;
return 0;
pf = pixelformat_get_info( pfi - 1 );
ctx = CALLOC_STRUCT( stw_context );
if (ctx == NULL)
return NULL;
return 0;
ctx->hdc = hdc;
ctx->color_bits = GetDeviceCaps( ctx->hdc, BITSPIXEL );
@ -119,10 +135,30 @@ stw_create_context(
ctx->st->ctx->DriverCtx = ctx;
ctx->next = ctx_head;
ctx_head = ctx;
pipe_mutex_lock( stw_dev->mutex );
{
UINT_PTR i;
return ctx;
for (i = 0; i < STW_CONTEXT_MAX; i++) {
if (stw_dev->ctx_array[i].ctx == NULL)
break;
}
/* No slot available, fail:
*/
if (i == STW_CONTEXT_MAX)
goto done;
stw_dev->ctx_array[i].ctx = ctx;
/* success:
*/
hglrc = i + 1;
}
done:
pipe_mutex_unlock( stw_dev->mutex );
return hglrc;
fail:
if (visual)
@ -132,47 +168,80 @@ fail:
pipe->destroy( pipe );
FREE( ctx );
return NULL;
return 0;
}
BOOL
stw_delete_context(
struct stw_context *hglrc )
UINT_PTR hglrc )
{
struct stw_context **link = &ctx_head;
struct stw_context *ctx = ctx_head;
struct stw_context *ctx ;
BOOL ret = FALSE;
pipe_mutex_lock( stw_dev->mutex );
while (ctx != NULL) {
if (ctx == hglrc) {
GLcontext *glctx = ctx->st->ctx;
GET_CURRENT_CONTEXT( glcurctx );
struct stw_framebuffer *fb;
ctx = stw_lookup_context(hglrc);
if (ctx) {
GLcontext *glctx = ctx->st->ctx;
GET_CURRENT_CONTEXT( glcurctx );
struct stw_framebuffer *fb;
/* Unbind current if deleting current context.
*/
if (glcurctx == glctx)
st_make_current( NULL, NULL, NULL );
/* Unbind current if deleting current context.
*/
if (glcurctx == glctx)
st_make_current( NULL, NULL, NULL );
fb = framebuffer_from_hdc( ctx->hdc );
if (fb)
framebuffer_destroy( fb );
fb = framebuffer_from_hdc( ctx->hdc );
if (fb)
framebuffer_destroy( fb );
if (WindowFromDC( ctx->hdc ) != NULL)
ReleaseDC( WindowFromDC( ctx->hdc ), ctx->hdc );
if (WindowFromDC( ctx->hdc ) != NULL)
ReleaseDC( WindowFromDC( ctx->hdc ), ctx->hdc );
st_destroy_context( ctx->st );
st_destroy_context( ctx->st );
*link = ctx->next;
FREE( ctx );
return TRUE;
}
link = &ctx->next;
ctx = ctx->next;
FREE( ctx );
stw_dev->ctx_array[hglrc - 1].ctx = NULL;
ret = TRUE;
}
return FALSE;
pipe_mutex_unlock( stw_dev->mutex );
return ret;
}
BOOL
stw_release_context(
UINT_PTR hglrc )
{
BOOL ret = FALSE;
if (!stw_dev)
return ret;
pipe_mutex_lock( stw_dev->mutex );
{
struct stw_context *ctx;
/* XXX: The expectation is that ctx is the same context which is
* current for this thread. We should check that and return False
* if not the case.
*/
ctx = stw_lookup_context( hglrc );
if (ctx == NULL)
goto done;
if (stw_make_current( NULL, 0 ) == FALSE)
goto done;
ret = TRUE;
}
done:
pipe_mutex_unlock( stw_dev->mutex );
return ret;
}
/* Find the width and height of the window named by hdc.
@ -193,10 +262,10 @@ get_window_size( HDC hdc, GLuint *width, GLuint *height )
}
}
struct stw_context *
UINT_PTR
stw_get_current_context( void )
{
return current_hrc;
return current_hglrc;
}
HDC
@ -208,30 +277,32 @@ stw_get_current_dc( void )
BOOL
stw_make_current(
HDC hdc,
struct stw_context *hglrc )
UINT_PTR hglrc )
{
struct stw_context *ctx = ctx_head;
struct stw_context *ctx;
GET_CURRENT_CONTEXT( glcurctx );
struct stw_framebuffer *fb;
GLuint width = 0;
GLuint height = 0;
current_hdc = hdc;
current_hrc = hglrc;
if (!stw_dev)
return FALSE;
if (hdc == NULL || hglrc == NULL) {
pipe_mutex_lock( stw_dev->mutex );
ctx = stw_lookup_context( hglrc );
pipe_mutex_unlock( stw_dev->mutex );
if (ctx == NULL)
return FALSE;
current_hdc = hdc;
current_hglrc = hglrc;
if (hdc == NULL || hglrc == 0) {
st_make_current( NULL, NULL, NULL );
return TRUE;
}
while (ctx != NULL) {
if (ctx == hglrc)
break;
ctx = ctx->next;
}
if (ctx == NULL)
return FALSE;
/* Return if already current.
*/
if (glcurctx != NULL) {
@ -273,20 +344,3 @@ stw_make_current(
return TRUE;
}
struct stw_context *
stw_context_from_hdc(
HDC hdc )
{
struct stw_context *ctx = ctx_head;
while (ctx != NULL) {
if (ctx->hdc == hdc)
return ctx;
ctx = ctx->next;
}
return NULL;
}

View File

@ -37,17 +37,6 @@ struct stw_context
struct st_context *st;
HDC hdc;
DWORD color_bits;
struct stw_context *next;
};
struct stw_context *
stw_context_from_hdc(HDC hdc );
#endif /* STW_CONTEXT_H */

View File

@ -34,7 +34,6 @@
#include "shared/stw_winsys.h"
#include "shared/stw_pixelformat.h"
#include "shared/stw_public.h"
#include "stw.h"
struct stw_device *stw_dev = NULL;
@ -57,7 +56,7 @@ st_flush_frontbuffer(struct pipe_screen *screen,
boolean
stw_shared_init(const struct stw_winsys *stw_winsys)
st_init(const struct stw_winsys *stw_winsys)
{
static struct stw_device stw_dev_storage;
@ -78,6 +77,8 @@ stw_shared_init(const struct stw_winsys *stw_winsys)
stw_dev->screen->flush_frontbuffer = st_flush_frontbuffer;
pipe_mutex_init( stw_dev->mutex );
pixelformat_init();
return TRUE;
@ -89,8 +90,24 @@ error1:
void
stw_shared_cleanup(void)
st_cleanup(void)
{
UINT_PTR i;
if (!stw_dev)
return;
pipe_mutex_lock( stw_dev->mutex );
{
/* Ensure all contexts are destroyed */
for (i = 0; i < STW_CONTEXT_MAX; i++)
if (stw_dev->ctx_array[i].ctx)
stw_delete_context( i + 1 );
}
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_destroy( stw_dev->mutex );
if(stw_dev) {
#ifdef DEBUG
debug_memory_end(stw_dev->memdbg_no);
@ -99,3 +116,18 @@ stw_shared_cleanup(void)
stw_dev = NULL;
}
struct stw_context *
stw_lookup_context( UINT_PTR dhglrc )
{
if (dhglrc == 0 ||
dhglrc >= STW_CONTEXT_MAX)
return NULL;
if (stw_dev == NULL)
return NULL;
return stw_dev->ctx_array[dhglrc - 1].ctx;
}

View File

@ -25,8 +25,15 @@
*
**************************************************************************/
#ifndef ST_DEVICE_H_
#define ST_DEVICE_H_
#ifndef STW_DEVICE_H_
#define STW_DEVICE_H_
#include "pipe/p_compiler.h"
#include "pipe/p_thread.h"
#define STW_CONTEXT_MAX 32
struct pipe_screen;
@ -36,13 +43,21 @@ struct stw_device
const struct stw_winsys *stw_winsys;
struct pipe_screen *screen;
pipe_mutex mutex;
struct {
struct stw_context *ctx;
} ctx_array[STW_CONTEXT_MAX];
#ifdef DEBUG
unsigned long memdbg_no;
#endif
};
struct stw_context *
stw_lookup_context( UINT_PTR hglrc );
extern struct stw_device *stw_dev;
#endif /* ST_DEVICE_H_ */
#endif /* STW_DEVICE_H_ */

View File

@ -29,31 +29,24 @@
#define STW_PUBLIC_H
#include <windows.h>
#include "pipe/p_compiler.h"
struct stw_winsys;
struct stw_context;
boolean
st_shared_init(const struct stw_winsys *stw_winsys);
void
st_shared_cleanup(void);
BOOL stw_copy_context( struct stw_context *src,
struct stw_context *dst,
BOOL stw_copy_context( UINT_PTR hglrcSrc,
UINT_PTR hglrcDst,
UINT mask );
struct stw_context *stw_create_context( HDC hdc, int iLayerPlane );
UINT_PTR stw_create_layer_context( HDC hdc,
int iLayerPlane );
BOOL stw_delete_context( struct stw_context *ctx );
BOOL stw_delete_context( UINT_PTR hglrc );
struct stw_context *stw_get_current_context( void );
BOOL
stw_release_context( UINT_PTR dhglrc );
UINT_PTR stw_get_current_context( void );
HDC stw_get_current_dc( void );
BOOL stw_make_current( HDC hdc, struct stw_context *ctx );
BOOL stw_make_current( HDC hdc, UINT_PTR hglrc );
BOOL stw_swap_buffers( HDC hdc );

View File

@ -1,57 +0,0 @@
/**************************************************************************
*
* Copyright 2009, VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "stw.h"
#include "shared/stw_winsys.h"
boolean
st_init(const struct stw_winsys *stw_winsys)
{
if (!stw_shared_init( stw_winsys ))
goto fail;
if (!stw_icd_init())
goto fail;
if (!stw_wgl_init())
goto fail;
return TRUE;
fail:
st_cleanup();
return FALSE;
}
void
st_cleanup(void)
{
stw_icd_cleanup();
stw_shared_cleanup();
stw_wgl_cleanup();
}

View File

@ -1,53 +0,0 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef STW_H
#define STW_H
#include "pipe/p_compiler.h"
struct stw_winsys;
/* Public interface:
*/
boolean stw_init( const struct stw_winsys *stw_winsys );
void stw_cleanup( void );
/* Internal functions
*/
boolean stw_shared_init( const struct stw_winsys *stw_winsys );
boolean stw_icd_init( void );
boolean stw_wgl_init( void );
void stw_shared_cleanup( void );
void stw_icd_cleanup( void );
void stw_wgl_cleanup( void );
#endif /* STW_H */

View File

@ -30,22 +30,6 @@
#include "util/u_debug.h"
#include "shared/stw_public.h"
#include "stw_wgl.h"
#include "stw.h"
boolean stw_wgl_init( void )
{
debug_printf("%s\n", __FUNCTION__);
return TRUE;
}
void stw_wgl_cleanup( void )
{
}
static INLINE struct stw_context *stw_context( HGLRC hglrc )
{
return (struct stw_context *)hglrc;
}
WINGDIAPI BOOL APIENTRY
@ -54,8 +38,8 @@ wglCopyContext(
HGLRC hglrcDst,
UINT mask )
{
return stw_copy_context( stw_context(hglrcSrc),
stw_context(hglrcDst),
return stw_copy_context( (UINT_PTR)hglrcSrc,
(UINT_PTR)hglrcDst,
mask );
}
@ -63,7 +47,7 @@ WINGDIAPI HGLRC APIENTRY
wglCreateContext(
HDC hdc )
{
return (HGLRC) stw_create_context( hdc, 0 );
return wglCreateLayerContext(hdc, 0);
}
WINGDIAPI HGLRC APIENTRY
@ -71,21 +55,21 @@ wglCreateLayerContext(
HDC hdc,
int iLayerPlane )
{
return (HGLRC) stw_create_context( hdc, iLayerPlane );
return (HGLRC) stw_create_layer_context( hdc, iLayerPlane );
}
WINGDIAPI BOOL APIENTRY
wglDeleteContext(
HGLRC hglrc )
{
return stw_delete_context( stw_context(hglrc) );
return stw_delete_context( (UINT_PTR)hglrc );
}
WINGDIAPI HGLRC APIENTRY
wglGetCurrentContext( VOID )
{
return (HGLRC) stw_get_current_context();
return (HGLRC)stw_get_current_context();
}
WINGDIAPI HDC APIENTRY
@ -99,7 +83,7 @@ wglMakeCurrent(
HDC hdc,
HGLRC hglrc )
{
return stw_make_current( hdc, stw_context(hglrc) );
return stw_make_current( hdc, (UINT_PTR)hglrc );
}

View File

@ -31,7 +31,7 @@
#include <windows.h>
#include "GL/gl.h"
#include <GL/gl.h>
/*