Merge branch 'master' of git+ssh://znh@git.freedesktop.org/git/mesa/mesa into 965...
[mesa.git] / src / mesa / drivers / windows / gdi / wmesa.c
1 /*
2 * Windows (Win32/Win64) device driver for Mesa
3 *
4 */
5
6 #include "wmesadef.h"
7 #include "colors.h"
8 #include <GL/wmesa.h>
9 #include "context.h"
10 #include "extensions.h"
11 #include "framebuffer.h"
12 #include "renderbuffer.h"
13 #include "drivers/common/driverfuncs.h"
14 #include "vbo/vbo.h"
15 #include "swrast/swrast.h"
16 #include "swrast_setup/swrast_setup.h"
17 #include "tnl/tnl.h"
18 #include "tnl/t_context.h"
19 #include "tnl/t_pipeline.h"
20
21
22 /* linked list of our Framebuffers (windows) */
23 static WMesaFramebuffer FirstFramebuffer = NULL;
24
25
26 /**
27 * Create a new WMesaFramebuffer object which will correspond to the
28 * given HDC (Window handle).
29 */
30 WMesaFramebuffer
31 wmesa_new_framebuffer(HDC hdc, GLvisual *visual)
32 {
33 WMesaFramebuffer pwfb
34 = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer));
35 if (pwfb) {
36 _mesa_initialize_framebuffer(&pwfb->Base, visual);
37 pwfb->hDC = hdc;
38 /* insert at head of list */
39 pwfb->next = FirstFramebuffer;
40 FirstFramebuffer = pwfb;
41 }
42 return pwfb;
43 }
44
45 /**
46 * Given an hdc, free the corresponding WMesaFramebuffer
47 */
48 void
49 wmesa_free_framebuffer(HDC hdc)
50 {
51 WMesaFramebuffer pwfb, prev;
52 for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
53 if (pwfb->hDC == hdc)
54 break;
55 prev = pwfb;
56 }
57 if (pwfb) {
58 if (pwfb == FirstFramebuffer)
59 FirstFramebuffer = pwfb->next;
60 else
61 prev->next = pwfb->next;
62 free(pwfb);
63 }
64 }
65
66 /**
67 * Given an hdc, return the corresponding WMesaFramebuffer
68 */
69 WMesaFramebuffer
70 wmesa_lookup_framebuffer(HDC hdc)
71 {
72 WMesaFramebuffer pwfb;
73 for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
74 if (pwfb->hDC == hdc)
75 return pwfb;
76 }
77 return NULL;
78 }
79
80
81 /**
82 * Given a GLframebuffer, return the corresponding WMesaFramebuffer.
83 */
84 static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb)
85 {
86 return (WMesaFramebuffer) fb;
87 }
88
89
90 /**
91 * Given a GLcontext, return the corresponding WMesaContext.
92 */
93 static WMesaContext wmesa_context(const GLcontext *ctx)
94 {
95 return (WMesaContext) ctx;
96 }
97
98
99 /*
100 * Every driver should implement a GetString function in order to
101 * return a meaningful GL_RENDERER string.
102 */
103 static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name)
104 {
105 return (name == GL_RENDERER) ?
106 (GLubyte *) "Mesa Windows GDI Driver" : NULL;
107 }
108
109
110 /*
111 * Determine the pixel format based on the pixel size.
112 */
113 static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
114 {
115 pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
116
117 // Only 16 and 32 bit targets are supported now
118 assert(pwfb->cColorBits == 0 ||
119 pwfb->cColorBits == 16 ||
120 pwfb->cColorBits == 32);
121
122 switch(pwfb->cColorBits){
123 case 8:
124 pwfb->pixelformat = PF_INDEX8;
125 break;
126 case 16:
127 pwfb->pixelformat = PF_5R6G5B;
128 break;
129 case 32:
130 pwfb->pixelformat = PF_8R8G8B;
131 break;
132 default:
133 pwfb->pixelformat = PF_BADFORMAT;
134 }
135 }
136
137
138 /**
139 * Create DIB for back buffer.
140 * We write into this memory with the span routines and then blit it
141 * to the window on a buffer swap.
142 */
143 BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize)
144 {
145 HDC hdc = pwfb->hDC;
146 LPBITMAPINFO pbmi = &(pwfb->bmi);
147 HDC hic;
148
149 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
150 pbmi->bmiHeader.biWidth = lxSize;
151 pbmi->bmiHeader.biHeight= -lySize;
152 pbmi->bmiHeader.biPlanes = 1;
153 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwfb->hDC, BITSPIXEL);
154 pbmi->bmiHeader.biCompression = BI_RGB;
155 pbmi->bmiHeader.biSizeImage = 0;
156 pbmi->bmiHeader.biXPelsPerMeter = 0;
157 pbmi->bmiHeader.biYPelsPerMeter = 0;
158 pbmi->bmiHeader.biClrUsed = 0;
159 pbmi->bmiHeader.biClrImportant = 0;
160
161 pwfb->cColorBits = pbmi->bmiHeader.biBitCount;
162 pwfb->ScanWidth = (lxSize * (pwfb->cColorBits / 8) + 3) & ~3;
163
164 hic = CreateIC("display", NULL, NULL, NULL);
165 pwfb->dib_hDC = CreateCompatibleDC(hic);
166
167 pwfb->hbmDIB = CreateDIBSection(hic,
168 &pwfb->bmi,
169 DIB_RGB_COLORS,
170 (void **)&(pwfb->pbPixels),
171 0,
172 0);
173 pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB);
174
175 DeleteDC(hic);
176
177 wmSetPixelFormat(pwfb, pwfb->hDC);
178 return TRUE;
179 }
180
181
182 static wmDeleteBackingStore(WMesaFramebuffer pwfb)
183 {
184 if (pwfb->hbmDIB) {
185 SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap);
186 DeleteDC(pwfb->dib_hDC);
187 DeleteObject(pwfb->hbmDIB);
188 }
189 }
190
191
192 /**
193 * Find the width and height of the window named by hdc.
194 */
195 static void
196 get_window_size(HDC hdc, GLuint *width, GLuint *height)
197 {
198 if (WindowFromDC(hdc)) {
199 RECT rect;
200 GetClientRect(WindowFromDC(hdc), &rect);
201 *width = rect.right - rect.left;
202 *height = rect.bottom - rect.top;
203 }
204 else { /* Memory context */
205 /* From contributed code - use the size of the desktop
206 * for the size of a memory context (?) */
207 *width = GetDeviceCaps(hdc, HORZRES);
208 *height = GetDeviceCaps(hdc, VERTRES);
209 }
210 }
211
212
213 static void
214 wmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height)
215 {
216 WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
217 get_window_size(pwfb->hDC, width, height);
218 }
219
220
221 static void wmesa_flush(GLcontext *ctx)
222 {
223 WMesaContext pwc = wmesa_context(ctx);
224 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer);
225
226 if (ctx->Visual.doubleBufferMode == 1) {
227 BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
228 pwfb->dib_hDC, 0, 0, SRCCOPY);
229 }
230 else {
231 /* Do nothing for single buffer */
232 }
233 }
234
235
236 /**********************************************************************/
237 /***** CLEAR Functions *****/
238 /**********************************************************************/
239
240 /* If we do not implement these, Mesa clears the buffers via the pixel
241 * span writing interface, which is very slow for a clear operation.
242 */
243
244 /*
245 * Set the color index used to clear the color buffer.
246 */
247 static void clear_index(GLcontext *ctx, GLuint index)
248 {
249 WMesaContext pwc = wmesa_context(ctx);
250 /* Note that indexed mode is not supported yet */
251 pwc->clearColorRef = RGB(0,0,0);
252 }
253
254 /*
255 * Set the color used to clear the color buffer.
256 */
257 static void clear_color(GLcontext *ctx, const GLfloat color[4])
258 {
259 WMesaContext pwc = wmesa_context(ctx);
260 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
261 GLubyte col[3];
262 UINT bytesPerPixel = pwfb->cColorBits / 8;
263
264 CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
265 CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
266 CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
267 pwc->clearColorRef = RGB(col[0], col[1], col[2]);
268 DeleteObject(pwc->clearPen);
269 DeleteObject(pwc->clearBrush);
270 pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef);
271 pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef);
272 }
273
274
275 /*
276 * Clear the specified region of the color buffer using the clear color
277 * or index as specified by one of the two functions above.
278 *
279 * This procedure clears either the front and/or the back COLOR buffers.
280 * Only the "left" buffer is cleared since we are not stereo.
281 * Clearing of the other non-color buffers is left to the swrast.
282 */
283
284 static void clear(GLcontext *ctx, GLbitfield mask)
285 {
286 #define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1)
287 const GLint x = ctx->DrawBuffer->_Xmin;
288 const GLint y = ctx->DrawBuffer->_Ymin;
289 const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
290 const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
291
292 WMesaContext pwc = wmesa_context(ctx);
293 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
294 int done = 0;
295
296 /* Let swrast do all the work if the masks are not set to
297 * clear all channels. */
298 if (ctx->Color.ColorMask[0] != 0xff ||
299 ctx->Color.ColorMask[1] != 0xff ||
300 ctx->Color.ColorMask[2] != 0xff ||
301 ctx->Color.ColorMask[3] != 0xff) {
302 _swrast_Clear(ctx, mask);
303 return;
304 }
305
306 /* Back buffer */
307 if (mask & BUFFER_BIT_BACK_LEFT) {
308
309 int i, rowSize;
310 UINT bytesPerPixel = pwfb->cColorBits / 8;
311 LPBYTE lpb, clearRow;
312 LPWORD lpw;
313 BYTE bColor;
314 WORD wColor;
315 BYTE r, g, b;
316 DWORD dwColor;
317 LPDWORD lpdw;
318
319 /* Try for a fast clear - clearing entire buffer with a single
320 * byte value. */
321 if (width == ctx->DrawBuffer->Width &&
322 height == ctx->DrawBuffer->Height) { /* entire buffer */
323 /* Now check for an easy clear value */
324 switch (bytesPerPixel) {
325 case 1:
326 bColor = BGR8(GetRValue(pwc->clearColorRef),
327 GetGValue(pwc->clearColorRef),
328 GetBValue(pwc->clearColorRef));
329 memset(pwfb->pbPixels, bColor,
330 pwfb->ScanWidth * height);
331 done = 1;
332 break;
333 case 2:
334 wColor = BGR16(GetRValue(pwc->clearColorRef),
335 GetGValue(pwc->clearColorRef),
336 GetBValue(pwc->clearColorRef));
337 if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {
338 memset(pwfb->pbPixels, wColor & 0xff,
339 pwfb->ScanWidth * height);
340 done = 1;
341 }
342 break;
343 case 3:
344 /* fall through */
345 case 4:
346 if (GetRValue(pwc->clearColorRef) ==
347 GetGValue(pwc->clearColorRef) &&
348 GetRValue(pwc->clearColorRef) ==
349 GetBValue(pwc->clearColorRef)) {
350 memset(pwfb->pbPixels,
351 GetRValue(pwc->clearColorRef),
352 pwfb->ScanWidth * height);
353 done = 1;
354 }
355 break;
356 default:
357 break;
358 }
359 } /* all */
360
361 if (!done) {
362 /* Need to clear a row at a time. Begin by setting the first
363 * row in the area to be cleared to the clear color. */
364
365 clearRow = pwfb->pbPixels +
366 pwfb->ScanWidth * FLIP(y) +
367 bytesPerPixel * x;
368 switch (bytesPerPixel) {
369 case 1:
370 lpb = clearRow;
371 bColor = BGR8(GetRValue(pwc->clearColorRef),
372 GetGValue(pwc->clearColorRef),
373 GetBValue(pwc->clearColorRef));
374 memset(lpb, bColor, width);
375 break;
376 case 2:
377 lpw = (LPWORD)clearRow;
378 wColor = BGR16(GetRValue(pwc->clearColorRef),
379 GetGValue(pwc->clearColorRef),
380 GetBValue(pwc->clearColorRef));
381 for (i=0; i<width; i++)
382 *lpw++ = wColor;
383 break;
384 case 3:
385 lpb = clearRow;
386 r = GetRValue(pwc->clearColorRef);
387 g = GetGValue(pwc->clearColorRef);
388 b = GetBValue(pwc->clearColorRef);
389 for (i=0; i<width; i++) {
390 *lpb++ = b;
391 *lpb++ = g;
392 *lpb++ = r;
393 }
394 break;
395 case 4:
396 lpdw = (LPDWORD)clearRow;
397 dwColor = BGR32(GetRValue(pwc->clearColorRef),
398 GetGValue(pwc->clearColorRef),
399 GetBValue(pwc->clearColorRef));
400 for (i=0; i<width; i++)
401 *lpdw++ = dwColor;
402 break;
403 default:
404 break;
405 } /* switch */
406
407 /* copy cleared row to other rows in buffer */
408 lpb = clearRow - pwfb->ScanWidth;
409 rowSize = width * bytesPerPixel;
410 for (i=1; i<height; i++) {
411 memcpy(lpb, clearRow, rowSize);
412 lpb -= pwfb->ScanWidth;
413 }
414 } /* not done */
415 mask &= ~BUFFER_BIT_BACK_LEFT;
416 } /* back buffer */
417
418 /* front buffer */
419 if (mask & BUFFER_BIT_FRONT_LEFT) {
420 HDC DC = pwc->hDC;
421 HPEN Old_Pen = SelectObject(DC, pwc->clearPen);
422 HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush);
423 Rectangle(DC,
424 x,
425 FLIP(y) + 1,
426 x + width + 1,
427 FLIP(y) - height + 1);
428 SelectObject(DC, Old_Pen);
429 SelectObject(DC, Old_Brush);
430 mask &= ~BUFFER_BIT_FRONT_LEFT;
431 } /* front buffer */
432
433 /* Call swrast if there is anything left to clear (like DEPTH) */
434 if (mask)
435 _swrast_Clear(ctx, mask);
436
437 #undef FLIP
438 }
439
440
441 /**********************************************************************/
442 /***** PIXEL Functions *****/
443 /**********************************************************************/
444
445 #define FLIP(Y) (rb->Height - (Y) - 1)
446
447
448 /**
449 ** Front Buffer reading/writing
450 ** These are slow, but work with all non-indexed visual types.
451 **/
452
453 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
454 static void write_rgba_span_front(const GLcontext *ctx,
455 struct gl_renderbuffer *rb,
456 GLuint n, GLint x, GLint y,
457 const GLubyte rgba[][4],
458 const GLubyte mask[] )
459 {
460 WMesaContext pwc = wmesa_context(ctx);
461 GLuint i;
462
463 (void) ctx;
464 y=FLIP(y);
465 if (mask) {
466 for (i=0; i<n; i++)
467 if (mask[i])
468 SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP],
469 rgba[i][BCOMP]));
470 }
471 else {
472 for (i=0; i<n; i++)
473 SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP],
474 rgba[i][BCOMP]));
475 }
476
477 }
478
479 /* Write a horizontal span of RGB color pixels with a boolean mask. */
480 static void write_rgb_span_front(const GLcontext *ctx,
481 struct gl_renderbuffer *rb,
482 GLuint n, GLint x, GLint y,
483 const GLubyte rgb[][3],
484 const GLubyte mask[] )
485 {
486 WMesaContext pwc = wmesa_context(ctx);
487 GLuint i;
488
489 (void) ctx;
490 y=FLIP(y);
491 if (mask) {
492 for (i=0; i<n; i++)
493 if (mask[i])
494 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP],
495 rgb[i][BCOMP]));
496 }
497 else {
498 for (i=0; i<n; i++)
499 SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP],
500 rgb[i][BCOMP]));
501 }
502
503 }
504
505 /*
506 * Write a horizontal span of pixels with a boolean mask. The current color
507 * is used for all pixels.
508 */
509 static void write_mono_rgba_span_front(const GLcontext *ctx,
510 struct gl_renderbuffer *rb,
511 GLuint n, GLint x, GLint y,
512 const GLchan color[4],
513 const GLubyte mask[])
514 {
515 GLuint i;
516 WMesaContext pwc = wmesa_context(ctx);
517 COLORREF colorref;
518
519 (void) ctx;
520 colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
521 y=FLIP(y);
522 if (mask) {
523 for (i=0; i<n; i++)
524 if (mask[i])
525 SetPixel(pwc->hDC, x+i, y, colorref);
526 }
527 else
528 for (i=0; i<n; i++)
529 SetPixel(pwc->hDC, x+i, y, colorref);
530
531 }
532
533 /* Write an array of RGBA pixels with a boolean mask. */
534 static void write_rgba_pixels_front(const GLcontext *ctx,
535 struct gl_renderbuffer *rb,
536 GLuint n,
537 const GLint x[], const GLint y[],
538 const GLubyte rgba[][4],
539 const GLubyte mask[] )
540 {
541 GLuint i;
542 WMesaContext pwc = wmesa_context(ctx);
543 (void) ctx;
544 for (i=0; i<n; i++)
545 if (mask[i])
546 SetPixel(pwc->hDC, x[i], FLIP(y[i]),
547 RGB(rgba[i][RCOMP], rgba[i][GCOMP],
548 rgba[i][BCOMP]));
549 }
550
551
552
553 /*
554 * Write an array of pixels with a boolean mask. The current color
555 * is used for all pixels.
556 */
557 static void write_mono_rgba_pixels_front(const GLcontext *ctx,
558 struct gl_renderbuffer *rb,
559 GLuint n,
560 const GLint x[], const GLint y[],
561 const GLchan color[4],
562 const GLubyte mask[] )
563 {
564 GLuint i;
565 WMesaContext pwc = wmesa_context(ctx);
566 COLORREF colorref;
567 (void) ctx;
568 colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]);
569 for (i=0; i<n; i++)
570 if (mask[i])
571 SetPixel(pwc->hDC, x[i], FLIP(y[i]), colorref);
572 }
573
574 /* Read a horizontal span of color pixels. */
575 static void read_rgba_span_front(const GLcontext *ctx,
576 struct gl_renderbuffer *rb,
577 GLuint n, GLint x, GLint y,
578 GLubyte rgba[][4] )
579 {
580 WMesaContext pwc = wmesa_context(ctx);
581 GLuint i;
582 COLORREF Color;
583 y = FLIP(y);
584 for (i=0; i<n; i++) {
585 Color = GetPixel(pwc->hDC, x+i, y);
586 rgba[i][RCOMP] = GetRValue(Color);
587 rgba[i][GCOMP] = GetGValue(Color);
588 rgba[i][BCOMP] = GetBValue(Color);
589 rgba[i][ACOMP] = 255;
590 }
591 }
592
593
594 /* Read an array of color pixels. */
595 static void read_rgba_pixels_front(const GLcontext *ctx,
596 struct gl_renderbuffer *rb,
597 GLuint n, const GLint x[], const GLint y[],
598 GLubyte rgba[][4])
599 {
600 WMesaContext pwc = wmesa_context(ctx);
601 GLuint i;
602 COLORREF Color;
603 for (i=0; i<n; i++) {
604 GLint y2 = FLIP(y[i]);
605 Color = GetPixel(pwc->hDC, x[i], y2);
606 rgba[i][RCOMP] = GetRValue(Color);
607 rgba[i][GCOMP] = GetGValue(Color);
608 rgba[i][BCOMP] = GetBValue(Color);
609 rgba[i][ACOMP] = 255;
610 }
611 }
612
613 /*********************************************************************/
614
615 /* DOUBLE BUFFER 32-bit */
616
617 #define WMSETPIXEL32(pwc, y, x, r, g, b) { \
618 LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
619 *lpdw = BGR32((r),(g),(b)); }
620
621
622
623 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
624 static void write_rgba_span_32(const GLcontext *ctx,
625 struct gl_renderbuffer *rb,
626 GLuint n, GLint x, GLint y,
627 const GLubyte rgba[][4],
628 const GLubyte mask[] )
629 {
630 WMesaContext pwc = wmesa_context(ctx);
631 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
632 GLuint i;
633 LPDWORD lpdw;
634
635 (void) ctx;
636
637 y=FLIP(y);
638 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
639 if (mask) {
640 for (i=0; i<n; i++)
641 if (mask[i])
642 lpdw[i] = BGR32(rgba[i][RCOMP], rgba[i][GCOMP],
643 rgba[i][BCOMP]);
644 }
645 else {
646 for (i=0; i<n; i++)
647 *lpdw++ = BGR32(rgba[i][RCOMP], rgba[i][GCOMP],
648 rgba[i][BCOMP]);
649 }
650 }
651
652
653 /* Write a horizontal span of RGB color pixels with a boolean mask. */
654 static void write_rgb_span_32(const GLcontext *ctx,
655 struct gl_renderbuffer *rb,
656 GLuint n, GLint x, GLint y,
657 const GLubyte rgb[][3],
658 const GLubyte mask[] )
659 {
660 WMesaContext pwc = wmesa_context(ctx);
661 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
662 GLuint i;
663 LPDWORD lpdw;
664
665 (void) ctx;
666
667 y=FLIP(y);
668 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
669 if (mask) {
670 for (i=0; i<n; i++)
671 if (mask[i])
672 lpdw[i] = BGR32(rgb[i][RCOMP], rgb[i][GCOMP],
673 rgb[i][BCOMP]);
674 }
675 else {
676 for (i=0; i<n; i++)
677 *lpdw++ = BGR32(rgb[i][RCOMP], rgb[i][GCOMP],
678 rgb[i][BCOMP]);
679 }
680 }
681
682 /*
683 * Write a horizontal span of pixels with a boolean mask. The current color
684 * is used for all pixels.
685 */
686 static void write_mono_rgba_span_32(const GLcontext *ctx,
687 struct gl_renderbuffer *rb,
688 GLuint n, GLint x, GLint y,
689 const GLchan color[4],
690 const GLubyte mask[])
691 {
692 LPDWORD lpdw;
693 DWORD pixel;
694 GLuint i;
695 WMesaContext pwc = wmesa_context(ctx);
696 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
697 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
698 y=FLIP(y);
699 pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]);
700 if (mask) {
701 for (i=0; i<n; i++)
702 if (mask[i])
703 lpdw[i] = pixel;
704 }
705 else
706 for (i=0; i<n; i++)
707 *lpdw++ = pixel;
708
709 }
710
711 /* Write an array of RGBA pixels with a boolean mask. */
712 static void write_rgba_pixels_32(const GLcontext *ctx,
713 struct gl_renderbuffer *rb,
714 GLuint n, const GLint x[], const GLint y[],
715 const GLubyte rgba[][4],
716 const GLubyte mask[])
717 {
718 GLuint i;
719 WMesaContext pwc = wmesa_context(ctx);
720 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
721 for (i=0; i<n; i++)
722 if (mask[i])
723 WMSETPIXEL32(pwfb, FLIP(y[i]), x[i],
724 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
725 }
726
727 /*
728 * Write an array of pixels with a boolean mask. The current color
729 * is used for all pixels.
730 */
731 static void write_mono_rgba_pixels_32(const GLcontext *ctx,
732 struct gl_renderbuffer *rb,
733 GLuint n,
734 const GLint x[], const GLint y[],
735 const GLchan color[4],
736 const GLubyte mask[])
737 {
738 GLuint i;
739 WMesaContext pwc = wmesa_context(ctx);
740 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
741 for (i=0; i<n; i++)
742 if (mask[i])
743 WMSETPIXEL32(pwfb, FLIP(y[i]),x[i],color[RCOMP],
744 color[GCOMP], color[BCOMP]);
745 }
746
747 /* Read a horizontal span of color pixels. */
748 static void read_rgba_span_32(const GLcontext *ctx,
749 struct gl_renderbuffer *rb,
750 GLuint n, GLint x, GLint y,
751 GLubyte rgba[][4] )
752 {
753 GLuint i;
754 DWORD pixel;
755 LPDWORD lpdw;
756 WMesaContext pwc = wmesa_context(ctx);
757 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
758
759 y = FLIP(y);
760 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
761 for (i=0; i<n; i++) {
762 pixel = lpdw[i];
763 rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16;
764 rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8;
765 rgba[i][BCOMP] = (pixel & 0x000000ff);
766 rgba[i][ACOMP] = 255;
767 }
768 }
769
770
771 /* Read an array of color pixels. */
772 static void read_rgba_pixels_32(const GLcontext *ctx,
773 struct gl_renderbuffer *rb,
774 GLuint n, const GLint x[], const GLint y[],
775 GLubyte rgba[][4])
776 {
777 GLuint i;
778 DWORD pixel;
779 LPDWORD lpdw;
780 WMesaContext pwc = wmesa_context(ctx);
781 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
782
783 for (i=0; i<n; i++) {
784 GLint y2 = FLIP(y[i]);
785 lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i];
786 pixel = *lpdw;
787 rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16;
788 rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8;
789 rgba[i][BCOMP] = (pixel & 0x000000ff);
790 rgba[i][ACOMP] = 255;
791 }
792 }
793
794
795 /*********************************************************************/
796
797 /* DOUBLE BUFFER 16-bit */
798
799 #define WMSETPIXEL16(pwc, y, x, r, g, b) { \
800 LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
801 *lpw = BGR16((r),(g),(b)); }
802
803
804
805 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
806 static void write_rgba_span_16(const GLcontext *ctx,
807 struct gl_renderbuffer *rb,
808 GLuint n, GLint x, GLint y,
809 const GLubyte rgba[][4],
810 const GLubyte mask[] )
811 {
812 WMesaContext pwc = wmesa_context(ctx);
813 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
814 GLuint i;
815 LPWORD lpw;
816
817 (void) ctx;
818
819 y=FLIP(y);
820 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
821 if (mask) {
822 for (i=0; i<n; i++)
823 if (mask[i])
824 lpw[i] = BGR16(rgba[i][RCOMP], rgba[i][GCOMP],
825 rgba[i][BCOMP]);
826 }
827 else {
828 for (i=0; i<n; i++)
829 *lpw++ = BGR16(rgba[i][RCOMP], rgba[i][GCOMP],
830 rgba[i][BCOMP]);
831 }
832 }
833
834
835 /* Write a horizontal span of RGB color pixels with a boolean mask. */
836 static void write_rgb_span_16(const GLcontext *ctx,
837 struct gl_renderbuffer *rb,
838 GLuint n, GLint x, GLint y,
839 const GLubyte rgb[][3],
840 const GLubyte mask[] )
841 {
842 WMesaContext pwc = wmesa_context(ctx);
843 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
844 GLuint i;
845 LPWORD lpw;
846
847 (void) ctx;
848
849 y=FLIP(y);
850 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
851 if (mask) {
852 for (i=0; i<n; i++)
853 if (mask[i])
854 lpw[i] = BGR16(rgb[i][RCOMP], rgb[i][GCOMP],
855 rgb[i][BCOMP]);
856 }
857 else {
858 for (i=0; i<n; i++)
859 *lpw++ = BGR16(rgb[i][RCOMP], rgb[i][GCOMP],
860 rgb[i][BCOMP]);
861 }
862 }
863
864 /*
865 * Write a horizontal span of pixels with a boolean mask. The current color
866 * is used for all pixels.
867 */
868 static void write_mono_rgba_span_16(const GLcontext *ctx,
869 struct gl_renderbuffer *rb,
870 GLuint n, GLint x, GLint y,
871 const GLchan color[4],
872 const GLubyte mask[])
873 {
874 LPWORD lpw;
875 WORD pixel;
876 GLuint i;
877 WMesaContext pwc = wmesa_context(ctx);
878 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
879 (void) ctx;
880 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
881 y=FLIP(y);
882 pixel = BGR16(color[RCOMP], color[GCOMP], color[BCOMP]);
883 if (mask) {
884 for (i=0; i<n; i++)
885 if (mask[i])
886 lpw[i] = pixel;
887 }
888 else
889 for (i=0; i<n; i++)
890 *lpw++ = pixel;
891
892 }
893
894 /* Write an array of RGBA pixels with a boolean mask. */
895 static void write_rgba_pixels_16(const GLcontext *ctx,
896 struct gl_renderbuffer *rb,
897 GLuint n, const GLint x[], const GLint y[],
898 const GLubyte rgba[][4],
899 const GLubyte mask[])
900 {
901 GLuint i;
902 WMesaContext pwc = wmesa_context(ctx);
903 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
904 (void) ctx;
905 for (i=0; i<n; i++)
906 if (mask[i])
907 WMSETPIXEL16(pwfb, FLIP(y[i]), x[i],
908 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
909 }
910
911 /*
912 * Write an array of pixels with a boolean mask. The current color
913 * is used for all pixels.
914 */
915 static void write_mono_rgba_pixels_16(const GLcontext *ctx,
916 struct gl_renderbuffer *rb,
917 GLuint n,
918 const GLint x[], const GLint y[],
919 const GLchan color[4],
920 const GLubyte mask[])
921 {
922 GLuint i;
923 WMesaContext pwc = wmesa_context(ctx);
924 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
925 (void) ctx;
926 for (i=0; i<n; i++)
927 if (mask[i])
928 WMSETPIXEL16(pwfb, FLIP(y[i]),x[i],color[RCOMP],
929 color[GCOMP], color[BCOMP]);
930 }
931
932 /* Read a horizontal span of color pixels. */
933 static void read_rgba_span_16(const GLcontext *ctx,
934 struct gl_renderbuffer *rb,
935 GLuint n, GLint x, GLint y,
936 GLubyte rgba[][4] )
937 {
938 GLuint i, pixel;
939 LPWORD lpw;
940 WMesaContext pwc = wmesa_context(ctx);
941 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
942
943 y = FLIP(y);
944 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x;
945 for (i=0; i<n; i++) {
946 pixel = lpw[i];
947 /* Windows uses 5,5,5 for 16-bit */
948 rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
949 rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
950 rgba[i][BCOMP] = (pixel & 0x001f) << 3;
951 rgba[i][ACOMP] = 255;
952 }
953 }
954
955
956 /* Read an array of color pixels. */
957 static void read_rgba_pixels_16(const GLcontext *ctx,
958 struct gl_renderbuffer *rb,
959 GLuint n, const GLint x[], const GLint y[],
960 GLubyte rgba[][4])
961 {
962 GLuint i, pixel;
963 LPWORD lpw;
964 WMesaContext pwc = wmesa_context(ctx);
965 WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);
966
967 for (i=0; i<n; i++) {
968 GLint y2 = FLIP(y[i]);
969 lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i];
970 pixel = *lpw;
971 /* Windows uses 5,5,5 for 16-bit */
972 rgba[i][RCOMP] = (pixel & 0x7c00) >> 7;
973 rgba[i][GCOMP] = (pixel & 0x03e0) >> 2;
974 rgba[i][BCOMP] = (pixel & 0x001f) << 3;
975 rgba[i][ACOMP] = 255;
976 }
977 }
978
979
980
981
982 /**********************************************************************/
983 /***** BUFFER Functions *****/
984 /**********************************************************************/
985
986
987
988
989 static void
990 wmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
991 {
992 _mesa_free(rb);
993 }
994
995
996 /**
997 * This is called by Mesa whenever it determines that the window size
998 * has changed. Do whatever's needed to cope with that.
999 */
1000 static GLboolean
1001 wmesa_renderbuffer_storage(GLcontext *ctx,
1002 struct gl_renderbuffer *rb,
1003 GLenum internalFormat,
1004 GLuint width,
1005 GLuint height)
1006 {
1007 rb->Width = width;
1008 rb->Height = height;
1009 return GL_TRUE;
1010 }
1011
1012
1013 /**
1014 * Plug in the Get/PutRow/Values functions for a renderbuffer depending
1015 * on if we're drawing to the front or back color buffer.
1016 */
1017 void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat,
1018 int double_buffer)
1019 {
1020 if (double_buffer) {
1021 /* back buffer */
1022 /* Picking the correct span functions is important because
1023 * the DIB was allocated with the indicated depth. */
1024 switch(pixelformat) {
1025 case PF_5R6G5B:
1026 rb->PutRow = write_rgba_span_16;
1027 rb->PutRowRGB = write_rgb_span_16;
1028 rb->PutMonoRow = write_mono_rgba_span_16;
1029 rb->PutValues = write_rgba_pixels_16;
1030 rb->PutMonoValues = write_mono_rgba_pixels_16;
1031 rb->GetRow = read_rgba_span_16;
1032 rb->GetValues = read_rgba_pixels_16;
1033 rb->RedBits = 5;
1034 rb->GreenBits = 6;
1035 rb->BlueBits = 5;
1036 break;
1037 case PF_8R8G8B:
1038 rb->PutRow = write_rgba_span_32;
1039 rb->PutRowRGB = write_rgb_span_32;
1040 rb->PutMonoRow = write_mono_rgba_span_32;
1041 rb->PutValues = write_rgba_pixels_32;
1042 rb->PutMonoValues = write_mono_rgba_pixels_32;
1043 rb->GetRow = read_rgba_span_32;
1044 rb->GetValues = read_rgba_pixels_32;
1045 rb->RedBits = 8;
1046 rb->GreenBits = 8;
1047 rb->BlueBits = 8;
1048 break;
1049 default:
1050 break;
1051 }
1052 }
1053 else {
1054 /* front buffer (actual Windows window) */
1055 rb->PutRow = write_rgba_span_front;
1056 rb->PutRowRGB = write_rgb_span_front;
1057 rb->PutMonoRow = write_mono_rgba_span_front;
1058 rb->PutValues = write_rgba_pixels_front;
1059 rb->PutMonoValues = write_mono_rgba_pixels_front;
1060 rb->GetRow = read_rgba_span_front;
1061 rb->GetValues = read_rgba_pixels_front;
1062 rb->RedBits = 8; /* XXX fix these (565?) */
1063 rb->GreenBits = 8;
1064 rb->BlueBits = 8;
1065 }
1066 }
1067
1068 /**
1069 * Called by ctx->Driver.ResizeBuffers()
1070 * Resize the front/back colorbuffers to match the latest window size.
1071 */
1072 static void
1073 wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer,
1074 GLuint width, GLuint height)
1075 {
1076 WMesaContext pwc = wmesa_context(ctx);
1077 WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);
1078
1079 if (pwfb->Base.Width != width || pwfb->Base.Height != height) {
1080 /* Realloc back buffer */
1081 if (ctx->Visual.doubleBufferMode == 1) {
1082 wmDeleteBackingStore(pwfb);
1083 wmCreateBackingStore(pwfb, width, height);
1084 }
1085 }
1086 _mesa_resize_framebuffer(ctx, buffer, width, height);
1087 }
1088
1089
1090 /**
1091 * Called by glViewport.
1092 * This is a good time for us to poll the current window size and adjust
1093 * our renderbuffers to match the current window size.
1094 * Remember, we have no opportunity to respond to conventional
1095 * resize events since the driver has no event loop.
1096 * Thus, we poll.
1097 * MakeCurrent also ends up making a call here, so that ensures
1098 * we get the viewport set correctly, even if the app does not call
1099 * glViewport and relies on the defaults.
1100 */
1101 static void wmesa_viewport(GLcontext *ctx,
1102 GLint x, GLint y,
1103 GLsizei width, GLsizei height)
1104 {
1105 WMesaContext pwc = wmesa_context(ctx);
1106 GLuint new_width, new_height;
1107
1108 wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height);
1109
1110 /**
1111 * Resize buffers if the window size changed.
1112 */
1113 wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height);
1114 ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */
1115 }
1116
1117
1118
1119
1120 /**
1121 * Called when the driver should update it's state, based on the new_state
1122 * flags.
1123 */
1124 static void wmesa_update_state(GLcontext *ctx, GLuint new_state)
1125 {
1126 _swrast_InvalidateState(ctx, new_state);
1127 _swsetup_InvalidateState(ctx, new_state);
1128 _vbo_InvalidateState(ctx, new_state);
1129 _tnl_InvalidateState(ctx, new_state);
1130
1131 /* TODO - This code is not complete yet because I
1132 * don't know what to do for all state updates.
1133 */
1134
1135 if (new_state & _NEW_BUFFERS) {
1136 }
1137 }
1138
1139
1140
1141
1142
1143 /**********************************************************************/
1144 /***** WMESA Functions *****/
1145 /**********************************************************************/
1146
1147 WMesaContext WMesaCreateContext(HDC hDC,
1148 HPALETTE* Pal,
1149 GLboolean rgb_flag,
1150 GLboolean db_flag,
1151 GLboolean alpha_flag)
1152 {
1153 WMesaContext c;
1154 struct dd_function_table functions;
1155 GLint red_bits, green_bits, blue_bits, alpha_bits;
1156 GLcontext *ctx;
1157 GLvisual *visual;
1158
1159 (void) Pal;
1160
1161 /* Indexed mode not supported */
1162 if (!rgb_flag)
1163 return NULL;
1164
1165 /* Allocate wmesa context */
1166 c = CALLOC_STRUCT(wmesa_context);
1167 if (!c)
1168 return NULL;
1169
1170 #if 0
1171 /* I do not understand this contributed code */
1172 /* Support memory and device contexts */
1173 if(WindowFromDC(hDC) != NULL) {
1174 c->hDC = GetDC(WindowFromDC(hDC)); // huh ????
1175 }
1176 else {
1177 c->hDC = hDC;
1178 }
1179 #else
1180 c->hDC = hDC;
1181 #endif
1182
1183 /* Get data for visual */
1184 /* Dealing with this is actually a bit of overkill because Mesa will end
1185 * up treating all color component size requests less than 8 by using
1186 * a single byte per channel. In addition, the interface to the span
1187 * routines passes colors as an entire byte per channel anyway, so there
1188 * is nothing to be saved by telling the visual to be 16 bits if the device
1189 * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per
1190 * channel anyway.
1191 * But we go through the motions here anyway.
1192 */
1193 switch (GetDeviceCaps(c->hDC, BITSPIXEL)) {
1194 case 16:
1195 red_bits = green_bits = blue_bits = 5;
1196 alpha_bits = 0;
1197 break;
1198 default:
1199 red_bits = green_bits = blue_bits = 8;
1200 alpha_bits = 8;
1201 break;
1202 }
1203 /* Create visual based on flags */
1204 visual = _mesa_create_visual(rgb_flag,
1205 db_flag, /* db_flag */
1206 GL_FALSE, /* stereo */
1207 red_bits, green_bits, blue_bits, /* color RGB */
1208 alpha_flag ? alpha_bits : 0, /* color A */
1209 0, /* index bits */
1210 DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */
1211 8, /* stencil_bits */
1212 16,16,16, /* accum RGB */
1213 alpha_flag ? 16 : 0, /* accum A */
1214 1); /* num samples */
1215
1216 if (!visual) {
1217 _mesa_free(c);
1218 return NULL;
1219 }
1220
1221 /* Set up driver functions */
1222 _mesa_init_driver_functions(&functions);
1223 functions.GetString = wmesa_get_string;
1224 functions.UpdateState = wmesa_update_state;
1225 functions.GetBufferSize = wmesa_get_buffer_size;
1226 functions.Flush = wmesa_flush;
1227 functions.Clear = clear;
1228 functions.ClearIndex = clear_index;
1229 functions.ClearColor = clear_color;
1230 functions.ResizeBuffers = wmesa_resize_buffers;
1231 functions.Viewport = wmesa_viewport;
1232
1233 /* initialize the Mesa context data */
1234 ctx = &c->gl_ctx;
1235 _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c);
1236
1237 _mesa_enable_sw_extensions(ctx);
1238 _mesa_enable_1_3_extensions(ctx);
1239 _mesa_enable_1_4_extensions(ctx);
1240 _mesa_enable_1_5_extensions(ctx);
1241 _mesa_enable_2_0_extensions(ctx);
1242 _mesa_enable_2_1_extensions(ctx);
1243
1244 /* Initialize the software rasterizer and helper modules. */
1245 if (!_swrast_CreateContext(ctx) ||
1246 !_vbo_CreateContext(ctx) ||
1247 !_tnl_CreateContext(ctx) ||
1248 !_swsetup_CreateContext(ctx)) {
1249 _mesa_free_context_data(ctx);
1250 _mesa_free(c);
1251 return NULL;
1252 }
1253 _swsetup_Wakeup(ctx);
1254 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
1255
1256 return c;
1257 }
1258
1259
1260 void WMesaDestroyContext( WMesaContext pwc )
1261 {
1262 GLcontext *ctx = &pwc->gl_ctx;
1263 WMesaFramebuffer pwfb;
1264 GET_CURRENT_CONTEXT(cur_ctx);
1265
1266 if (cur_ctx == ctx) {
1267 /* unbind current if deleting current context */
1268 WMesaMakeCurrent(NULL, NULL);
1269 }
1270
1271 /* clean up frame buffer resources */
1272 pwfb = wmesa_lookup_framebuffer(pwc->hDC);
1273 if (pwfb) {
1274 if (ctx->Visual.doubleBufferMode == 1)
1275 wmDeleteBackingStore(pwfb);
1276 wmesa_free_framebuffer(pwc->hDC);
1277 }
1278
1279 /* Release for device, not memory contexts */
1280 if (WindowFromDC(pwc->hDC) != NULL)
1281 {
1282 ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC);
1283 }
1284 DeleteObject(pwc->clearPen);
1285 DeleteObject(pwc->clearBrush);
1286
1287 _swsetup_DestroyContext(ctx);
1288 _tnl_DestroyContext(ctx);
1289 _vbo_DestroyContext(ctx);
1290 _swrast_DestroyContext(ctx);
1291
1292 _mesa_free_context_data(ctx);
1293 _mesa_free(pwc);
1294 }
1295
1296
1297 /**
1298 * Create a new color renderbuffer.
1299 */
1300 struct gl_renderbuffer *
1301 wmesa_new_renderbuffer(void)
1302 {
1303 struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
1304 if (!rb)
1305 return NULL;
1306
1307 _mesa_init_renderbuffer(rb, (GLuint)0);
1308
1309 rb->_BaseFormat = GL_RGBA;
1310 rb->InternalFormat = GL_RGBA;
1311 rb->DataType = CHAN_TYPE;
1312 rb->Delete = wmesa_delete_renderbuffer;
1313 rb->AllocStorage = wmesa_renderbuffer_storage;
1314 return rb;
1315 }
1316
1317
1318 void WMesaMakeCurrent(WMesaContext c, HDC hdc)
1319 {
1320 WMesaFramebuffer pwfb;
1321
1322 {
1323 /* return if already current */
1324 GET_CURRENT_CONTEXT(ctx);
1325 WMesaContext pwc = wmesa_context(ctx);
1326 if (pwc && c == pwc && pwc->hDC == hdc)
1327 return;
1328 }
1329
1330 pwfb = wmesa_lookup_framebuffer(hdc);
1331
1332 /* Lazy creation of framebuffers */
1333 if (c && !pwfb && hdc) {
1334 struct gl_renderbuffer *rb;
1335 GLvisual *visual = &c->gl_ctx.Visual;
1336 GLuint width, height;
1337
1338 get_window_size(hdc, &width, &height);
1339
1340 c->clearPen = CreatePen(PS_SOLID, 1, 0);
1341 c->clearBrush = CreateSolidBrush(0);
1342
1343 pwfb = wmesa_new_framebuffer(hdc, visual);
1344
1345 /* Create back buffer if double buffered */
1346 if (visual->doubleBufferMode == 1) {
1347 wmCreateBackingStore(pwfb, width, height);
1348 }
1349
1350 /* make render buffers */
1351 if (visual->doubleBufferMode == 1) {
1352 rb = wmesa_new_renderbuffer();
1353 _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb);
1354 wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 1);
1355 }
1356 rb = wmesa_new_renderbuffer();
1357 _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb);
1358 wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, 0);
1359
1360 /* Let Mesa own the Depth, Stencil, and Accum buffers */
1361 _mesa_add_soft_renderbuffers(&pwfb->Base,
1362 GL_FALSE, /* color */
1363 visual->depthBits > 0,
1364 visual->stencilBits > 0,
1365 visual->accumRedBits > 0,
1366 visual->alphaBits >0,
1367 GL_FALSE);
1368 }
1369
1370 if (c && pwfb)
1371 _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base);
1372 else
1373 _mesa_make_current(NULL, NULL, NULL);
1374 }
1375
1376
1377 void WMesaSwapBuffers( HDC hdc )
1378 {
1379 GET_CURRENT_CONTEXT(ctx);
1380 WMesaContext pwc = wmesa_context(ctx);
1381 WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc);
1382
1383 if (!pwfb) {
1384 _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc");
1385 return;
1386 }
1387
1388 /* If we're swapping the buffer associated with the current context
1389 * we have to flush any pending rendering commands first.
1390 */
1391 if (pwc->hDC == hdc) {
1392 _mesa_notifySwapBuffers(ctx);
1393
1394 BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,
1395 pwfb->dib_hDC, 0, 0, SRCCOPY);
1396 }
1397 else {
1398 /* XXX for now only allow swapping current window */
1399 _mesa_problem(NULL, "wmesa: can't swap non-current window");
1400 }
1401 }
1402
1403 /* This is hopefully a temporary hack to define some needed dispatch
1404 * table entries. Hopefully, I'll find a better solution. The
1405 * dispatch table generation scripts ought to be making these dummy
1406 * stubs as well. */
1407 void gl_dispatch_stub_543(void){}
1408 void gl_dispatch_stub_544(void){}
1409 void gl_dispatch_stub_545(void){}
1410 void gl_dispatch_stub_546(void){}
1411 void gl_dispatch_stub_547(void){}
1412 void gl_dispatch_stub_548(void){}
1413 void gl_dispatch_stub_549(void){}
1414 void gl_dispatch_stub_550(void){}
1415 void gl_dispatch_stub_551(void){}
1416 void gl_dispatch_stub_552(void){}
1417 void gl_dispatch_stub_553(void){}
1418 void gl_dispatch_stub_554(void){}
1419 void gl_dispatch_stub_555(void){}
1420 void gl_dispatch_stub_556(void){}
1421 void gl_dispatch_stub_557(void){}
1422 void gl_dispatch_stub_558(void){}
1423 void gl_dispatch_stub_559(void){}
1424 void gl_dispatch_stub_560(void){}
1425 void gl_dispatch_stub_561(void){}
1426 void gl_dispatch_stub_565(void){}
1427 void gl_dispatch_stub_566(void){}
1428 void gl_dispatch_stub_577(void){}
1429 void gl_dispatch_stub_578(void){}
1430 void gl_dispatch_stub_603(void){}
1431 void gl_dispatch_stub_645(void){}
1432 void gl_dispatch_stub_646(void){}
1433 void gl_dispatch_stub_647(void){}
1434 void gl_dispatch_stub_648(void){}
1435 void gl_dispatch_stub_649(void){}
1436 void gl_dispatch_stub_650(void){}
1437 void gl_dispatch_stub_651(void){}
1438 void gl_dispatch_stub_652(void){}
1439 void gl_dispatch_stub_653(void){}
1440 void gl_dispatch_stub_734(void){}
1441 void gl_dispatch_stub_735(void){}
1442 void gl_dispatch_stub_736(void){}
1443 void gl_dispatch_stub_737(void){}
1444 void gl_dispatch_stub_738(void){}
1445 void gl_dispatch_stub_745(void){}
1446 void gl_dispatch_stub_746(void){}
1447 void gl_dispatch_stub_760(void){}
1448 void gl_dispatch_stub_761(void){}
1449 void gl_dispatch_stub_766(void){}
1450 void gl_dispatch_stub_767(void){}
1451 void gl_dispatch_stub_768(void){}
1452
1453 void gl_dispatch_stub_562(void){}
1454 void gl_dispatch_stub_563(void){}
1455 void gl_dispatch_stub_564(void){}
1456 void gl_dispatch_stub_567(void){}
1457 void gl_dispatch_stub_568(void){}
1458 void gl_dispatch_stub_569(void){}
1459 void gl_dispatch_stub_580(void){}
1460 void gl_dispatch_stub_581(void){}
1461 void gl_dispatch_stub_606(void){}
1462 void gl_dispatch_stub_654(void){}
1463 void gl_dispatch_stub_655(void){}
1464 void gl_dispatch_stub_656(void){}
1465 void gl_dispatch_stub_739(void){}
1466 void gl_dispatch_stub_740(void){}
1467 void gl_dispatch_stub_741(void){}
1468 void gl_dispatch_stub_748(void){}
1469 void gl_dispatch_stub_749(void){}
1470 void gl_dispatch_stub_769(void){}
1471 void gl_dispatch_stub_770(void){}
1472 void gl_dispatch_stub_771(void){}
1473