aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/windows/gdi/wmesa.c
diff options
context:
space:
mode:
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");
+ }
+}