From 87af12dbdcb078b95391d57dabe53ce17b19f651 Mon Sep 17 00:00:00 2001 From: Karl Schultz Date: Thu, 30 Mar 2006 07:58:24 +0000 Subject: [PATCH] Fixes from Brian to help migrate to render buffer DD interfaces. Also fix bug in the viewport function that was using the viewport size to resize the buffer, when it should have been using the window size. Fix bug in write_rgb_span_32 where the incoming pixel data parameter was coded as a [][4] instead of [][3]. Now all the demos work correctly except singlebuffer. --- src/mesa/drivers/windows/gdi/wgl.c | 45 +- src/mesa/drivers/windows/gdi/wmesa.c | 630 ++++++++++++++---------- src/mesa/drivers/windows/gdi/wmesadef.h | 41 +- 3 files changed, 419 insertions(+), 297 deletions(-) diff --git a/src/mesa/drivers/windows/gdi/wgl.c b/src/mesa/drivers/windows/gdi/wgl.c index 47e32c579fc..197de0743c7 100644 --- a/src/mesa/drivers/windows/gdi/wgl.c +++ b/src/mesa/drivers/windows/gdi/wgl.c @@ -1,4 +1,4 @@ -/* $Id: wgl.c,v 1.11 2006/01/25 06:02:55 kschultz Exp $ */ +/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */ /* * This library is free software; you can redistribute it and/or @@ -38,8 +38,6 @@ #include "GL/wmesa.h" /* protos for wmesa* functions */ -typedef struct wmesa_context *PWMC; - /* * Pixel Format Descriptors */ @@ -143,7 +141,6 @@ int npfd = sizeof(pfd) / sizeof(pfd[0]); typedef struct { WMesaContext ctx; - HDC hdc; } MesaWglCtx; #define MESAWGL_CTX_MAX_COUNT 20 @@ -154,13 +151,15 @@ static unsigned ctx_count = 0; static int ctx_current = -1; static unsigned curPFD = 0; +static HDC CurrentHDC = 0; + + WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc) { int i = 0; if (!ctx_count) { for(i=0;i +#include "context.h" #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" @@ -17,11 +18,63 @@ #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#define FLIP(Y) (Current->height-(Y)-1) -/* Static Data */ +/* linked list of our Framebuffers (windows) */ +static WMesaFramebuffer FirstFramebuffer = NULL; + + +/** + * Create a new WMesaFramebuffer object which will correspond to the + * given HDC (Window handle). + */ +WMesaFramebuffer +wmesa_new_framebuffer(HDC hdc, GLvisual *visual) +{ + WMesaFramebuffer pwfb + = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); + if (pwfb) { + _mesa_initialize_framebuffer(&pwfb->Base, visual); + pwfb->hdc = hdc; + /* insert at head of list */ + pwfb->next = FirstFramebuffer; + FirstFramebuffer = pwfb; + } + return pwfb; +} + + +/** + * Given an hdc, return the corresponding WMesaFramebuffer + */ +WMesaFramebuffer +wmesa_lookup_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hdc == hdc) + return pwfb; + } + return NULL; +} + + +/** + * Given a GLframebuffer, return the corresponding WMesaFramebuffer. + */ +static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) +{ + return (WMesaFramebuffer) fb; +} + + +/** + * Given a GLcontext, return the corresponding WMesaContext. + */ +static WMesaContext wmesa_context(const GLcontext *ctx) +{ + return (WMesaContext) ctx; +} -static PWMC Current = NULL; /* * Every driver should implement a GetString function in order to @@ -33,15 +86,17 @@ static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name) (GLubyte *) "Mesa Windows GDI Driver" : NULL; } + /* * Determine the pixel format based on the pixel size. */ -static void wmSetPixelFormat(PWMC pwc, HDC hDC) +static void wmSetPixelFormat(WMesaContext pwc, HDC hDC) { pwc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL); // Only 16 and 32 bit targets are supported now - assert(pwc->cColorBits == 16 || + assert(pwc->cColorBits == 0 || + pwc->cColorBits == 16 || pwc->cColorBits == 32); switch(pwc->cColorBits){ @@ -59,13 +114,15 @@ static void wmSetPixelFormat(PWMC pwc, HDC hDC) } } -/* + +/** * Create DIB for back buffer. * We write into this memory with the span routines and then blit it * to the window on a buffer swap. + * + * XXX we should probably pass a WMesaFramebuffer ptr, not a WMesaContext! */ - -BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize) +BOOL wmCreateBackingStore(WMesaContext pwc, long lxSize, long lySize) { HDC hdc = pwc->hDC; LPBITMAPINFO pbmi = &(pwc->bmi); @@ -105,7 +162,10 @@ BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize) return TRUE; } -static wmDeleteBackingStore(PWMC pwc) + +/* XXX pass WMesaFramebuffer, not WMesaContext. + */ +static wmDeleteBackingStore(WMesaContext pwc) { if (pwc->hbmDIB) { SelectObject(pwc->dib.hDC, pwc->hOldBitmap); @@ -114,20 +174,48 @@ static wmDeleteBackingStore(PWMC pwc) } } -static void wmesa_get_buffer_size(GLframebuffer *buffer, - GLuint *width, - GLuint *height ) + +/** + * Find the width and height of the window named by hdc. + */ +static void +get_window_size(HDC hdc, GLuint *width, GLuint *height) { - *width = Current->width; - *height = Current->height; + if (WindowFromDC(hdc)) { + RECT rect; + GetClientRect(WindowFromDC(hdc), &rect); + *width = rect.right - rect.left; + *height = rect.bottom - rect.top; + } + else { /* Memory context */ + /* From contributed code - use the size of the desktop + * for the size of a memory context (?) */ + *width = GetDeviceCaps(hdc, HORZRES); + *height = GetDeviceCaps(hdc, VERTRES); + } } -static void wmesa_flush(GLcontext* ctx) +static void +wmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height) { - if (Current->db_flag) { - BitBlt(Current->hDC, 0, 0, Current->width, Current->height, - Current->dib.hDC, 0, 0, SRCCOPY); + WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); + get_window_size(pwfb->hdc, width, height); +} + + +static void wmesa_flush(GLcontext *ctx) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer); + + /* XXX I guess we're _always_ double buffered and render to the back + * buffer. So flushing involves copying the back color buffer to + * the front. + */ + if (pwc->db_flag) { + BitBlt(pwc->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, + pwc->dib.hDC, 0, 0, SRCCOPY); } else { /* Do nothing for single buffer */ @@ -146,28 +234,30 @@ static void wmesa_flush(GLcontext* ctx) /* * Set the color index used to clear the color buffer. */ -static void clear_index(GLcontext* ctx, GLuint index) +static void clear_index(GLcontext *ctx, GLuint index) { + WMesaContext pwc = wmesa_context(ctx); /* Note that indexed mode is not supported yet */ - Current->clearColorRef = RGB(0,0,0); + pwc->clearColorRef = RGB(0,0,0); } /* * Set the color used to clear the color buffer. */ -static void clear_color(GLcontext* ctx, const GLfloat color[4]) +static void clear_color(GLcontext *ctx, const GLfloat color[4]) { + WMesaContext pwc = wmesa_context(ctx); GLubyte col[3]; - UINT bytesPerPixel = Current->cColorBits / 8; + UINT bytesPerPixel = pwc->cColorBits / 8; CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); - Current->clearColorRef = RGB(col[0], col[1], col[2]); - DeleteObject(Current->clearPen); - DeleteObject(Current->clearBrush); - Current->clearPen = CreatePen(PS_SOLID, 1, Current->clearColorRef); - Current->clearBrush = CreateSolidBrush(Current->clearColorRef); + pwc->clearColorRef = RGB(col[0], col[1], col[2]); + DeleteObject(pwc->clearPen); + DeleteObject(pwc->clearBrush); + pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef); + pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); } @@ -180,12 +270,15 @@ static void clear_color(GLcontext* ctx, const GLfloat color[4]) * Clearing of the other non-color buffers is left to the swrast. */ -static void clear(GLcontext* ctx, +static void clear(GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height) { +#define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1) + + WMesaContext pwc = wmesa_context(ctx); int done = 0; /* Let swrast do all the work if the masks are not set to @@ -198,18 +291,11 @@ static void clear(GLcontext* ctx, return; } - /* 'all' means clear the entire window */ - if (all) { - x = y = 0; - width = Current->width; - height = Current->height; - } - /* Back buffer */ if (mask & BUFFER_BIT_BACK_LEFT) { int i, rowSize; - UINT bytesPerPixel = Current->cColorBits / 8; + UINT bytesPerPixel = pwc->cColorBits / 8; LPBYTE lpb, clearRow; LPWORD lpw; BYTE bColor; @@ -224,33 +310,33 @@ static void clear(GLcontext* ctx, /* Now check for an easy clear value */ switch (bytesPerPixel) { case 1: - bColor = BGR8(GetRValue(Current->clearColorRef), - GetGValue(Current->clearColorRef), - GetBValue(Current->clearColorRef)); - memset(Current->pbPixels, bColor, - Current->ScanWidth * height); + bColor = BGR8(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); + memset(pwc->pbPixels, bColor, + pwc->ScanWidth * height); done = 1; break; case 2: - wColor = BGR16(GetRValue(Current->clearColorRef), - GetGValue(Current->clearColorRef), - GetBValue(Current->clearColorRef)); + wColor = BGR16(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); if (((wColor >> 8) & 0xff) == (wColor & 0xff)) { - memset(Current->pbPixels, wColor & 0xff, - Current->ScanWidth * height); + memset(pwc->pbPixels, wColor & 0xff, + pwc->ScanWidth * height); done = 1; } break; case 3: /* fall through */ case 4: - if (GetRValue(Current->clearColorRef) == - GetGValue(Current->clearColorRef) && - GetRValue(Current->clearColorRef) == - GetBValue(Current->clearColorRef)) { - memset(Current->pbPixels, - GetRValue(Current->clearColorRef), - Current->ScanWidth * height); + if (GetRValue(pwc->clearColorRef) == + GetGValue(pwc->clearColorRef) && + GetRValue(pwc->clearColorRef) == + GetBValue(pwc->clearColorRef)) { + memset(pwc->pbPixels, + GetRValue(pwc->clearColorRef), + pwc->ScanWidth * height); done = 1; } break; @@ -263,30 +349,30 @@ static void clear(GLcontext* ctx, /* Need to clear a row at a time. Begin by setting the first * row in the area to be cleared to the clear color. */ - clearRow = Current->pbPixels + - Current->ScanWidth * FLIP(y) + + clearRow = pwc->pbPixels + + pwc->ScanWidth * FLIP(y) + bytesPerPixel * x; switch (bytesPerPixel) { case 1: lpb = clearRow; - bColor = BGR8(GetRValue(Current->clearColorRef), - GetGValue(Current->clearColorRef), - GetBValue(Current->clearColorRef)); + bColor = BGR8(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); memset(lpb, bColor, width); break; case 2: lpw = (LPWORD)clearRow; - wColor = BGR16(GetRValue(Current->clearColorRef), - GetGValue(Current->clearColorRef), - GetBValue(Current->clearColorRef)); + wColor = BGR16(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); for (i=0; iclearColorRef); - g = GetGValue(Current->clearColorRef); - b = GetBValue(Current->clearColorRef); + r = GetRValue(pwc->clearColorRef); + g = GetGValue(pwc->clearColorRef); + b = GetBValue(pwc->clearColorRef); for (i=0; iclearColorRef), - GetGValue(Current->clearColorRef), - GetBValue(Current->clearColorRef)); + dwColor = BGR32(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); for (i=0; iScanWidth; + lpb = clearRow - pwc->ScanWidth; rowSize = width * bytesPerPixel; for (i=1; iScanWidth; + lpb -= pwc->ScanWidth; } } /* not done */ mask &= ~BUFFER_BIT_BACK_LEFT; @@ -318,9 +404,9 @@ static void clear(GLcontext* ctx, /* front buffer */ if (mask & BUFFER_BIT_FRONT_LEFT) { - HDC DC = Current->hDC; - HPEN Old_Pen = SelectObject(DC, Current->clearPen); - HBRUSH Old_Brush = SelectObject(DC, Current->clearBrush); + HDC DC = pwc->hDC; + HPEN Old_Pen = SelectObject(DC, pwc->clearPen); + HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush); Rectangle(DC, x, FLIP(y) + 1, @@ -335,6 +421,7 @@ static void clear(GLcontext* ctx, if (mask) _swrast_Clear(ctx, mask, all, x, y, width, height); +#undef FLIP } @@ -342,18 +429,21 @@ static void clear(GLcontext* ctx, /***** PIXEL Functions *****/ /**********************************************************************/ +#define FLIP(Y) (rb->Height - (Y) - 1) + + /* SINGLE BUFFER */ /* These are slow, but work with all non-indexed visual types */ /* Write a horizontal span of RGBA color pixels with a boolean mask. */ -static void write_rgba_span_single(const GLcontext* ctx, +static void write_rgba_span_single(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ) { - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); GLuint i; (void) ctx; @@ -373,13 +463,13 @@ static void write_rgba_span_single(const GLcontext* ctx, } /* Write a horizontal span of RGB color pixels with a boolean mask. */ -static void write_rgb_span_single(const GLcontext* ctx, +static void write_rgb_span_single(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLubyte rgb[][3], const GLubyte mask[] ) { - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); GLuint i; (void) ctx; @@ -402,14 +492,14 @@ static void write_rgb_span_single(const GLcontext* ctx, * Write a horizontal span of pixels with a boolean mask. The current color * is used for all pixels. */ -static void write_mono_rgba_span_single(const GLcontext* ctx, +static void write_mono_rgba_span_single(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLchan color[4], const GLubyte mask[]) { GLuint i; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); COLORREF colorref; (void) ctx; @@ -427,7 +517,7 @@ static void write_mono_rgba_span_single(const GLcontext* ctx, } /* Write an array of RGBA pixels with a boolean mask. */ -static void write_rgba_pixels_single(const GLcontext* ctx, +static void write_rgba_pixels_single(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], @@ -435,7 +525,7 @@ static void write_rgba_pixels_single(const GLcontext* ctx, const GLubyte mask[] ) { GLuint i; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); (void) ctx; for (i=0; ihDC, x+i, y); + Color = GetPixel(pwc->hDC, x+i, y); rgba[i][RCOMP] = GetRValue(Color); rgba[i][GCOMP] = GetGValue(Color); rgba[i][BCOMP] = GetBValue(Color); @@ -487,21 +578,22 @@ static void read_rgba_span_single(const GLcontext* ctx, /* Read an array of color pixels. */ -static void read_rgba_pixels_single(const GLcontext* ctx, +static void read_rgba_pixels_single(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4]) { - GLuint i; - COLORREF Color; - for (i=0; ihDC, x[i], y2); - rgba[i][RCOMP] = GetRValue(Color); - rgba[i][GCOMP] = GetGValue(Color); - rgba[i][BCOMP] = GetBValue(Color); - rgba[i][ACOMP] = 255; - } + WMesaContext pwc = wmesa_context(ctx); + GLuint i; + COLORREF Color; + for (i=0; ihDC, x[i], y2); + rgba[i][RCOMP] = GetRValue(Color); + rgba[i][GCOMP] = GetGValue(Color); + rgba[i][BCOMP] = GetBValue(Color); + rgba[i][ACOMP] = 255; + } } /*********************************************************************/ @@ -515,13 +607,13 @@ LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ /* Write a horizontal span of RGBA color pixels with a boolean mask. */ -static void write_rgba_span_32(const GLcontext* ctx, +static void write_rgba_span_32(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ) { - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); GLuint i; LPDWORD lpdw; @@ -544,13 +636,13 @@ static void write_rgba_span_32(const GLcontext* ctx, /* Write a horizontal span of RGB color pixels with a boolean mask. */ -static void write_rgb_span_32(const GLcontext* ctx, +static void write_rgb_span_32(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, - const GLubyte rgb[][4], + const GLubyte rgb[][3], const GLubyte mask[] ) { - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); GLuint i; LPDWORD lpdw; @@ -575,7 +667,7 @@ static void write_rgb_span_32(const GLcontext* ctx, * Write a horizontal span of pixels with a boolean mask. The current color * is used for all pixels. */ -static void write_mono_rgba_span_32(const GLcontext* ctx, +static void write_mono_rgba_span_32(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLchan color[4], @@ -584,7 +676,7 @@ static void write_mono_rgba_span_32(const GLcontext* ctx, LPDWORD lpdw; DWORD pixel; GLuint i; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x; y=FLIP(y); pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]); @@ -600,14 +692,14 @@ static void write_mono_rgba_span_32(const GLcontext* ctx, } /* Write an array of RGBA pixels with a boolean mask. */ -static void write_rgba_pixels_32(const GLcontext* ctx, +static void write_rgba_pixels_32(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[]) { GLuint i; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx);; for (i=0; ipbPixels + pwc->ScanWidth * y)) + x; @@ -657,7 +749,7 @@ static void read_rgba_span_32(const GLcontext* ctx, /* Read an array of color pixels. */ -static void read_rgba_pixels_32(const GLcontext* ctx, +static void read_rgba_pixels_32(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4]) @@ -665,7 +757,7 @@ static void read_rgba_pixels_32(const GLcontext* ctx, GLuint i; DWORD pixel; LPDWORD lpdw; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); for (i=0; ipbPixels + (pwc)->ScanWidth * (y)) + (x)); \ /* Write a horizontal span of RGBA color pixels with a boolean mask. */ -static void write_rgba_span_16(const GLcontext* ctx, +static void write_rgba_span_16(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLubyte rgba[][4], const GLubyte mask[] ) { - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); GLuint i; LPWORD lpw; @@ -719,13 +811,13 @@ static void write_rgba_span_16(const GLcontext* ctx, /* Write a horizontal span of RGB color pixels with a boolean mask. */ -static void write_rgb_span_16(const GLcontext* ctx, +static void write_rgb_span_16(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLubyte rgb[][4], const GLubyte mask[] ) { - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); GLuint i; LPWORD lpw; @@ -750,7 +842,7 @@ static void write_rgb_span_16(const GLcontext* ctx, * Write a horizontal span of pixels with a boolean mask. The current color * is used for all pixels. */ -static void write_mono_rgba_span_16(const GLcontext* ctx, +static void write_mono_rgba_span_16(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, const GLchan color[4], @@ -759,7 +851,7 @@ static void write_mono_rgba_span_16(const GLcontext* ctx, LPWORD lpw; WORD pixel; GLuint i; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); (void) ctx; lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * y)) + x; y=FLIP(y); @@ -776,14 +868,14 @@ static void write_mono_rgba_span_16(const GLcontext* ctx, } /* Write an array of RGBA pixels with a boolean mask. */ -static void write_rgba_pixels_16(const GLcontext* ctx, +static void write_rgba_pixels_16(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], const GLubyte rgba[][4], const GLubyte mask[]) { GLuint i; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); (void) ctx; for (i=0; ipbPixels + pwc->ScanWidth * y)) + x; @@ -835,14 +927,14 @@ static void read_rgba_span_16(const GLcontext* ctx, /* Read an array of color pixels. */ -static void read_rgba_pixels_16(const GLcontext* ctx, +static void read_rgba_pixels_16(const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], GLubyte rgba[][4]) { GLuint i, pixel; LPWORD lpw; - PWMC pwc = Current; + WMesaContext pwc = wmesa_context(ctx); for (i=0; iWidth = width; + rb->Height = height; return GL_TRUE; } @@ -930,13 +1029,14 @@ static void wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, GLuint width, GLuint height) { - if (Current->width != width || Current->height != height) { - Current->width = width; - Current->height = height; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); + + if (pwfb->Base.Width != width || pwfb->Base.Height != height) { /* Realloc back buffer */ - if (Current->db_flag) { - wmDeleteBackingStore(Current); - wmCreateBackingStore(Current, width, height); + if (pwc->db_flag) { + wmDeleteBackingStore(pwc); + wmCreateBackingStore(pwc, width, height); } } _mesa_resize_framebuffer(ctx, buffer, width, height); @@ -950,15 +1050,25 @@ wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, * Remember, we have no opportunity to respond to conventional * resize events since the driver has no event loop. * Thus, we poll. - * Note that this trick isn't fool-proof. If the application never calls - * glViewport, our notion of the current window size may be incorrect. + * MakeCurrent also ends up making a call here, so that ensures + * we get the viewport set correctly, even if the app does not call + * glViewport and relies on the defaults. */ static void wmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height) { - if (Current->width != width || Current->height != height) { - wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, width, height); + WMesaContext pwc = wmesa_context(ctx); + GLuint new_width, new_height; + + wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height); + + if (new_width != width || new_height != height) { + /** + * Either the window was resized or the viewport changed - not sure which. + * So call resize buffers to resize them if the window size changed. + */ + wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height); ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ } } @@ -1014,6 +1124,8 @@ WMesaContext WMesaCreateContext(HDC hDC, WMesaContext c; struct dd_function_table functions; GLint red_bits, green_bits, blue_bits, alpha_bits; + GLcontext *ctx; + GLvisual *visual; (void) Pal; @@ -1065,19 +1177,19 @@ WMesaContext WMesaCreateContext(HDC hDC, break; } /* Create visual based on flags */ - c->gl_visual = _mesa_create_visual(rgb_flag, - db_flag, /* db_flag */ - GL_FALSE, /* stereo */ - red_bits, green_bits, blue_bits, /* color RGB */ - alpha_flag ? alpha_bits : 0, /* color A */ - 0, /* index bits */ - DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ - 8, /* stencil_bits */ - 16,16,16, /* accum RGB */ - alpha_flag ? 16 : 0, /* accum A */ - 1); /* num samples */ + visual = _mesa_create_visual(rgb_flag, + db_flag, /* db_flag */ + GL_FALSE, /* stereo */ + red_bits, green_bits, blue_bits, /* color RGB */ + alpha_flag ? alpha_bits : 0, /* color A */ + 0, /* index bits */ + DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ + 8, /* stencil_bits */ + 16,16,16, /* accum RGB */ + alpha_flag ? 16 : 0, /* accum A */ + 1); /* num samples */ - if (!c->gl_visual) { + if (!visual) { _mesa_free(c); return NULL; } @@ -1094,155 +1206,163 @@ WMesaContext WMesaCreateContext(HDC hDC, functions.ResizeBuffers = wmesa_resize_buffers; functions.Viewport = wmesa_viewport; - /* allocate a new Mesa context */ - c->gl_ctx = _mesa_create_context(c->gl_visual, NULL, - &functions, (void *)c); - if (!c->gl_ctx) { - _mesa_destroy_visual( c->gl_visual ); - _mesa_free(c); - return NULL; - } - - _mesa_enable_sw_extensions(c->gl_ctx); - _mesa_enable_1_3_extensions(c->gl_ctx); - _mesa_enable_1_4_extensions(c->gl_ctx); - _mesa_enable_1_5_extensions(c->gl_ctx); - _mesa_enable_2_0_extensions(c->gl_ctx); + /* initialize the Mesa context data */ + ctx = &c->gl_ctx; + _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c); + + _mesa_enable_sw_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + _mesa_enable_1_4_extensions(ctx); + _mesa_enable_1_5_extensions(ctx); + _mesa_enable_2_0_extensions(ctx); /* Initialize the software rasterizer and helper modules. */ - if (!_swrast_CreateContext(c->gl_ctx) || - !_ac_CreateContext(c->gl_ctx) || - !_tnl_CreateContext(c->gl_ctx) || - !_swsetup_CreateContext(c->gl_ctx)) { - _mesa_destroy_visual(c->gl_visual); - _mesa_destroy_framebuffer(c->gl_buffer); - _mesa_free_context_data(c->gl_ctx); + if (!_swrast_CreateContext(ctx) || + !_ac_CreateContext(ctx) || + !_tnl_CreateContext(ctx) || + !_swsetup_CreateContext(ctx)) { + _mesa_free_context_data(ctx); _mesa_free(c); return NULL; } - _swsetup_Wakeup(c->gl_ctx); - TNL_CONTEXT(c->gl_ctx)->Driver.RunPipeline = _tnl_run_pipeline; + _swsetup_Wakeup(ctx); + TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; return c; } -void WMesaDestroyContext( void ) + +void WMesaDestroyContext( WMesaContext pwc ) { - WMesaContext c = Current; + GLcontext *ctx = &pwc->gl_ctx; + GET_CURRENT_CONTEXT(cur_ctx); - WMesaMakeCurrent(NULL); + if (cur_ctx == ctx) { + /* unbind current if deleting current context */ + WMesaMakeCurrent(NULL, NULL); + } /* Release for device, not memory contexts */ - if(WindowFromDC(c->hDC) != NULL) + if (WindowFromDC(pwc->hDC) != NULL) { - ReleaseDC(WindowFromDC(c->hDC), c->hDC); + ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); } - DeleteObject(c->clearPen); - DeleteObject(c->clearBrush); + DeleteObject(pwc->clearPen); + DeleteObject(pwc->clearBrush); - if (c->db_flag) - wmDeleteBackingStore(c); + if (pwc->db_flag) + wmDeleteBackingStore(pwc); - _swsetup_DestroyContext(c->gl_ctx); - _tnl_DestroyContext(c->gl_ctx); - _ac_DestroyContext(c->gl_ctx); - _swrast_DestroyContext(c->gl_ctx); + _swsetup_DestroyContext(ctx); + _tnl_DestroyContext(ctx); + _ac_DestroyContext(ctx); + _swrast_DestroyContext(ctx); - _mesa_destroy_visual(c->gl_visual); - _mesa_destroy_framebuffer(c->gl_buffer); - _mesa_free_context_data(c->gl_ctx); - _mesa_free(c->gl_ctx); - _mesa_free(c); + _mesa_free_context_data(ctx); + _mesa_free(pwc); } -void WMesaMakeCurrent(WMesaContext c) +/** + * Create a new color renderbuffer. + */ +struct gl_renderbuffer * +wmesa_new_renderbuffer(void) { - /* return if already current */ - if (Current == c || c == NULL) - return; + struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); + if (!rb) + return NULL; + + _mesa_init_renderbuffer(rb, (GLuint)0); + + rb->_BaseFormat = GL_RGBA; + rb->InternalFormat = GL_RGBA; + rb->DataType = CHAN_TYPE; + rb->Delete = wmesa_delete_renderbuffer; + rb->AllocStorage = wmesa_renderbuffer_storage; + return rb; +} + + +void WMesaMakeCurrent(WMesaContext c, HDC hdc) +{ + WMesaFramebuffer pwfb; + + { + /* return if already current */ + GET_CURRENT_CONTEXT(ctx); + WMesaContext pwc = wmesa_context(ctx); + if (c == pwc && pwc->hDC == hdc) + return; + } - /* Lazy creation of buffers */ - if (!c->gl_buffer) { + pwfb = wmesa_lookup_framebuffer(hdc); + + /* Lazy creation of framebuffers */ + if (c && !pwfb) { struct gl_renderbuffer *rb; - RECT rect; - - /* Determine window size */ - if (WindowFromDC(c->hDC)) { - GetClientRect(WindowFromDC(c->hDC), &rect); - c->width = rect.right - rect.left; - c->height = rect.bottom - rect.top; - } - else { /* Memory context */ - /* From contributed code - use the size of the desktop - * for the size of a memory context (?) */ - c->width = GetDeviceCaps(c->hDC, HORZRES); - c->height = GetDeviceCaps(c->hDC, VERTRES); - } + GLvisual *visual = &c->gl_ctx.Visual; + GLuint width, height; + + get_window_size(hdc, &width, &height); + c->clearPen = CreatePen(PS_SOLID, 1, 0); c->clearBrush = CreateSolidBrush(0); /* Create back buffer if double buffered */ if (c->db_flag) { - wmCreateBackingStore(c, c->width, c->height); - + wmCreateBackingStore(c, width, height); } - c->gl_buffer = _mesa_create_framebuffer(c->gl_visual); - if (!c->gl_buffer) - return; - - rb = CALLOC_STRUCT(gl_renderbuffer); - - if (!rb) - return; - - _mesa_init_renderbuffer(rb, (GLuint)0); - - rb->_BaseFormat = GL_RGBA; - rb->InternalFormat = GL_RGBA; - rb->DataType = CHAN_TYPE; - rb->Delete = wmesa_delete_renderbuffer; - rb->AllocStorage = wmesa_renderbuffer_storage; - - if (c->db_flag) - _mesa_add_renderbuffer(c->gl_buffer, BUFFER_BACK_LEFT, rb); - else - _mesa_add_renderbuffer(c->gl_buffer, BUFFER_FRONT_LEFT, rb); - wmesa_set_renderbuffer_funcs(rb, c->pixelformat, c->db_flag); - - /* Let Mesa own the Depth, Stencil, and Accum buffers */ - _mesa_add_soft_renderbuffers(c->gl_buffer, - GL_FALSE, /* color */ - c->gl_visual->depthBits > 0, - c->gl_visual->stencilBits > 0, - c->gl_visual->accumRedBits > 0, - c->alpha_flag, - GL_FALSE); + pwfb = wmesa_new_framebuffer(hdc, visual); + + /* need a color renderbuffer */ + rb = wmesa_new_renderbuffer(); + if (c->db_flag) + _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb); + else + _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb); + wmesa_set_renderbuffer_funcs(rb, c->pixelformat, c->db_flag); + + /* Let Mesa own the Depth, Stencil, and Accum buffers */ + _mesa_add_soft_renderbuffers(&pwfb->Base, + GL_FALSE, /* color */ + visual->depthBits > 0, + visual->stencilBits > 0, + visual->accumRedBits > 0, + c->alpha_flag, + GL_FALSE); } - - - - if (Current = c) - _mesa_make_current(c->gl_ctx, c->gl_buffer, c->gl_buffer); + if (c && pwfb) + _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base); + else + _mesa_make_current(NULL, NULL, NULL); } -void WMesaSwapBuffers( void ) +void WMesaSwapBuffers( HDC hdc ) { GET_CURRENT_CONTEXT(ctx); - + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); + + if (!pwfb) { + _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); + return; + } + /* If we're swapping the buffer associated with the current context * we have to flush any pending rendering commands first. */ - if (Current && Current->gl_ctx == ctx) + if (pwc->hDC == hdc) { _mesa_notifySwapBuffers(ctx); - - if (Current->db_flag) - wmesa_flush(ctx); -} -/**********************************************************************/ -/***** END *****/ -/**********************************************************************/ + BitBlt(pwc->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, + pwc->dib.hDC, 0, 0, SRCCOPY); + } + else { + /* XXX for now only allow swapping current window */ + _mesa_problem(NULL, "wmesa: can't swap non-current window"); + } +} diff --git a/src/mesa/drivers/windows/gdi/wmesadef.h b/src/mesa/drivers/windows/gdi/wmesadef.h index 8b2f4912d6c..296000a12f7 100644 --- a/src/mesa/drivers/windows/gdi/wmesadef.h +++ b/src/mesa/drivers/windows/gdi/wmesadef.h @@ -1,27 +1,28 @@ +#ifndef WMESADEF_H +#define WMESADEF_H #include "context.h" -typedef struct _dibSection{ +typedef struct _dibSection { HDC hDC; HANDLE hFileMap; BOOL fFlushed; LPVOID base; -}WMDIBSECTION, *PWMDIBSECTION; +} WMDIBSECTION, *PWMDIBSECTION; -typedef struct wmesa_context{ - GLcontext *gl_ctx; /* The core GL/Mesa context */ - GLvisual *gl_visual; /* Describes the buffers */ - GLframebuffer *gl_buffer; /* Depth, stencil, accum, etc buffers*/ +/** + * The Windows Mesa rendering context, derived from GLcontext. + */ +struct wmesa_context { + GLcontext gl_ctx; /* The core GL/Mesa context */ HDC hDC; COLORREF clearColorRef; HPEN clearPen; HBRUSH clearBrush; - GLuint width; - GLuint height; - GLuint ScanWidth; - GLboolean rgb_flag; - GLboolean db_flag; - GLboolean alpha_flag; + GLuint ScanWidth; /* XXX move into wmesa_framebuffer */ + GLboolean rgb_flag; /* XXX remove - use gl_visual field */ + GLboolean db_flag; /* XXX remove - use gl_visual field */ + GLboolean alpha_flag; /* XXX remove - use gl_visual field */ WMDIBSECTION dib; BITMAPINFO bmi; HBITMAP hbmDIB; @@ -29,6 +30,20 @@ typedef struct wmesa_context{ PBYTE pbPixels; BYTE cColorBits; int pixelformat; -} *PWMC; +}; +/** + * Windows framebuffer, derived from gl_framebuffer + */ +struct wmesa_framebuffer +{ + struct gl_framebuffer Base; + HDC hdc; + struct wmesa_framebuffer *next; +}; + +typedef struct wmesa_framebuffer *WMesaFramebuffer; + + +#endif /* WMESADEF_H */ -- 2.30.2