2 * Windows (Win32/Win64) device driver for Mesa
11 #include "extensions.h"
12 #include "framebuffer.h"
13 #include "renderbuffer.h"
14 #include "drivers/common/driverfuncs.h"
16 #include "swrast/swrast.h"
17 #include "swrast_setup/swrast_setup.h"
19 #include "tnl/t_context.h"
20 #include "tnl/t_pipeline.h"
23 /* linked list of our Framebuffers (windows) */
24 static WMesaFramebuffer FirstFramebuffer
= NULL
;
28 * Create a new WMesaFramebuffer object which will correspond to the
29 * given HDC (Window handle).
32 wmesa_new_framebuffer(HDC hdc
, GLvisual
*visual
)
35 = (WMesaFramebuffer
) malloc(sizeof(struct wmesa_framebuffer
));
37 _mesa_initialize_framebuffer(&pwfb
->Base
, visual
);
39 /* insert at head of list */
40 pwfb
->next
= FirstFramebuffer
;
41 FirstFramebuffer
= pwfb
;
47 * Given an hdc, free the corresponding WMesaFramebuffer
50 wmesa_free_framebuffer(HDC hdc
)
52 WMesaFramebuffer pwfb
, prev
;
53 for (pwfb
= FirstFramebuffer
; pwfb
; pwfb
= pwfb
->next
) {
59 struct gl_framebuffer
*fb
;
60 if (pwfb
== FirstFramebuffer
)
61 FirstFramebuffer
= pwfb
->next
;
63 prev
->next
= pwfb
->next
;
65 _mesa_reference_framebuffer(&fb
, NULL
);
70 * Given an hdc, return the corresponding WMesaFramebuffer
73 wmesa_lookup_framebuffer(HDC hdc
)
75 WMesaFramebuffer pwfb
;
76 for (pwfb
= FirstFramebuffer
; pwfb
; pwfb
= pwfb
->next
) {
85 * Given a GLframebuffer, return the corresponding WMesaFramebuffer.
87 static WMesaFramebuffer
wmesa_framebuffer(GLframebuffer
*fb
)
89 return (WMesaFramebuffer
) fb
;
94 * Given a GLcontext, return the corresponding WMesaContext.
96 static WMesaContext
wmesa_context(const GLcontext
*ctx
)
98 return (WMesaContext
) ctx
;
103 * Every driver should implement a GetString function in order to
104 * return a meaningful GL_RENDERER string.
106 static const GLubyte
*wmesa_get_string(GLcontext
*ctx
, GLenum name
)
108 return (name
== GL_RENDERER
) ?
109 (GLubyte
*) "Mesa Windows GDI Driver" : NULL
;
114 * Determine the pixel format based on the pixel size.
116 static void wmSetPixelFormat(WMesaFramebuffer pwfb
, HDC hDC
)
118 pwfb
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
120 /* Only 16 and 32 bit targets are supported now */
121 assert(pwfb
->cColorBits
== 0 ||
122 pwfb
->cColorBits
== 16 ||
123 pwfb
->cColorBits
== 24 ||
124 pwfb
->cColorBits
== 32);
126 switch(pwfb
->cColorBits
){
128 pwfb
->pixelformat
= PF_INDEX8
;
131 pwfb
->pixelformat
= PF_5R6G5B
;
135 pwfb
->pixelformat
= PF_8R8G8B
;
138 pwfb
->pixelformat
= PF_BADFORMAT
;
144 * Create DIB for back buffer.
145 * We write into this memory with the span routines and then blit it
146 * to the window on a buffer swap.
148 BOOL
wmCreateBackingStore(WMesaFramebuffer pwfb
, long lxSize
, long lySize
)
151 LPBITMAPINFO pbmi
= &(pwfb
->bmi
);
154 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
155 pbmi
->bmiHeader
.biWidth
= lxSize
;
156 pbmi
->bmiHeader
.biHeight
= -lySize
;
157 pbmi
->bmiHeader
.biPlanes
= 1;
158 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwfb
->hDC
, BITSPIXEL
);
159 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
160 pbmi
->bmiHeader
.biSizeImage
= 0;
161 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
162 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
163 pbmi
->bmiHeader
.biClrUsed
= 0;
164 pbmi
->bmiHeader
.biClrImportant
= 0;
166 pwfb
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
167 pwfb
->ScanWidth
= (lxSize
* (pwfb
->cColorBits
/ 8) + 3) & ~3;
169 hic
= CreateIC("display", NULL
, NULL
, NULL
);
170 pwfb
->dib_hDC
= CreateCompatibleDC(hic
);
172 pwfb
->hbmDIB
= CreateDIBSection(hic
,
175 (void **)&(pwfb
->pbPixels
),
178 pwfb
->hOldBitmap
= SelectObject(pwfb
->dib_hDC
, pwfb
->hbmDIB
);
182 wmSetPixelFormat(pwfb
, pwfb
->hDC
);
187 static wmDeleteBackingStore(WMesaFramebuffer pwfb
)
190 SelectObject(pwfb
->dib_hDC
, pwfb
->hOldBitmap
);
191 DeleteDC(pwfb
->dib_hDC
);
192 DeleteObject(pwfb
->hbmDIB
);
198 * Find the width and height of the window named by hdc.
201 get_window_size(HDC hdc
, GLuint
*width
, GLuint
*height
)
203 if (WindowFromDC(hdc
)) {
205 GetClientRect(WindowFromDC(hdc
), &rect
);
206 *width
= rect
.right
- rect
.left
;
207 *height
= rect
.bottom
- rect
.top
;
209 else { /* Memory context */
210 /* From contributed code - use the size of the desktop
211 * for the size of a memory context (?) */
212 *width
= GetDeviceCaps(hdc
, HORZRES
);
213 *height
= GetDeviceCaps(hdc
, VERTRES
);
219 wmesa_get_buffer_size(GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
221 WMesaFramebuffer pwfb
= wmesa_framebuffer(buffer
);
222 get_window_size(pwfb
->hDC
, width
, height
);
226 static void wmesa_flush(GLcontext
*ctx
)
228 WMesaContext pwc
= wmesa_context(ctx
);
229 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->WinSysDrawBuffer
);
231 if (ctx
->Visual
.doubleBufferMode
== 1) {
232 BitBlt(pwfb
->hDC
, 0, 0, pwfb
->Base
.Width
, pwfb
->Base
.Height
,
233 pwfb
->dib_hDC
, 0, 0, SRCCOPY
);
236 /* Do nothing for single buffer */
241 /**********************************************************************/
242 /***** CLEAR Functions *****/
243 /**********************************************************************/
245 /* If we do not implement these, Mesa clears the buffers via the pixel
246 * span writing interface, which is very slow for a clear operation.
250 * Set the color index used to clear the color buffer.
252 static void clear_index(GLcontext
*ctx
, GLuint index
)
254 WMesaContext pwc
= wmesa_context(ctx
);
255 /* Note that indexed mode is not supported yet */
256 pwc
->clearColorRef
= RGB(0,0,0);
260 * Set the color used to clear the color buffer.
262 static void clear_color(GLcontext
*ctx
, const GLfloat color
[4])
264 WMesaContext pwc
= wmesa_context(ctx
);
265 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
267 UINT bytesPerPixel
= pwfb
->cColorBits
/ 8;
269 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
270 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
271 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
272 pwc
->clearColorRef
= RGB(col
[0], col
[1], col
[2]);
273 DeleteObject(pwc
->clearPen
);
274 DeleteObject(pwc
->clearBrush
);
275 pwc
->clearPen
= CreatePen(PS_SOLID
, 1, pwc
->clearColorRef
);
276 pwc
->clearBrush
= CreateSolidBrush(pwc
->clearColorRef
);
281 * Clear the specified region of the color buffer using the clear color
282 * or index as specified by one of the two functions above.
284 * This procedure clears either the front and/or the back COLOR buffers.
285 * Only the "left" buffer is cleared since we are not stereo.
286 * Clearing of the other non-color buffers is left to the swrast.
289 static void clear(GLcontext
*ctx
, GLbitfield mask
)
291 #define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1)
292 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
293 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
294 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
295 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
297 WMesaContext pwc
= wmesa_context(ctx
);
298 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
301 /* Let swrast do all the work if the masks are not set to
302 * clear all channels. */
303 if (ctx
->Color
.ColorMask
[0] != 0xff ||
304 ctx
->Color
.ColorMask
[1] != 0xff ||
305 ctx
->Color
.ColorMask
[2] != 0xff ||
306 ctx
->Color
.ColorMask
[3] != 0xff) {
307 _swrast_Clear(ctx
, mask
);
312 if (mask
& BUFFER_BIT_BACK_LEFT
) {
315 UINT bytesPerPixel
= pwfb
->cColorBits
/ 8;
316 LPBYTE lpb
, clearRow
;
324 /* Try for a fast clear - clearing entire buffer with a single
326 if (width
== ctx
->DrawBuffer
->Width
&&
327 height
== ctx
->DrawBuffer
->Height
) { /* entire buffer */
328 /* Now check for an easy clear value */
329 switch (bytesPerPixel
) {
331 bColor
= BGR8(GetRValue(pwc
->clearColorRef
),
332 GetGValue(pwc
->clearColorRef
),
333 GetBValue(pwc
->clearColorRef
));
334 memset(pwfb
->pbPixels
, bColor
,
335 pwfb
->ScanWidth
* height
);
339 wColor
= BGR16(GetRValue(pwc
->clearColorRef
),
340 GetGValue(pwc
->clearColorRef
),
341 GetBValue(pwc
->clearColorRef
));
342 if (((wColor
>> 8) & 0xff) == (wColor
& 0xff)) {
343 memset(pwfb
->pbPixels
, wColor
& 0xff,
344 pwfb
->ScanWidth
* height
);
351 if (GetRValue(pwc
->clearColorRef
) ==
352 GetGValue(pwc
->clearColorRef
) &&
353 GetRValue(pwc
->clearColorRef
) ==
354 GetBValue(pwc
->clearColorRef
)) {
355 memset(pwfb
->pbPixels
,
356 GetRValue(pwc
->clearColorRef
),
357 pwfb
->ScanWidth
* height
);
367 /* Need to clear a row at a time. Begin by setting the first
368 * row in the area to be cleared to the clear color. */
370 clearRow
= pwfb
->pbPixels
+
371 pwfb
->ScanWidth
* FLIP(y
) +
373 switch (bytesPerPixel
) {
376 bColor
= BGR8(GetRValue(pwc
->clearColorRef
),
377 GetGValue(pwc
->clearColorRef
),
378 GetBValue(pwc
->clearColorRef
));
379 memset(lpb
, bColor
, width
);
382 lpw
= (LPWORD
)clearRow
;
383 wColor
= BGR16(GetRValue(pwc
->clearColorRef
),
384 GetGValue(pwc
->clearColorRef
),
385 GetBValue(pwc
->clearColorRef
));
386 for (i
=0; i
<width
; i
++)
391 r
= GetRValue(pwc
->clearColorRef
);
392 g
= GetGValue(pwc
->clearColorRef
);
393 b
= GetBValue(pwc
->clearColorRef
);
394 for (i
=0; i
<width
; i
++) {
401 lpdw
= (LPDWORD
)clearRow
;
402 dwColor
= BGR32(GetRValue(pwc
->clearColorRef
),
403 GetGValue(pwc
->clearColorRef
),
404 GetBValue(pwc
->clearColorRef
));
405 for (i
=0; i
<width
; i
++)
412 /* copy cleared row to other rows in buffer */
413 lpb
= clearRow
- pwfb
->ScanWidth
;
414 rowSize
= width
* bytesPerPixel
;
415 for (i
=1; i
<height
; i
++) {
416 memcpy(lpb
, clearRow
, rowSize
);
417 lpb
-= pwfb
->ScanWidth
;
420 mask
&= ~BUFFER_BIT_BACK_LEFT
;
424 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
426 HPEN Old_Pen
= SelectObject(DC
, pwc
->clearPen
);
427 HBRUSH Old_Brush
= SelectObject(DC
, pwc
->clearBrush
);
432 FLIP(y
) - height
+ 1);
433 SelectObject(DC
, Old_Pen
);
434 SelectObject(DC
, Old_Brush
);
435 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
438 /* Call swrast if there is anything left to clear (like DEPTH) */
440 _swrast_Clear(ctx
, mask
);
446 /**********************************************************************/
447 /***** PIXEL Functions *****/
448 /**********************************************************************/
450 #define FLIP(Y) (rb->Height - (Y) - 1)
454 ** Front Buffer reading/writing
455 ** These are slow, but work with all non-indexed visual types.
458 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
459 static void write_rgba_span_front(const GLcontext
*ctx
,
460 struct gl_renderbuffer
*rb
,
461 GLuint n
, GLint x
, GLint y
,
462 const GLubyte rgba
[][4],
463 const GLubyte mask
[] )
465 WMesaContext pwc
= wmesa_context(ctx
);
466 WMesaFramebuffer pwfb
= wmesa_lookup_framebuffer(pwc
->hDC
);
467 CONST BITMAPINFO bmi
=
470 sizeof(BITMAPINFOHEADER
),
471 n
, 1, 1, 32, BI_RGB
, 0, 1, 1, 0, 0
480 unsigned b
:8, g
:8, r
:8, a
:8;
486 if (n
< 16) { // the value 16 is just guessed
491 SetPixel(pwc
->hDC
, x
+i
, y
,
492 RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
496 SetPixel(pwc
->hDC
, x
+i
, y
,
497 RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
502 _mesa_problem(NULL
, "wmesa: write_rgba_span_front on unknown hdc");
505 bgra
=malloc(n
*sizeof(BGRA
));
507 _mesa_problem(NULL
, "wmesa: write_rgba_span_front: out of memory");
512 for (i
=0; i
<n
; i
++) {
525 for (i
=0; i
<n
; i
++) {
533 bmp
=CreateBitmap(n
, 1, 1, 32, bgra
);
534 mdc
=CreateCompatibleDC(pwfb
->hDC
);
535 SelectObject(mdc
, bmp
);
537 BitBlt(pwfb
->hDC
, x
, y
, n
, 1, mdc
, 0, 0, SRCCOPY
);
538 SelectObject(mdc
, 0);
545 /* Write a horizontal span of RGB color pixels with a boolean mask. */
546 static void write_rgb_span_front(const GLcontext
*ctx
,
547 struct gl_renderbuffer
*rb
,
548 GLuint n
, GLint x
, GLint y
,
549 const GLubyte rgb
[][3],
550 const GLubyte mask
[] )
552 WMesaContext pwc
= wmesa_context(ctx
);
560 SetPixel(pwc
->hDC
, x
+i
, y
, RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
565 SetPixel(pwc
->hDC
, x
+i
, y
, RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
572 * Write a horizontal span of pixels with a boolean mask. The current color
573 * is used for all pixels.
575 static void write_mono_rgba_span_front(const GLcontext
*ctx
,
576 struct gl_renderbuffer
*rb
,
577 GLuint n
, GLint x
, GLint y
,
578 const GLchan color
[4],
579 const GLubyte mask
[])
582 WMesaContext pwc
= wmesa_context(ctx
);
586 colorref
= RGB(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
591 SetPixel(pwc
->hDC
, x
+i
, y
, colorref
);
595 SetPixel(pwc
->hDC
, x
+i
, y
, colorref
);
599 /* Write an array of RGBA pixels with a boolean mask. */
600 static void write_rgba_pixels_front(const GLcontext
*ctx
,
601 struct gl_renderbuffer
*rb
,
603 const GLint x
[], const GLint y
[],
604 const GLubyte rgba
[][4],
605 const GLubyte mask
[] )
608 WMesaContext pwc
= wmesa_context(ctx
);
612 SetPixel(pwc
->hDC
, x
[i
], FLIP(y
[i
]),
613 RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
620 * Write an array of pixels with a boolean mask. The current color
621 * is used for all pixels.
623 static void write_mono_rgba_pixels_front(const GLcontext
*ctx
,
624 struct gl_renderbuffer
*rb
,
626 const GLint x
[], const GLint y
[],
627 const GLchan color
[4],
628 const GLubyte mask
[] )
631 WMesaContext pwc
= wmesa_context(ctx
);
634 colorref
= RGB(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
637 SetPixel(pwc
->hDC
, x
[i
], FLIP(y
[i
]), colorref
);
640 /* Read a horizontal span of color pixels. */
641 static void read_rgba_span_front(const GLcontext
*ctx
,
642 struct gl_renderbuffer
*rb
,
643 GLuint n
, GLint x
, GLint y
,
646 WMesaContext pwc
= wmesa_context(ctx
);
650 for (i
=0; i
<n
; i
++) {
651 Color
= GetPixel(pwc
->hDC
, x
+i
, y
);
652 rgba
[i
][RCOMP
] = GetRValue(Color
);
653 rgba
[i
][GCOMP
] = GetGValue(Color
);
654 rgba
[i
][BCOMP
] = GetBValue(Color
);
655 rgba
[i
][ACOMP
] = 255;
660 /* Read an array of color pixels. */
661 static void read_rgba_pixels_front(const GLcontext
*ctx
,
662 struct gl_renderbuffer
*rb
,
663 GLuint n
, const GLint x
[], const GLint y
[],
666 WMesaContext pwc
= wmesa_context(ctx
);
669 for (i
=0; i
<n
; i
++) {
670 GLint y2
= FLIP(y
[i
]);
671 Color
= GetPixel(pwc
->hDC
, x
[i
], y2
);
672 rgba
[i
][RCOMP
] = GetRValue(Color
);
673 rgba
[i
][GCOMP
] = GetGValue(Color
);
674 rgba
[i
][BCOMP
] = GetBValue(Color
);
675 rgba
[i
][ACOMP
] = 255;
679 /*********************************************************************/
681 /* DOUBLE BUFFER 32-bit */
683 #define WMSETPIXEL32(pwc, y, x, r, g, b) { \
684 LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
685 *lpdw = BGR32((r),(g),(b)); }
689 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
690 static void write_rgba_span_32(const GLcontext
*ctx
,
691 struct gl_renderbuffer
*rb
,
692 GLuint n
, GLint x
, GLint y
,
693 const GLubyte rgba
[][4],
694 const GLubyte mask
[] )
696 WMesaContext pwc
= wmesa_context(ctx
);
697 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
704 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
708 lpdw
[i
] = BGR32(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
713 *lpdw
++ = BGR32(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
719 /* Write a horizontal span of RGB color pixels with a boolean mask. */
720 static void write_rgb_span_32(const GLcontext
*ctx
,
721 struct gl_renderbuffer
*rb
,
722 GLuint n
, GLint x
, GLint y
,
723 const GLubyte rgb
[][3],
724 const GLubyte mask
[] )
726 WMesaContext pwc
= wmesa_context(ctx
);
727 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
734 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
738 lpdw
[i
] = BGR32(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
743 *lpdw
++ = BGR32(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
749 * Write a horizontal span of pixels with a boolean mask. The current color
750 * is used for all pixels.
752 static void write_mono_rgba_span_32(const GLcontext
*ctx
,
753 struct gl_renderbuffer
*rb
,
754 GLuint n
, GLint x
, GLint y
,
755 const GLchan color
[4],
756 const GLubyte mask
[])
761 WMesaContext pwc
= wmesa_context(ctx
);
762 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
763 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
765 pixel
= BGR32(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
777 /* Write an array of RGBA pixels with a boolean mask. */
778 static void write_rgba_pixels_32(const GLcontext
*ctx
,
779 struct gl_renderbuffer
*rb
,
780 GLuint n
, const GLint x
[], const GLint y
[],
781 const GLubyte rgba
[][4],
782 const GLubyte mask
[])
785 WMesaContext pwc
= wmesa_context(ctx
);
786 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
789 WMSETPIXEL32(pwfb
, FLIP(y
[i
]), x
[i
],
790 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
794 * Write an array of pixels with a boolean mask. The current color
795 * is used for all pixels.
797 static void write_mono_rgba_pixels_32(const GLcontext
*ctx
,
798 struct gl_renderbuffer
*rb
,
800 const GLint x
[], const GLint y
[],
801 const GLchan color
[4],
802 const GLubyte mask
[])
805 WMesaContext pwc
= wmesa_context(ctx
);
806 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
809 WMSETPIXEL32(pwfb
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
810 color
[GCOMP
], color
[BCOMP
]);
813 /* Read a horizontal span of color pixels. */
814 static void read_rgba_span_32(const GLcontext
*ctx
,
815 struct gl_renderbuffer
*rb
,
816 GLuint n
, GLint x
, GLint y
,
822 WMesaContext pwc
= wmesa_context(ctx
);
823 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
826 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
827 for (i
=0; i
<n
; i
++) {
829 rgba
[i
][RCOMP
] = (pixel
& 0x00ff0000) >> 16;
830 rgba
[i
][GCOMP
] = (pixel
& 0x0000ff00) >> 8;
831 rgba
[i
][BCOMP
] = (pixel
& 0x000000ff);
832 rgba
[i
][ACOMP
] = 255;
837 /* Read an array of color pixels. */
838 static void read_rgba_pixels_32(const GLcontext
*ctx
,
839 struct gl_renderbuffer
*rb
,
840 GLuint n
, const GLint x
[], const GLint y
[],
846 WMesaContext pwc
= wmesa_context(ctx
);
847 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
849 for (i
=0; i
<n
; i
++) {
850 GLint y2
= FLIP(y
[i
]);
851 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y2
)) + x
[i
];
853 rgba
[i
][RCOMP
] = (pixel
& 0x00ff0000) >> 16;
854 rgba
[i
][GCOMP
] = (pixel
& 0x0000ff00) >> 8;
855 rgba
[i
][BCOMP
] = (pixel
& 0x000000ff);
856 rgba
[i
][ACOMP
] = 255;
861 /*********************************************************************/
863 /* DOUBLE BUFFER 24-bit */
865 #define WMSETPIXEL24(pwc, y, x, r, g, b) { \
866 LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \
871 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
872 static void write_rgba_span_24(const GLcontext
*ctx
,
873 struct gl_renderbuffer
*rb
,
874 GLuint n
, GLint x
, GLint y
,
875 const GLubyte rgba
[][4],
876 const GLubyte mask
[] )
878 WMesaContext pwc
= wmesa_context(ctx
);
879 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
886 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
890 lpb
[3*i
] = rgba
[i
][BCOMP
];
891 lpb
[3*i
+1] = rgba
[i
][GCOMP
];
892 lpb
[3*i
+2] = rgba
[i
][RCOMP
];
896 for (i
=0; i
<n
; i
++) {
897 *lpb
++ = rgba
[i
][BCOMP
];
898 *lpb
++ = rgba
[i
][GCOMP
];
899 *lpb
++ = rgba
[i
][RCOMP
];
905 /* Write a horizontal span of RGB color pixels with a boolean mask. */
906 static void write_rgb_span_24(const GLcontext
*ctx
,
907 struct gl_renderbuffer
*rb
,
908 GLuint n
, GLint x
, GLint y
,
909 const GLubyte rgb
[][3],
910 const GLubyte mask
[] )
912 WMesaContext pwc
= wmesa_context(ctx
);
913 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
920 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
924 lpb
[3*i
] = rgb
[i
][BCOMP
];
925 lpb
[3*i
+1] = rgb
[i
][GCOMP
];
926 lpb
[3*i
+2] = rgb
[i
][RCOMP
];
930 for (i
=0; i
<n
; i
++) {
931 *lpb
++ = rgb
[i
][BCOMP
];
932 *lpb
++ = rgb
[i
][GCOMP
];
933 *lpb
++ = rgb
[i
][RCOMP
];
939 * Write a horizontal span of pixels with a boolean mask. The current color
940 * is used for all pixels.
942 static void write_mono_rgba_span_24(const GLcontext
*ctx
,
943 struct gl_renderbuffer
*rb
,
944 GLuint n
, GLint x
, GLint y
,
945 const GLchan color
[4],
946 const GLubyte mask
[])
950 WMesaContext pwc
= wmesa_context(ctx
);
951 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
952 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
957 lpb
[3*i
] = color
[BCOMP
];
958 lpb
[3*i
+1] = color
[GCOMP
];
959 lpb
[3*i
+2] = color
[RCOMP
];
963 for (i
=0; i
<n
; i
++) {
964 *lpb
++ = color
[BCOMP
];
965 *lpb
++ = color
[GCOMP
];
966 *lpb
++ = color
[RCOMP
];
970 /* Write an array of RGBA pixels with a boolean mask. */
971 static void write_rgba_pixels_24(const GLcontext
*ctx
,
972 struct gl_renderbuffer
*rb
,
973 GLuint n
, const GLint x
[], const GLint y
[],
974 const GLubyte rgba
[][4],
975 const GLubyte mask
[])
978 WMesaContext pwc
= wmesa_context(ctx
);
979 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
982 WMSETPIXEL24(pwfb
, FLIP(y
[i
]), x
[i
],
983 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
987 * Write an array of pixels with a boolean mask. The current color
988 * is used for all pixels.
990 static void write_mono_rgba_pixels_24(const GLcontext
*ctx
,
991 struct gl_renderbuffer
*rb
,
993 const GLint x
[], const GLint y
[],
994 const GLchan color
[4],
995 const GLubyte mask
[])
998 WMesaContext pwc
= wmesa_context(ctx
);
999 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1002 WMSETPIXEL24(pwfb
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
1003 color
[GCOMP
], color
[BCOMP
]);
1006 /* Read a horizontal span of color pixels. */
1007 static void read_rgba_span_24(const GLcontext
*ctx
,
1008 struct gl_renderbuffer
*rb
,
1009 GLuint n
, GLint x
, GLint y
,
1014 WMesaContext pwc
= wmesa_context(ctx
);
1015 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1018 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
1019 for (i
=0; i
<n
; i
++) {
1020 rgba
[i
][RCOMP
] = lpb
[3*i
+2];
1021 rgba
[i
][GCOMP
] = lpb
[3*i
+1];
1022 rgba
[i
][BCOMP
] = lpb
[3*i
];
1023 rgba
[i
][ACOMP
] = 255;
1028 /* Read an array of color pixels. */
1029 static void read_rgba_pixels_24(const GLcontext
*ctx
,
1030 struct gl_renderbuffer
*rb
,
1031 GLuint n
, const GLint x
[], const GLint y
[],
1036 WMesaContext pwc
= wmesa_context(ctx
);
1037 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1039 for (i
=0; i
<n
; i
++) {
1040 GLint y2
= FLIP(y
[i
]);
1041 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y2
)) + (3 * x
[i
]);
1042 rgba
[i
][RCOMP
] = lpb
[3*i
+2];
1043 rgba
[i
][GCOMP
] = lpb
[3*i
+1];
1044 rgba
[i
][BCOMP
] = lpb
[3*i
];
1045 rgba
[i
][ACOMP
] = 255;
1050 /*********************************************************************/
1052 /* DOUBLE BUFFER 16-bit */
1054 #define WMSETPIXEL16(pwc, y, x, r, g, b) { \
1055 LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
1056 *lpw = BGR16((r),(g),(b)); }
1060 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
1061 static void write_rgba_span_16(const GLcontext
*ctx
,
1062 struct gl_renderbuffer
*rb
,
1063 GLuint n
, GLint x
, GLint y
,
1064 const GLubyte rgba
[][4],
1065 const GLubyte mask
[] )
1067 WMesaContext pwc
= wmesa_context(ctx
);
1068 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1075 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1079 lpw
[i
] = BGR16(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
1084 *lpw
++ = BGR16(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
1090 /* Write a horizontal span of RGB color pixels with a boolean mask. */
1091 static void write_rgb_span_16(const GLcontext
*ctx
,
1092 struct gl_renderbuffer
*rb
,
1093 GLuint n
, GLint x
, GLint y
,
1094 const GLubyte rgb
[][3],
1095 const GLubyte mask
[] )
1097 WMesaContext pwc
= wmesa_context(ctx
);
1098 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1105 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1109 lpw
[i
] = BGR16(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
1114 *lpw
++ = BGR16(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
1120 * Write a horizontal span of pixels with a boolean mask. The current color
1121 * is used for all pixels.
1123 static void write_mono_rgba_span_16(const GLcontext
*ctx
,
1124 struct gl_renderbuffer
*rb
,
1125 GLuint n
, GLint x
, GLint y
,
1126 const GLchan color
[4],
1127 const GLubyte mask
[])
1132 WMesaContext pwc
= wmesa_context(ctx
);
1133 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1135 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1137 pixel
= BGR16(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
1149 /* Write an array of RGBA pixels with a boolean mask. */
1150 static void write_rgba_pixels_16(const GLcontext
*ctx
,
1151 struct gl_renderbuffer
*rb
,
1152 GLuint n
, const GLint x
[], const GLint y
[],
1153 const GLubyte rgba
[][4],
1154 const GLubyte mask
[])
1157 WMesaContext pwc
= wmesa_context(ctx
);
1158 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1162 WMSETPIXEL16(pwfb
, FLIP(y
[i
]), x
[i
],
1163 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1167 * Write an array of pixels with a boolean mask. The current color
1168 * is used for all pixels.
1170 static void write_mono_rgba_pixels_16(const GLcontext
*ctx
,
1171 struct gl_renderbuffer
*rb
,
1173 const GLint x
[], const GLint y
[],
1174 const GLchan color
[4],
1175 const GLubyte mask
[])
1178 WMesaContext pwc
= wmesa_context(ctx
);
1179 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1183 WMSETPIXEL16(pwfb
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
1184 color
[GCOMP
], color
[BCOMP
]);
1187 /* Read a horizontal span of color pixels. */
1188 static void read_rgba_span_16(const GLcontext
*ctx
,
1189 struct gl_renderbuffer
*rb
,
1190 GLuint n
, GLint x
, GLint y
,
1195 WMesaContext pwc
= wmesa_context(ctx
);
1196 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1199 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1200 for (i
=0; i
<n
; i
++) {
1202 /* Windows uses 5,5,5 for 16-bit */
1203 rgba
[i
][RCOMP
] = (pixel
& 0x7c00) >> 7;
1204 rgba
[i
][GCOMP
] = (pixel
& 0x03e0) >> 2;
1205 rgba
[i
][BCOMP
] = (pixel
& 0x001f) << 3;
1206 rgba
[i
][ACOMP
] = 255;
1211 /* Read an array of color pixels. */
1212 static void read_rgba_pixels_16(const GLcontext
*ctx
,
1213 struct gl_renderbuffer
*rb
,
1214 GLuint n
, const GLint x
[], const GLint y
[],
1219 WMesaContext pwc
= wmesa_context(ctx
);
1220 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1222 for (i
=0; i
<n
; i
++) {
1223 GLint y2
= FLIP(y
[i
]);
1224 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y2
)) + x
[i
];
1226 /* Windows uses 5,5,5 for 16-bit */
1227 rgba
[i
][RCOMP
] = (pixel
& 0x7c00) >> 7;
1228 rgba
[i
][GCOMP
] = (pixel
& 0x03e0) >> 2;
1229 rgba
[i
][BCOMP
] = (pixel
& 0x001f) << 3;
1230 rgba
[i
][ACOMP
] = 255;
1237 /**********************************************************************/
1238 /***** BUFFER Functions *****/
1239 /**********************************************************************/
1245 wmesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1252 * This is called by Mesa whenever it determines that the window size
1253 * has changed. Do whatever's needed to cope with that.
1256 wmesa_renderbuffer_storage(GLcontext
*ctx
,
1257 struct gl_renderbuffer
*rb
,
1258 GLenum internalFormat
,
1263 rb
->Height
= height
;
1269 * Plug in the Get/PutRow/Values functions for a renderbuffer depending
1270 * on if we're drawing to the front or back color buffer.
1272 void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer
*rb
, int pixelformat
,
1273 BYTE cColorBits
, int double_buffer
)
1275 if (double_buffer
) {
1277 /* Picking the correct span functions is important because
1278 * the DIB was allocated with the indicated depth. */
1279 switch(pixelformat
) {
1281 rb
->PutRow
= write_rgba_span_16
;
1282 rb
->PutRowRGB
= write_rgb_span_16
;
1283 rb
->PutMonoRow
= write_mono_rgba_span_16
;
1284 rb
->PutValues
= write_rgba_pixels_16
;
1285 rb
->PutMonoValues
= write_mono_rgba_pixels_16
;
1286 rb
->GetRow
= read_rgba_span_16
;
1287 rb
->GetValues
= read_rgba_pixels_16
;
1293 if (cColorBits
== 24)
1295 rb
->PutRow
= write_rgba_span_24
;
1296 rb
->PutRowRGB
= write_rgb_span_24
;
1297 rb
->PutMonoRow
= write_mono_rgba_span_24
;
1298 rb
->PutValues
= write_rgba_pixels_24
;
1299 rb
->PutMonoValues
= write_mono_rgba_pixels_24
;
1300 rb
->GetRow
= read_rgba_span_24
;
1301 rb
->GetValues
= read_rgba_pixels_24
;
1308 rb
->PutRow
= write_rgba_span_32
;
1309 rb
->PutRowRGB
= write_rgb_span_32
;
1310 rb
->PutMonoRow
= write_mono_rgba_span_32
;
1311 rb
->PutValues
= write_rgba_pixels_32
;
1312 rb
->PutMonoValues
= write_mono_rgba_pixels_32
;
1313 rb
->GetRow
= read_rgba_span_32
;
1314 rb
->GetValues
= read_rgba_pixels_32
;
1325 /* front buffer (actual Windows window) */
1326 rb
->PutRow
= write_rgba_span_front
;
1327 rb
->PutRowRGB
= write_rgb_span_front
;
1328 rb
->PutMonoRow
= write_mono_rgba_span_front
;
1329 rb
->PutValues
= write_rgba_pixels_front
;
1330 rb
->PutMonoValues
= write_mono_rgba_pixels_front
;
1331 rb
->GetRow
= read_rgba_span_front
;
1332 rb
->GetValues
= read_rgba_pixels_front
;
1333 rb
->RedBits
= 8; /* XXX fix these (565?) */
1340 * Called by ctx->Driver.ResizeBuffers()
1341 * Resize the front/back colorbuffers to match the latest window size.
1344 wmesa_resize_buffers(GLcontext
*ctx
, GLframebuffer
*buffer
,
1345 GLuint width
, GLuint height
)
1347 WMesaContext pwc
= wmesa_context(ctx
);
1348 WMesaFramebuffer pwfb
= wmesa_framebuffer(buffer
);
1350 if (pwfb
->Base
.Width
!= width
|| pwfb
->Base
.Height
!= height
) {
1351 /* Realloc back buffer */
1352 if (ctx
->Visual
.doubleBufferMode
== 1) {
1353 wmDeleteBackingStore(pwfb
);
1354 wmCreateBackingStore(pwfb
, width
, height
);
1357 _mesa_resize_framebuffer(ctx
, buffer
, width
, height
);
1362 * Called by glViewport.
1363 * This is a good time for us to poll the current window size and adjust
1364 * our renderbuffers to match the current window size.
1365 * Remember, we have no opportunity to respond to conventional
1366 * resize events since the driver has no event loop.
1368 * MakeCurrent also ends up making a call here, so that ensures
1369 * we get the viewport set correctly, even if the app does not call
1370 * glViewport and relies on the defaults.
1372 static void wmesa_viewport(GLcontext
*ctx
,
1374 GLsizei width
, GLsizei height
)
1376 WMesaContext pwc
= wmesa_context(ctx
);
1377 GLuint new_width
, new_height
;
1379 wmesa_get_buffer_size(ctx
->WinSysDrawBuffer
, &new_width
, &new_height
);
1382 * Resize buffers if the window size changed.
1384 wmesa_resize_buffers(ctx
, ctx
->WinSysDrawBuffer
, new_width
, new_height
);
1385 ctx
->NewState
|= _NEW_BUFFERS
; /* to update scissor / window bounds */
1392 * Called when the driver should update it's state, based on the new_state
1395 static void wmesa_update_state(GLcontext
*ctx
, GLuint new_state
)
1397 _swrast_InvalidateState(ctx
, new_state
);
1398 _swsetup_InvalidateState(ctx
, new_state
);
1399 _vbo_InvalidateState(ctx
, new_state
);
1400 _tnl_InvalidateState(ctx
, new_state
);
1402 /* TODO - This code is not complete yet because I
1403 * don't know what to do for all state updates.
1406 if (new_state
& _NEW_BUFFERS
) {
1414 /**********************************************************************/
1415 /***** WMESA Functions *****/
1416 /**********************************************************************/
1418 WMesaContext
WMesaCreateContext(HDC hDC
,
1422 GLboolean alpha_flag
)
1425 struct dd_function_table functions
;
1426 GLint red_bits
, green_bits
, blue_bits
, alpha_bits
;
1432 /* Indexed mode not supported */
1436 /* Allocate wmesa context */
1437 c
= CALLOC_STRUCT(wmesa_context
);
1442 /* I do not understand this contributed code */
1443 /* Support memory and device contexts */
1444 if(WindowFromDC(hDC
) != NULL
) {
1445 c
->hDC
= GetDC(WindowFromDC(hDC
)); /* huh ???? */
1454 /* Get data for visual */
1455 /* Dealing with this is actually a bit of overkill because Mesa will end
1456 * up treating all color component size requests less than 8 by using
1457 * a single byte per channel. In addition, the interface to the span
1458 * routines passes colors as an entire byte per channel anyway, so there
1459 * is nothing to be saved by telling the visual to be 16 bits if the device
1460 * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per
1462 * But we go through the motions here anyway.
1464 switch (GetDeviceCaps(c
->hDC
, BITSPIXEL
)) {
1466 red_bits
= green_bits
= blue_bits
= 5;
1470 red_bits
= green_bits
= blue_bits
= 8;
1474 /* Create visual based on flags */
1475 visual
= _mesa_create_visual(rgb_flag
,
1476 db_flag
, /* db_flag */
1477 GL_FALSE
, /* stereo */
1478 red_bits
, green_bits
, blue_bits
, /* color RGB */
1479 alpha_flag
? alpha_bits
: 0, /* color A */
1481 DEFAULT_SOFTWARE_DEPTH_BITS
, /* depth_bits */
1482 8, /* stencil_bits */
1483 16,16,16, /* accum RGB */
1484 alpha_flag
? 16 : 0, /* accum A */
1485 1); /* num samples */
1492 /* Set up driver functions */
1493 _mesa_init_driver_functions(&functions
);
1494 functions
.GetString
= wmesa_get_string
;
1495 functions
.UpdateState
= wmesa_update_state
;
1496 functions
.GetBufferSize
= wmesa_get_buffer_size
;
1497 functions
.Flush
= wmesa_flush
;
1498 functions
.Clear
= clear
;
1499 functions
.ClearIndex
= clear_index
;
1500 functions
.ClearColor
= clear_color
;
1501 functions
.ResizeBuffers
= wmesa_resize_buffers
;
1502 functions
.Viewport
= wmesa_viewport
;
1504 /* initialize the Mesa context data */
1506 _mesa_initialize_context(ctx
, visual
, NULL
, &functions
, (void *)c
);
1508 /* visual no longer needed - it was copied by _mesa_initialize_context() */
1509 _mesa_destroy_visual(visual
);
1511 _mesa_enable_sw_extensions(ctx
);
1512 _mesa_enable_1_3_extensions(ctx
);
1513 _mesa_enable_1_4_extensions(ctx
);
1514 _mesa_enable_1_5_extensions(ctx
);
1515 _mesa_enable_2_0_extensions(ctx
);
1516 _mesa_enable_2_1_extensions(ctx
);
1518 /* Initialize the software rasterizer and helper modules. */
1519 if (!_swrast_CreateContext(ctx
) ||
1520 !_vbo_CreateContext(ctx
) ||
1521 !_tnl_CreateContext(ctx
) ||
1522 !_swsetup_CreateContext(ctx
)) {
1523 _mesa_free_context_data(ctx
);
1527 _swsetup_Wakeup(ctx
);
1528 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
1534 void WMesaDestroyContext( WMesaContext pwc
)
1536 GLcontext
*ctx
= &pwc
->gl_ctx
;
1537 WMesaFramebuffer pwfb
;
1538 GET_CURRENT_CONTEXT(cur_ctx
);
1540 if (cur_ctx
== ctx
) {
1541 /* unbind current if deleting current context */
1542 WMesaMakeCurrent(NULL
, NULL
);
1545 /* clean up frame buffer resources */
1546 pwfb
= wmesa_lookup_framebuffer(pwc
->hDC
);
1548 if (ctx
->Visual
.doubleBufferMode
== 1)
1549 wmDeleteBackingStore(pwfb
);
1550 wmesa_free_framebuffer(pwc
->hDC
);
1553 /* Release for device, not memory contexts */
1554 if (WindowFromDC(pwc
->hDC
) != NULL
)
1556 ReleaseDC(WindowFromDC(pwc
->hDC
), pwc
->hDC
);
1558 DeleteObject(pwc
->clearPen
);
1559 DeleteObject(pwc
->clearBrush
);
1561 _swsetup_DestroyContext(ctx
);
1562 _tnl_DestroyContext(ctx
);
1563 _vbo_DestroyContext(ctx
);
1564 _swrast_DestroyContext(ctx
);
1566 _mesa_free_context_data(ctx
);
1572 * Create a new color renderbuffer.
1574 struct gl_renderbuffer
*
1575 wmesa_new_renderbuffer(void)
1577 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1581 _mesa_init_renderbuffer(rb
, (GLuint
)0);
1583 rb
->_BaseFormat
= GL_RGBA
;
1584 rb
->InternalFormat
= GL_RGBA
;
1585 rb
->DataType
= CHAN_TYPE
;
1586 rb
->Delete
= wmesa_delete_renderbuffer
;
1587 rb
->AllocStorage
= wmesa_renderbuffer_storage
;
1592 void WMesaMakeCurrent(WMesaContext c
, HDC hdc
)
1594 WMesaFramebuffer pwfb
;
1597 /* return if already current */
1598 GET_CURRENT_CONTEXT(ctx
);
1599 WMesaContext pwc
= wmesa_context(ctx
);
1600 if (pwc
&& c
== pwc
&& pwc
->hDC
== hdc
)
1604 pwfb
= wmesa_lookup_framebuffer(hdc
);
1606 /* Lazy creation of framebuffers */
1607 if (c
&& !pwfb
&& hdc
) {
1608 struct gl_renderbuffer
*rb
;
1609 GLvisual
*visual
= &c
->gl_ctx
.Visual
;
1610 GLuint width
, height
;
1612 get_window_size(hdc
, &width
, &height
);
1614 c
->clearPen
= CreatePen(PS_SOLID
, 1, 0);
1615 c
->clearBrush
= CreateSolidBrush(0);
1617 pwfb
= wmesa_new_framebuffer(hdc
, visual
);
1619 /* Create back buffer if double buffered */
1620 if (visual
->doubleBufferMode
== 1) {
1621 wmCreateBackingStore(pwfb
, width
, height
);
1624 /* make render buffers */
1625 if (visual
->doubleBufferMode
== 1) {
1626 rb
= wmesa_new_renderbuffer();
1627 _mesa_add_renderbuffer(&pwfb
->Base
, BUFFER_BACK_LEFT
, rb
);
1628 wmesa_set_renderbuffer_funcs(rb
, pwfb
->pixelformat
, pwfb
->cColorBits
, 1);
1630 rb
= wmesa_new_renderbuffer();
1631 _mesa_add_renderbuffer(&pwfb
->Base
, BUFFER_FRONT_LEFT
, rb
);
1632 wmesa_set_renderbuffer_funcs(rb
, pwfb
->pixelformat
, pwfb
->cColorBits
, 0);
1634 /* Let Mesa own the Depth, Stencil, and Accum buffers */
1635 _mesa_add_soft_renderbuffers(&pwfb
->Base
,
1636 GL_FALSE
, /* color */
1637 visual
->depthBits
> 0,
1638 visual
->stencilBits
> 0,
1639 visual
->accumRedBits
> 0,
1640 visual
->alphaBits
>0,
1645 _mesa_make_current(&c
->gl_ctx
, &pwfb
->Base
, &pwfb
->Base
);
1647 _mesa_make_current(NULL
, NULL
, NULL
);
1651 void WMesaSwapBuffers( HDC hdc
)
1653 GET_CURRENT_CONTEXT(ctx
);
1654 WMesaContext pwc
= wmesa_context(ctx
);
1655 WMesaFramebuffer pwfb
= wmesa_lookup_framebuffer(hdc
);
1658 _mesa_problem(NULL
, "wmesa: swapbuffers on unknown hdc");
1662 /* If we're swapping the buffer associated with the current context
1663 * we have to flush any pending rendering commands first.
1665 if (pwc
->hDC
== hdc
) {
1666 _mesa_notifySwapBuffers(ctx
);
1668 BitBlt(pwfb
->hDC
, 0, 0, pwfb
->Base
.Width
, pwfb
->Base
.Height
,
1669 pwfb
->dib_hDC
, 0, 0, SRCCOPY
);
1672 /* XXX for now only allow swapping current window */
1673 _mesa_problem(NULL
, "wmesa: can't swap non-current window");
1677 void WMesaShareLists(WMesaContext ctx_to_share
, WMesaContext ctx
)
1679 _mesa_share_state(&ctx
->gl_ctx
, &ctx_to_share
->gl_ctx
);
1682 /* This is hopefully a temporary hack to define some needed dispatch
1683 * table entries. Hopefully, I'll find a better solution. The
1684 * dispatch table generation scripts ought to be making these dummy
1686 #if !defined(__MINGW32__) || !defined(GL_NO_STDCALL)
1687 void gl_dispatch_stub_543(void){}
1688 void gl_dispatch_stub_544(void){}
1689 void gl_dispatch_stub_545(void){}
1690 void gl_dispatch_stub_546(void){}
1691 void gl_dispatch_stub_547(void){}
1692 void gl_dispatch_stub_548(void){}
1693 void gl_dispatch_stub_549(void){}
1694 void gl_dispatch_stub_550(void){}
1695 void gl_dispatch_stub_551(void){}
1696 void gl_dispatch_stub_552(void){}
1697 void gl_dispatch_stub_553(void){}
1698 void gl_dispatch_stub_554(void){}
1699 void gl_dispatch_stub_555(void){}
1700 void gl_dispatch_stub_556(void){}
1701 void gl_dispatch_stub_557(void){}
1702 void gl_dispatch_stub_558(void){}
1703 void gl_dispatch_stub_559(void){}
1704 void gl_dispatch_stub_560(void){}
1705 void gl_dispatch_stub_561(void){}
1706 void gl_dispatch_stub_565(void){}
1707 void gl_dispatch_stub_566(void){}
1708 void gl_dispatch_stub_577(void){}
1709 void gl_dispatch_stub_578(void){}
1710 void gl_dispatch_stub_603(void){}
1711 void gl_dispatch_stub_645(void){}
1712 void gl_dispatch_stub_646(void){}
1713 void gl_dispatch_stub_647(void){}
1714 void gl_dispatch_stub_648(void){}
1715 void gl_dispatch_stub_649(void){}
1716 void gl_dispatch_stub_650(void){}
1717 void gl_dispatch_stub_651(void){}
1718 void gl_dispatch_stub_652(void){}
1719 void gl_dispatch_stub_653(void){}
1720 void gl_dispatch_stub_733(void){}
1721 void gl_dispatch_stub_734(void){}
1722 void gl_dispatch_stub_735(void){}
1723 void gl_dispatch_stub_736(void){}
1724 void gl_dispatch_stub_737(void){}
1725 void gl_dispatch_stub_738(void){}
1726 void gl_dispatch_stub_744(void){}
1727 void gl_dispatch_stub_745(void){}
1728 void gl_dispatch_stub_746(void){}
1729 void gl_dispatch_stub_760(void){}
1730 void gl_dispatch_stub_761(void){}
1731 void gl_dispatch_stub_763(void){}
1732 void gl_dispatch_stub_765(void){}
1733 void gl_dispatch_stub_766(void){}
1734 void gl_dispatch_stub_767(void){}
1735 void gl_dispatch_stub_768(void){}
1737 void gl_dispatch_stub_562(void){}
1738 void gl_dispatch_stub_563(void){}
1739 void gl_dispatch_stub_564(void){}
1740 void gl_dispatch_stub_567(void){}
1741 void gl_dispatch_stub_568(void){}
1742 void gl_dispatch_stub_569(void){}
1743 void gl_dispatch_stub_580(void){}
1744 void gl_dispatch_stub_581(void){}
1745 void gl_dispatch_stub_606(void){}
1746 void gl_dispatch_stub_654(void){}
1747 void gl_dispatch_stub_655(void){}
1748 void gl_dispatch_stub_656(void){}
1749 void gl_dispatch_stub_739(void){}
1750 void gl_dispatch_stub_740(void){}
1751 void gl_dispatch_stub_741(void){}
1752 void gl_dispatch_stub_748(void){}
1753 void gl_dispatch_stub_749(void){}
1754 void gl_dispatch_stub_769(void){}
1755 void gl_dispatch_stub_770(void){}
1756 void gl_dispatch_stub_771(void){}