summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/windows/gdi/wmesa.c
diff options
context:
space:
mode:
authorKarl Schultz <[email protected]>2006-03-30 07:58:24 +0000
committerKarl Schultz <[email protected]>2006-03-30 07:58:24 +0000
commit87af12dbdcb078b95391d57dabe53ce17b19f651 (patch)
tree20c22ec3b2877fe9a66f0b4ca9d9014bcafa1dde /src/mesa/drivers/windows/gdi/wmesa.c
parenta8c9ecfab005088b1b201abc9d04f5169d1b3b64 (diff)
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.
Diffstat (limited to 'src/mesa/drivers/windows/gdi/wmesa.c')
-rw-r--r--src/mesa/drivers/windows/gdi/wmesa.c630
1 files changed, 375 insertions, 255 deletions
diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c
index 982366be42b..fd7e28817e3 100644
--- a/src/mesa/drivers/windows/gdi/wmesa.c
+++ b/src/mesa/drivers/windows/gdi/wmesa.c
@@ -6,6 +6,7 @@
#include "wmesadef.h"
#include "colors.h"
#include <GL/wmesa.h>
+#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; i<width; i++)
*lpw++ = wColor;
break;
case 3:
lpb = clearRow;
- r = GetRValue(Current->clearColorRef);
- g = GetGValue(Current->clearColorRef);
- b = GetBValue(Current->clearColorRef);
+ r = GetRValue(pwc->clearColorRef);
+ g = GetGValue(pwc->clearColorRef);
+ b = GetBValue(pwc->clearColorRef);
for (i=0; i<width; i++) {
*lpb++ = b;
*lpb++ = g;
@@ -295,9 +381,9 @@ static void clear(GLcontext* ctx,
break;
case 4:
lpdw = (LPDWORD)clearRow;
- dwColor = BGR32(GetRValue(Current->clearColorRef),
- GetGValue(Current->clearColorRef),
- GetBValue(Current->clearColorRef));
+ dwColor = BGR32(GetRValue(pwc->clearColorRef),
+ GetGValue(pwc->clearColorRef),
+ GetBValue(pwc->clearColorRef));
for (i=0; i<width; i++)
*lpdw++ = dwColor;
break;
@@ -306,11 +392,11 @@ static void clear(GLcontext* ctx,
} /* switch */
/* copy cleared row to other rows in buffer */
- lpb = clearRow - Current->ScanWidth;
+ lpb = clearRow - pwc->ScanWidth;
rowSize = width * bytesPerPixel;
for (i=1; i<height; i++) {
memcpy(lpb, clearRow, rowSize);
- lpb -= Current->ScanWidth;
+ 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; i<n; i++)
if (mask[i])
@@ -450,7 +540,7 @@ static void write_rgba_pixels_single(const GLcontext* ctx,
* Write an array of pixels with a boolean mask. The current color
* is used for all pixels.
*/
-static void write_mono_rgba_pixels_single(const GLcontext* ctx,
+static void write_mono_rgba_pixels_single(const GLcontext *ctx,
struct gl_renderbuffer *rb,
GLuint n,
const GLint x[], const GLint y[],
@@ -458,7 +548,7 @@ static void write_mono_rgba_pixels_single(const GLcontext* ctx,
const GLubyte mask[] )
{
GLuint i;
- PWMC pwc = Current;
+ WMesaContext pwc = wmesa_context(ctx);
COLORREF colorref;
(void) ctx;
colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
@@ -468,16 +558,17 @@ static void write_mono_rgba_pixels_single(const GLcontext* ctx,
}
/* Read a horizontal span of color pixels. */
-static void read_rgba_span_single(const GLcontext* ctx,
+static void read_rgba_span_single(const GLcontext *ctx,
struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4] )
{
+ WMesaContext pwc = wmesa_context(ctx);
GLuint i;
COLORREF Color;
y = FLIP(y);
for (i=0; i<n; i++) {
- Color = GetPixel(Current->hDC, 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; i<n; i++) {
- GLint y2 = FLIP(y[i]);
- Color = GetPixel(Current->hDC, 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; i<n; i++) {
+ GLint y2 = FLIP(y[i]);
+ Color = GetPixel(pwc->hDC, 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; i<n; i++)
if (mask[i])
WMSETPIXEL32(pwc, FLIP(y[i]), x[i],
@@ -618,7 +710,7 @@ static void write_rgba_pixels_32(const GLcontext* ctx,
* Write an array of pixels with a boolean mask. The current color
* is used for all pixels.
*/
-static void write_mono_rgba_pixels_32(const GLcontext* ctx,
+static void write_mono_rgba_pixels_32(const GLcontext *ctx,
struct gl_renderbuffer *rb,
GLuint n,
const GLint x[], const GLint y[],
@@ -626,7 +718,7 @@ static void write_mono_rgba_pixels_32(const GLcontext* ctx,
const GLubyte mask[])
{
GLuint i;
- PWMC pwc = Current;
+ WMesaContext pwc = wmesa_context(ctx);
for (i=0; i<n; i++)
if (mask[i])
WMSETPIXEL32(pwc, FLIP(y[i]),x[i],color[RCOMP],
@@ -634,7 +726,7 @@ static void write_mono_rgba_pixels_32(const GLcontext* ctx,
}
/* Read a horizontal span of color pixels. */
-static void read_rgba_span_32(const GLcontext* ctx,
+static void read_rgba_span_32(const GLcontext *ctx,
struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4] )
@@ -642,7 +734,7 @@ static void read_rgba_span_32(const GLcontext* ctx,
GLuint i;
DWORD pixel;
LPDWORD lpdw;
- PWMC pwc = Current;
+ WMesaContext pwc = wmesa_context(ctx);
y = FLIP(y);
lpdw = ((LPDWORD)(pwc->pbPixels + 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; i<n; i++) {
GLint y2 = FLIP(y[i]);
@@ -690,13 +782,13 @@ LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (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; i<n; i++)
if (mask[i])
@@ -795,7 +887,7 @@ static void write_rgba_pixels_16(const GLcontext* ctx,
* Write an array of pixels with a boolean mask. The current color
* is used for all pixels.
*/
-static void write_mono_rgba_pixels_16(const GLcontext* ctx,
+static void write_mono_rgba_pixels_16(const GLcontext *ctx,
struct gl_renderbuffer *rb,
GLuint n,
const GLint x[], const GLint y[],
@@ -803,7 +895,7 @@ static void write_mono_rgba_pixels_16(const GLcontext* ctx,
const GLubyte mask[])
{
GLuint i;
- PWMC pwc = Current;
+ WMesaContext pwc = wmesa_context(ctx);
(void) ctx;
for (i=0; i<n; i++)
if (mask[i])
@@ -812,14 +904,14 @@ static void write_mono_rgba_pixels_16(const GLcontext* ctx,
}
/* Read a horizontal span of color pixels. */
-static void read_rgba_span_16(const GLcontext* ctx,
+static void read_rgba_span_16(const GLcontext *ctx,
struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y,
GLubyte rgba[][4] )
{
GLuint i, pixel;
LPWORD lpw;
- PWMC pwc = Current;
+ WMesaContext pwc = wmesa_context(ctx);
y = FLIP(y);
lpw = ((LPWORD)(pwc->pbPixels + 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; i<n; i++) {
GLint y2 = FLIP(y[i]);
@@ -872,6 +964,11 @@ wmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
_mesa_free(rb);
}
+
+/**
+ * This is called by Mesa whenever it determines that the window size
+ * has changed. Do whatever's needed to cope with that.
+ */
static GLboolean
wmesa_renderbuffer_storage(GLcontext *ctx,
struct gl_renderbuffer *rb,
@@ -879,6 +976,8 @@ wmesa_renderbuffer_storage(GLcontext *ctx,
GLuint width,
GLuint height)
{
+ rb->Width = 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");
+ }
+}