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"
15 #include "drivers/common/meta.h"
17 #include "swrast/swrast.h"
18 #include "swrast_setup/swrast_setup.h"
20 #include "tnl/t_context.h"
21 #include "tnl/t_pipeline.h"
24 /* linked list of our Framebuffers (windows) */
25 static WMesaFramebuffer FirstFramebuffer
= NULL
;
29 * Create a new WMesaFramebuffer object which will correspond to the
30 * given HDC (Window handle).
33 wmesa_new_framebuffer(HDC hdc
, GLvisual
*visual
)
36 = (WMesaFramebuffer
) malloc(sizeof(struct wmesa_framebuffer
));
38 _mesa_initialize_framebuffer(&pwfb
->Base
, visual
);
40 /* insert at head of list */
41 pwfb
->next
= FirstFramebuffer
;
42 FirstFramebuffer
= pwfb
;
48 * Given an hdc, free the corresponding WMesaFramebuffer
51 wmesa_free_framebuffer(HDC hdc
)
53 WMesaFramebuffer pwfb
, prev
;
54 for (pwfb
= FirstFramebuffer
; pwfb
; pwfb
= pwfb
->next
) {
60 struct gl_framebuffer
*fb
;
61 if (pwfb
== FirstFramebuffer
)
62 FirstFramebuffer
= pwfb
->next
;
64 prev
->next
= pwfb
->next
;
66 _mesa_reference_framebuffer(&fb
, NULL
);
71 * Given an hdc, return the corresponding WMesaFramebuffer
74 wmesa_lookup_framebuffer(HDC hdc
)
76 WMesaFramebuffer pwfb
;
77 for (pwfb
= FirstFramebuffer
; pwfb
; pwfb
= pwfb
->next
) {
86 * Given a GLframebuffer, return the corresponding WMesaFramebuffer.
88 static WMesaFramebuffer
wmesa_framebuffer(GLframebuffer
*fb
)
90 return (WMesaFramebuffer
) fb
;
95 * Given a GLcontext, return the corresponding WMesaContext.
97 static WMesaContext
wmesa_context(const GLcontext
*ctx
)
99 return (WMesaContext
) ctx
;
104 * Every driver should implement a GetString function in order to
105 * return a meaningful GL_RENDERER string.
107 static const GLubyte
*wmesa_get_string(GLcontext
*ctx
, GLenum name
)
109 return (name
== GL_RENDERER
) ?
110 (GLubyte
*) "Mesa Windows GDI Driver" : NULL
;
115 * Determine the pixel format based on the pixel size.
117 static void wmSetPixelFormat(WMesaFramebuffer pwfb
, HDC hDC
)
119 pwfb
->cColorBits
= GetDeviceCaps(hDC
, BITSPIXEL
);
121 /* Only 16 and 32 bit targets are supported now */
122 assert(pwfb
->cColorBits
== 0 ||
123 pwfb
->cColorBits
== 16 ||
124 pwfb
->cColorBits
== 24 ||
125 pwfb
->cColorBits
== 32);
127 switch(pwfb
->cColorBits
){
129 pwfb
->pixelformat
= PF_INDEX8
;
132 pwfb
->pixelformat
= PF_5R6G5B
;
136 pwfb
->pixelformat
= PF_8R8G8B
;
139 pwfb
->pixelformat
= PF_BADFORMAT
;
145 * Create DIB for back buffer.
146 * We write into this memory with the span routines and then blit it
147 * to the window on a buffer swap.
149 BOOL
wmCreateBackingStore(WMesaFramebuffer pwfb
, long lxSize
, long lySize
)
152 LPBITMAPINFO pbmi
= &(pwfb
->bmi
);
155 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
156 pbmi
->bmiHeader
.biWidth
= lxSize
;
157 pbmi
->bmiHeader
.biHeight
= -lySize
;
158 pbmi
->bmiHeader
.biPlanes
= 1;
159 pbmi
->bmiHeader
.biBitCount
= GetDeviceCaps(pwfb
->hDC
, BITSPIXEL
);
160 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
161 pbmi
->bmiHeader
.biSizeImage
= 0;
162 pbmi
->bmiHeader
.biXPelsPerMeter
= 0;
163 pbmi
->bmiHeader
.biYPelsPerMeter
= 0;
164 pbmi
->bmiHeader
.biClrUsed
= 0;
165 pbmi
->bmiHeader
.biClrImportant
= 0;
167 pwfb
->cColorBits
= pbmi
->bmiHeader
.biBitCount
;
168 pwfb
->ScanWidth
= (lxSize
* (pwfb
->cColorBits
/ 8) + 3) & ~3;
170 hic
= CreateIC("display", NULL
, NULL
, NULL
);
171 pwfb
->dib_hDC
= CreateCompatibleDC(hic
);
173 pwfb
->hbmDIB
= CreateDIBSection(hic
,
176 (void **)&(pwfb
->pbPixels
),
179 pwfb
->hOldBitmap
= SelectObject(pwfb
->dib_hDC
, pwfb
->hbmDIB
);
183 wmSetPixelFormat(pwfb
, pwfb
->hDC
);
188 static wmDeleteBackingStore(WMesaFramebuffer pwfb
)
191 SelectObject(pwfb
->dib_hDC
, pwfb
->hOldBitmap
);
192 DeleteDC(pwfb
->dib_hDC
);
193 DeleteObject(pwfb
->hbmDIB
);
199 * Find the width and height of the window named by hdc.
202 get_window_size(HDC hdc
, GLuint
*width
, GLuint
*height
)
204 if (WindowFromDC(hdc
)) {
206 GetClientRect(WindowFromDC(hdc
), &rect
);
207 *width
= rect
.right
- rect
.left
;
208 *height
= rect
.bottom
- rect
.top
;
210 else { /* Memory context */
211 /* From contributed code - use the size of the desktop
212 * for the size of a memory context (?) */
213 *width
= GetDeviceCaps(hdc
, HORZRES
);
214 *height
= GetDeviceCaps(hdc
, VERTRES
);
220 wmesa_get_buffer_size(GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
222 WMesaFramebuffer pwfb
= wmesa_framebuffer(buffer
);
223 get_window_size(pwfb
->hDC
, width
, height
);
227 static void wmesa_flush(GLcontext
*ctx
)
229 WMesaContext pwc
= wmesa_context(ctx
);
230 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->WinSysDrawBuffer
);
232 if (ctx
->Visual
.doubleBufferMode
== 1) {
233 BitBlt(pwfb
->hDC
, 0, 0, pwfb
->Base
.Width
, pwfb
->Base
.Height
,
234 pwfb
->dib_hDC
, 0, 0, SRCCOPY
);
237 /* Do nothing for single buffer */
242 /**********************************************************************/
243 /***** CLEAR Functions *****/
244 /**********************************************************************/
246 /* If we do not implement these, Mesa clears the buffers via the pixel
247 * span writing interface, which is very slow for a clear operation.
251 * Set the color index used to clear the color buffer.
253 static void clear_index(GLcontext
*ctx
, GLuint index
)
255 WMesaContext pwc
= wmesa_context(ctx
);
256 /* Note that indexed mode is not supported yet */
257 pwc
->clearColorRef
= RGB(0,0,0);
261 * Set the color used to clear the color buffer.
263 static void clear_color(GLcontext
*ctx
, const GLfloat color
[4])
265 WMesaContext pwc
= wmesa_context(ctx
);
266 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
268 UINT bytesPerPixel
= pwfb
->cColorBits
/ 8;
270 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
271 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
272 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
273 pwc
->clearColorRef
= RGB(col
[0], col
[1], col
[2]);
274 DeleteObject(pwc
->clearPen
);
275 DeleteObject(pwc
->clearBrush
);
276 pwc
->clearPen
= CreatePen(PS_SOLID
, 1, pwc
->clearColorRef
);
277 pwc
->clearBrush
= CreateSolidBrush(pwc
->clearColorRef
);
282 * Clear the specified region of the color buffer using the clear color
283 * or index as specified by one of the two functions above.
285 * This procedure clears either the front and/or the back COLOR buffers.
286 * Only the "left" buffer is cleared since we are not stereo.
287 * Clearing of the other non-color buffers is left to the swrast.
290 static void clear(GLcontext
*ctx
, GLbitfield mask
)
292 #define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1)
293 const GLint x
= ctx
->DrawBuffer
->_Xmin
;
294 const GLint y
= ctx
->DrawBuffer
->_Ymin
;
295 const GLint height
= ctx
->DrawBuffer
->_Ymax
- ctx
->DrawBuffer
->_Ymin
;
296 const GLint width
= ctx
->DrawBuffer
->_Xmax
- ctx
->DrawBuffer
->_Xmin
;
298 WMesaContext pwc
= wmesa_context(ctx
);
299 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
302 /* Let swrast do all the work if the masks are not set to
303 * clear all channels. */
304 if (!ctx
->Color
.ColorMask
[0][0] ||
305 !ctx
->Color
.ColorMask
[0][1] ||
306 !ctx
->Color
.ColorMask
[0][2] ||
307 !ctx
->Color
.ColorMask
[0][3]) {
308 _swrast_Clear(ctx
, mask
);
313 if (mask
& BUFFER_BIT_BACK_LEFT
) {
316 UINT bytesPerPixel
= pwfb
->cColorBits
/ 8;
317 LPBYTE lpb
, clearRow
;
325 /* Try for a fast clear - clearing entire buffer with a single
327 if (width
== ctx
->DrawBuffer
->Width
&&
328 height
== ctx
->DrawBuffer
->Height
) { /* entire buffer */
329 /* Now check for an easy clear value */
330 switch (bytesPerPixel
) {
332 bColor
= BGR8(GetRValue(pwc
->clearColorRef
),
333 GetGValue(pwc
->clearColorRef
),
334 GetBValue(pwc
->clearColorRef
));
335 memset(pwfb
->pbPixels
, bColor
,
336 pwfb
->ScanWidth
* height
);
340 wColor
= BGR16(GetRValue(pwc
->clearColorRef
),
341 GetGValue(pwc
->clearColorRef
),
342 GetBValue(pwc
->clearColorRef
));
343 if (((wColor
>> 8) & 0xff) == (wColor
& 0xff)) {
344 memset(pwfb
->pbPixels
, wColor
& 0xff,
345 pwfb
->ScanWidth
* height
);
352 if (GetRValue(pwc
->clearColorRef
) ==
353 GetGValue(pwc
->clearColorRef
) &&
354 GetRValue(pwc
->clearColorRef
) ==
355 GetBValue(pwc
->clearColorRef
)) {
356 memset(pwfb
->pbPixels
,
357 GetRValue(pwc
->clearColorRef
),
358 pwfb
->ScanWidth
* height
);
368 /* Need to clear a row at a time. Begin by setting the first
369 * row in the area to be cleared to the clear color. */
371 clearRow
= pwfb
->pbPixels
+
372 pwfb
->ScanWidth
* FLIP(y
) +
374 switch (bytesPerPixel
) {
377 bColor
= BGR8(GetRValue(pwc
->clearColorRef
),
378 GetGValue(pwc
->clearColorRef
),
379 GetBValue(pwc
->clearColorRef
));
380 memset(lpb
, bColor
, width
);
383 lpw
= (LPWORD
)clearRow
;
384 wColor
= BGR16(GetRValue(pwc
->clearColorRef
),
385 GetGValue(pwc
->clearColorRef
),
386 GetBValue(pwc
->clearColorRef
));
387 for (i
=0; i
<width
; i
++)
392 r
= GetRValue(pwc
->clearColorRef
);
393 g
= GetGValue(pwc
->clearColorRef
);
394 b
= GetBValue(pwc
->clearColorRef
);
395 for (i
=0; i
<width
; i
++) {
402 lpdw
= (LPDWORD
)clearRow
;
403 dwColor
= BGR32(GetRValue(pwc
->clearColorRef
),
404 GetGValue(pwc
->clearColorRef
),
405 GetBValue(pwc
->clearColorRef
));
406 for (i
=0; i
<width
; i
++)
413 /* copy cleared row to other rows in buffer */
414 lpb
= clearRow
- pwfb
->ScanWidth
;
415 rowSize
= width
* bytesPerPixel
;
416 for (i
=1; i
<height
; i
++) {
417 memcpy(lpb
, clearRow
, rowSize
);
418 lpb
-= pwfb
->ScanWidth
;
421 mask
&= ~BUFFER_BIT_BACK_LEFT
;
425 if (mask
& BUFFER_BIT_FRONT_LEFT
) {
427 HPEN Old_Pen
= SelectObject(DC
, pwc
->clearPen
);
428 HBRUSH Old_Brush
= SelectObject(DC
, pwc
->clearBrush
);
433 FLIP(y
) - height
+ 1);
434 SelectObject(DC
, Old_Pen
);
435 SelectObject(DC
, Old_Brush
);
436 mask
&= ~BUFFER_BIT_FRONT_LEFT
;
439 /* Call swrast if there is anything left to clear (like DEPTH) */
441 _swrast_Clear(ctx
, mask
);
447 /**********************************************************************/
448 /***** PIXEL Functions *****/
449 /**********************************************************************/
451 #define FLIP(Y) (rb->Height - (Y) - 1)
455 ** Front Buffer reading/writing
456 ** These are slow, but work with all non-indexed visual types.
459 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
460 static void write_rgba_span_front(const GLcontext
*ctx
,
461 struct gl_renderbuffer
*rb
,
462 GLuint n
, GLint x
, GLint y
,
463 const GLubyte rgba
[][4],
464 const GLubyte mask
[] )
466 WMesaContext pwc
= wmesa_context(ctx
);
467 WMesaFramebuffer pwfb
= wmesa_lookup_framebuffer(pwc
->hDC
);
468 CONST BITMAPINFO bmi
=
471 sizeof(BITMAPINFOHEADER
),
472 n
, 1, 1, 32, BI_RGB
, 0, 1, 1, 0, 0
481 unsigned b
:8, g
:8, r
:8, a
:8;
487 if (n
< 16) { // the value 16 is just guessed
492 SetPixel(pwc
->hDC
, x
+i
, y
,
493 RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
497 SetPixel(pwc
->hDC
, x
+i
, y
,
498 RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]));
503 _mesa_problem(NULL
, "wmesa: write_rgba_span_front on unknown hdc");
506 bgra
=malloc(n
*sizeof(BGRA
));
508 _mesa_problem(NULL
, "wmesa: write_rgba_span_front: out of memory");
513 for (i
=0; i
<n
; i
++) {
526 for (i
=0; i
<n
; i
++) {
534 bmp
=CreateBitmap(n
, 1, 1, 32, bgra
);
535 mdc
=CreateCompatibleDC(pwfb
->hDC
);
536 SelectObject(mdc
, bmp
);
538 BitBlt(pwfb
->hDC
, x
, y
, n
, 1, mdc
, 0, 0, SRCCOPY
);
539 SelectObject(mdc
, 0);
546 /* Write a horizontal span of RGB color pixels with a boolean mask. */
547 static void write_rgb_span_front(const GLcontext
*ctx
,
548 struct gl_renderbuffer
*rb
,
549 GLuint n
, GLint x
, GLint y
,
550 const GLubyte rgb
[][3],
551 const GLubyte mask
[] )
553 WMesaContext pwc
= wmesa_context(ctx
);
561 SetPixel(pwc
->hDC
, x
+i
, y
, RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
566 SetPixel(pwc
->hDC
, x
+i
, y
, RGB(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
573 * Write a horizontal span of pixels with a boolean mask. The current color
574 * is used for all pixels.
576 static void write_mono_rgba_span_front(const GLcontext
*ctx
,
577 struct gl_renderbuffer
*rb
,
578 GLuint n
, GLint x
, GLint y
,
579 const GLchan color
[4],
580 const GLubyte mask
[])
583 WMesaContext pwc
= wmesa_context(ctx
);
587 colorref
= RGB(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
592 SetPixel(pwc
->hDC
, x
+i
, y
, colorref
);
596 SetPixel(pwc
->hDC
, x
+i
, y
, colorref
);
600 /* Write an array of RGBA pixels with a boolean mask. */
601 static void write_rgba_pixels_front(const GLcontext
*ctx
,
602 struct gl_renderbuffer
*rb
,
604 const GLint x
[], const GLint y
[],
605 const GLubyte rgba
[][4],
606 const GLubyte mask
[] )
609 WMesaContext pwc
= wmesa_context(ctx
);
613 SetPixel(pwc
->hDC
, x
[i
], FLIP(y
[i
]),
614 RGB(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
621 * Write an array of pixels with a boolean mask. The current color
622 * is used for all pixels.
624 static void write_mono_rgba_pixels_front(const GLcontext
*ctx
,
625 struct gl_renderbuffer
*rb
,
627 const GLint x
[], const GLint y
[],
628 const GLchan color
[4],
629 const GLubyte mask
[] )
632 WMesaContext pwc
= wmesa_context(ctx
);
635 colorref
= RGB(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
638 SetPixel(pwc
->hDC
, x
[i
], FLIP(y
[i
]), colorref
);
641 /* Read a horizontal span of color pixels. */
642 static void read_rgba_span_front(const GLcontext
*ctx
,
643 struct gl_renderbuffer
*rb
,
644 GLuint n
, GLint x
, GLint y
,
647 WMesaContext pwc
= wmesa_context(ctx
);
651 for (i
=0; i
<n
; i
++) {
652 Color
= GetPixel(pwc
->hDC
, x
+i
, y
);
653 rgba
[i
][RCOMP
] = GetRValue(Color
);
654 rgba
[i
][GCOMP
] = GetGValue(Color
);
655 rgba
[i
][BCOMP
] = GetBValue(Color
);
656 rgba
[i
][ACOMP
] = 255;
661 /* Read an array of color pixels. */
662 static void read_rgba_pixels_front(const GLcontext
*ctx
,
663 struct gl_renderbuffer
*rb
,
664 GLuint n
, const GLint x
[], const GLint y
[],
667 WMesaContext pwc
= wmesa_context(ctx
);
670 for (i
=0; i
<n
; i
++) {
671 GLint y2
= FLIP(y
[i
]);
672 Color
= GetPixel(pwc
->hDC
, x
[i
], y2
);
673 rgba
[i
][RCOMP
] = GetRValue(Color
);
674 rgba
[i
][GCOMP
] = GetGValue(Color
);
675 rgba
[i
][BCOMP
] = GetBValue(Color
);
676 rgba
[i
][ACOMP
] = 255;
680 /*********************************************************************/
682 /* DOUBLE BUFFER 32-bit */
684 #define WMSETPIXEL32(pwc, y, x, r, g, b) { \
685 LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
686 *lpdw = BGR32((r),(g),(b)); }
690 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
691 static void write_rgba_span_32(const GLcontext
*ctx
,
692 struct gl_renderbuffer
*rb
,
693 GLuint n
, GLint x
, GLint y
,
694 const GLubyte rgba
[][4],
695 const GLubyte mask
[] )
697 WMesaContext pwc
= wmesa_context(ctx
);
698 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
705 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
709 lpdw
[i
] = BGR32(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
714 *lpdw
++ = BGR32(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
720 /* Write a horizontal span of RGB color pixels with a boolean mask. */
721 static void write_rgb_span_32(const GLcontext
*ctx
,
722 struct gl_renderbuffer
*rb
,
723 GLuint n
, GLint x
, GLint y
,
724 const GLubyte rgb
[][3],
725 const GLubyte mask
[] )
727 WMesaContext pwc
= wmesa_context(ctx
);
728 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
735 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
739 lpdw
[i
] = BGR32(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
744 *lpdw
++ = BGR32(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
750 * Write a horizontal span of pixels with a boolean mask. The current color
751 * is used for all pixels.
753 static void write_mono_rgba_span_32(const GLcontext
*ctx
,
754 struct gl_renderbuffer
*rb
,
755 GLuint n
, GLint x
, GLint y
,
756 const GLchan color
[4],
757 const GLubyte mask
[])
762 WMesaContext pwc
= wmesa_context(ctx
);
763 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
764 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
766 pixel
= BGR32(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
778 /* Write an array of RGBA pixels with a boolean mask. */
779 static void write_rgba_pixels_32(const GLcontext
*ctx
,
780 struct gl_renderbuffer
*rb
,
781 GLuint n
, const GLint x
[], const GLint y
[],
782 const GLubyte rgba
[][4],
783 const GLubyte mask
[])
786 WMesaContext pwc
= wmesa_context(ctx
);
787 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
790 WMSETPIXEL32(pwfb
, FLIP(y
[i
]), x
[i
],
791 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
795 * Write an array of pixels with a boolean mask. The current color
796 * is used for all pixels.
798 static void write_mono_rgba_pixels_32(const GLcontext
*ctx
,
799 struct gl_renderbuffer
*rb
,
801 const GLint x
[], const GLint y
[],
802 const GLchan color
[4],
803 const GLubyte mask
[])
806 WMesaContext pwc
= wmesa_context(ctx
);
807 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
810 WMSETPIXEL32(pwfb
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
811 color
[GCOMP
], color
[BCOMP
]);
814 /* Read a horizontal span of color pixels. */
815 static void read_rgba_span_32(const GLcontext
*ctx
,
816 struct gl_renderbuffer
*rb
,
817 GLuint n
, GLint x
, GLint y
,
823 WMesaContext pwc
= wmesa_context(ctx
);
824 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
827 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
828 for (i
=0; i
<n
; i
++) {
830 rgba
[i
][RCOMP
] = (pixel
& 0x00ff0000) >> 16;
831 rgba
[i
][GCOMP
] = (pixel
& 0x0000ff00) >> 8;
832 rgba
[i
][BCOMP
] = (pixel
& 0x000000ff);
833 rgba
[i
][ACOMP
] = 255;
838 /* Read an array of color pixels. */
839 static void read_rgba_pixels_32(const GLcontext
*ctx
,
840 struct gl_renderbuffer
*rb
,
841 GLuint n
, const GLint x
[], const GLint y
[],
847 WMesaContext pwc
= wmesa_context(ctx
);
848 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
850 for (i
=0; i
<n
; i
++) {
851 GLint y2
= FLIP(y
[i
]);
852 lpdw
= ((LPDWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y2
)) + x
[i
];
854 rgba
[i
][RCOMP
] = (pixel
& 0x00ff0000) >> 16;
855 rgba
[i
][GCOMP
] = (pixel
& 0x0000ff00) >> 8;
856 rgba
[i
][BCOMP
] = (pixel
& 0x000000ff);
857 rgba
[i
][ACOMP
] = 255;
862 /*********************************************************************/
864 /* DOUBLE BUFFER 24-bit */
866 #define WMSETPIXEL24(pwc, y, x, r, g, b) { \
867 LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \
872 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
873 static void write_rgba_span_24(const GLcontext
*ctx
,
874 struct gl_renderbuffer
*rb
,
875 GLuint n
, GLint x
, GLint y
,
876 const GLubyte rgba
[][4],
877 const GLubyte mask
[] )
879 WMesaContext pwc
= wmesa_context(ctx
);
880 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
887 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
891 lpb
[3*i
] = rgba
[i
][BCOMP
];
892 lpb
[3*i
+1] = rgba
[i
][GCOMP
];
893 lpb
[3*i
+2] = rgba
[i
][RCOMP
];
897 for (i
=0; i
<n
; i
++) {
898 *lpb
++ = rgba
[i
][BCOMP
];
899 *lpb
++ = rgba
[i
][GCOMP
];
900 *lpb
++ = rgba
[i
][RCOMP
];
906 /* Write a horizontal span of RGB color pixels with a boolean mask. */
907 static void write_rgb_span_24(const GLcontext
*ctx
,
908 struct gl_renderbuffer
*rb
,
909 GLuint n
, GLint x
, GLint y
,
910 const GLubyte rgb
[][3],
911 const GLubyte mask
[] )
913 WMesaContext pwc
= wmesa_context(ctx
);
914 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
921 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
925 lpb
[3*i
] = rgb
[i
][BCOMP
];
926 lpb
[3*i
+1] = rgb
[i
][GCOMP
];
927 lpb
[3*i
+2] = rgb
[i
][RCOMP
];
931 for (i
=0; i
<n
; i
++) {
932 *lpb
++ = rgb
[i
][BCOMP
];
933 *lpb
++ = rgb
[i
][GCOMP
];
934 *lpb
++ = rgb
[i
][RCOMP
];
940 * Write a horizontal span of pixels with a boolean mask. The current color
941 * is used for all pixels.
943 static void write_mono_rgba_span_24(const GLcontext
*ctx
,
944 struct gl_renderbuffer
*rb
,
945 GLuint n
, GLint x
, GLint y
,
946 const GLchan color
[4],
947 const GLubyte mask
[])
951 WMesaContext pwc
= wmesa_context(ctx
);
952 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
953 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
958 lpb
[3*i
] = color
[BCOMP
];
959 lpb
[3*i
+1] = color
[GCOMP
];
960 lpb
[3*i
+2] = color
[RCOMP
];
964 for (i
=0; i
<n
; i
++) {
965 *lpb
++ = color
[BCOMP
];
966 *lpb
++ = color
[GCOMP
];
967 *lpb
++ = color
[RCOMP
];
971 /* Write an array of RGBA pixels with a boolean mask. */
972 static void write_rgba_pixels_24(const GLcontext
*ctx
,
973 struct gl_renderbuffer
*rb
,
974 GLuint n
, const GLint x
[], const GLint y
[],
975 const GLubyte rgba
[][4],
976 const GLubyte mask
[])
979 WMesaContext pwc
= wmesa_context(ctx
);
980 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
983 WMSETPIXEL24(pwfb
, FLIP(y
[i
]), x
[i
],
984 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
988 * Write an array of pixels with a boolean mask. The current color
989 * is used for all pixels.
991 static void write_mono_rgba_pixels_24(const GLcontext
*ctx
,
992 struct gl_renderbuffer
*rb
,
994 const GLint x
[], const GLint y
[],
995 const GLchan color
[4],
996 const GLubyte mask
[])
999 WMesaContext pwc
= wmesa_context(ctx
);
1000 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1003 WMSETPIXEL24(pwfb
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
1004 color
[GCOMP
], color
[BCOMP
]);
1007 /* Read a horizontal span of color pixels. */
1008 static void read_rgba_span_24(const GLcontext
*ctx
,
1009 struct gl_renderbuffer
*rb
,
1010 GLuint n
, GLint x
, GLint y
,
1015 WMesaContext pwc
= wmesa_context(ctx
);
1016 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1019 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + (3 * x
);
1020 for (i
=0; i
<n
; i
++) {
1021 rgba
[i
][RCOMP
] = lpb
[3*i
+2];
1022 rgba
[i
][GCOMP
] = lpb
[3*i
+1];
1023 rgba
[i
][BCOMP
] = lpb
[3*i
];
1024 rgba
[i
][ACOMP
] = 255;
1029 /* Read an array of color pixels. */
1030 static void read_rgba_pixels_24(const GLcontext
*ctx
,
1031 struct gl_renderbuffer
*rb
,
1032 GLuint n
, const GLint x
[], const GLint y
[],
1037 WMesaContext pwc
= wmesa_context(ctx
);
1038 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1040 for (i
=0; i
<n
; i
++) {
1041 GLint y2
= FLIP(y
[i
]);
1042 lpb
= ((LPBYTE
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y2
)) + (3 * x
[i
]);
1043 rgba
[i
][RCOMP
] = lpb
[3*i
+2];
1044 rgba
[i
][GCOMP
] = lpb
[3*i
+1];
1045 rgba
[i
][BCOMP
] = lpb
[3*i
];
1046 rgba
[i
][ACOMP
] = 255;
1051 /*********************************************************************/
1053 /* DOUBLE BUFFER 16-bit */
1055 #define WMSETPIXEL16(pwc, y, x, r, g, b) { \
1056 LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \
1057 *lpw = BGR16((r),(g),(b)); }
1061 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
1062 static void write_rgba_span_16(const GLcontext
*ctx
,
1063 struct gl_renderbuffer
*rb
,
1064 GLuint n
, GLint x
, GLint y
,
1065 const GLubyte rgba
[][4],
1066 const GLubyte mask
[] )
1068 WMesaContext pwc
= wmesa_context(ctx
);
1069 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1076 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1080 lpw
[i
] = BGR16(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
1085 *lpw
++ = BGR16(rgba
[i
][RCOMP
], rgba
[i
][GCOMP
],
1091 /* Write a horizontal span of RGB color pixels with a boolean mask. */
1092 static void write_rgb_span_16(const GLcontext
*ctx
,
1093 struct gl_renderbuffer
*rb
,
1094 GLuint n
, GLint x
, GLint y
,
1095 const GLubyte rgb
[][3],
1096 const GLubyte mask
[] )
1098 WMesaContext pwc
= wmesa_context(ctx
);
1099 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1106 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1110 lpw
[i
] = BGR16(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
1115 *lpw
++ = BGR16(rgb
[i
][RCOMP
], rgb
[i
][GCOMP
],
1121 * Write a horizontal span of pixels with a boolean mask. The current color
1122 * is used for all pixels.
1124 static void write_mono_rgba_span_16(const GLcontext
*ctx
,
1125 struct gl_renderbuffer
*rb
,
1126 GLuint n
, GLint x
, GLint y
,
1127 const GLchan color
[4],
1128 const GLubyte mask
[])
1133 WMesaContext pwc
= wmesa_context(ctx
);
1134 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1136 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1138 pixel
= BGR16(color
[RCOMP
], color
[GCOMP
], color
[BCOMP
]);
1150 /* Write an array of RGBA pixels with a boolean mask. */
1151 static void write_rgba_pixels_16(const GLcontext
*ctx
,
1152 struct gl_renderbuffer
*rb
,
1153 GLuint n
, const GLint x
[], const GLint y
[],
1154 const GLubyte rgba
[][4],
1155 const GLubyte mask
[])
1158 WMesaContext pwc
= wmesa_context(ctx
);
1159 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1163 WMSETPIXEL16(pwfb
, FLIP(y
[i
]), x
[i
],
1164 rgba
[i
][RCOMP
], rgba
[i
][GCOMP
], rgba
[i
][BCOMP
]);
1168 * Write an array of pixels with a boolean mask. The current color
1169 * is used for all pixels.
1171 static void write_mono_rgba_pixels_16(const GLcontext
*ctx
,
1172 struct gl_renderbuffer
*rb
,
1174 const GLint x
[], const GLint y
[],
1175 const GLchan color
[4],
1176 const GLubyte mask
[])
1179 WMesaContext pwc
= wmesa_context(ctx
);
1180 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1184 WMSETPIXEL16(pwfb
, FLIP(y
[i
]),x
[i
],color
[RCOMP
],
1185 color
[GCOMP
], color
[BCOMP
]);
1188 /* Read a horizontal span of color pixels. */
1189 static void read_rgba_span_16(const GLcontext
*ctx
,
1190 struct gl_renderbuffer
*rb
,
1191 GLuint n
, GLint x
, GLint y
,
1196 WMesaContext pwc
= wmesa_context(ctx
);
1197 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1200 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y
)) + x
;
1201 for (i
=0; i
<n
; i
++) {
1203 /* Windows uses 5,5,5 for 16-bit */
1204 rgba
[i
][RCOMP
] = (pixel
& 0x7c00) >> 7;
1205 rgba
[i
][GCOMP
] = (pixel
& 0x03e0) >> 2;
1206 rgba
[i
][BCOMP
] = (pixel
& 0x001f) << 3;
1207 rgba
[i
][ACOMP
] = 255;
1212 /* Read an array of color pixels. */
1213 static void read_rgba_pixels_16(const GLcontext
*ctx
,
1214 struct gl_renderbuffer
*rb
,
1215 GLuint n
, const GLint x
[], const GLint y
[],
1220 WMesaContext pwc
= wmesa_context(ctx
);
1221 WMesaFramebuffer pwfb
= wmesa_framebuffer(ctx
->DrawBuffer
);
1223 for (i
=0; i
<n
; i
++) {
1224 GLint y2
= FLIP(y
[i
]);
1225 lpw
= ((LPWORD
)(pwfb
->pbPixels
+ pwfb
->ScanWidth
* y2
)) + x
[i
];
1227 /* Windows uses 5,5,5 for 16-bit */
1228 rgba
[i
][RCOMP
] = (pixel
& 0x7c00) >> 7;
1229 rgba
[i
][GCOMP
] = (pixel
& 0x03e0) >> 2;
1230 rgba
[i
][BCOMP
] = (pixel
& 0x001f) << 3;
1231 rgba
[i
][ACOMP
] = 255;
1238 /**********************************************************************/
1239 /***** BUFFER Functions *****/
1240 /**********************************************************************/
1246 wmesa_delete_renderbuffer(struct gl_renderbuffer
*rb
)
1253 * This is called by Mesa whenever it determines that the window size
1254 * has changed. Do whatever's needed to cope with that.
1257 wmesa_renderbuffer_storage(GLcontext
*ctx
,
1258 struct gl_renderbuffer
*rb
,
1259 GLenum internalFormat
,
1264 rb
->Height
= height
;
1270 * Plug in the Get/PutRow/Values functions for a renderbuffer depending
1271 * on if we're drawing to the front or back color buffer.
1273 void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer
*rb
, int pixelformat
,
1274 BYTE cColorBits
, int double_buffer
)
1276 if (double_buffer
) {
1278 /* Picking the correct span functions is important because
1279 * the DIB was allocated with the indicated depth. */
1280 switch(pixelformat
) {
1282 rb
->PutRow
= write_rgba_span_16
;
1283 rb
->PutRowRGB
= write_rgb_span_16
;
1284 rb
->PutMonoRow
= write_mono_rgba_span_16
;
1285 rb
->PutValues
= write_rgba_pixels_16
;
1286 rb
->PutMonoValues
= write_mono_rgba_pixels_16
;
1287 rb
->GetRow
= read_rgba_span_16
;
1288 rb
->GetValues
= read_rgba_pixels_16
;
1294 if (cColorBits
== 24)
1296 rb
->PutRow
= write_rgba_span_24
;
1297 rb
->PutRowRGB
= write_rgb_span_24
;
1298 rb
->PutMonoRow
= write_mono_rgba_span_24
;
1299 rb
->PutValues
= write_rgba_pixels_24
;
1300 rb
->PutMonoValues
= write_mono_rgba_pixels_24
;
1301 rb
->GetRow
= read_rgba_span_24
;
1302 rb
->GetValues
= read_rgba_pixels_24
;
1309 rb
->PutRow
= write_rgba_span_32
;
1310 rb
->PutRowRGB
= write_rgb_span_32
;
1311 rb
->PutMonoRow
= write_mono_rgba_span_32
;
1312 rb
->PutValues
= write_rgba_pixels_32
;
1313 rb
->PutMonoValues
= write_mono_rgba_pixels_32
;
1314 rb
->GetRow
= read_rgba_span_32
;
1315 rb
->GetValues
= read_rgba_pixels_32
;
1326 /* front buffer (actual Windows window) */
1327 rb
->PutRow
= write_rgba_span_front
;
1328 rb
->PutRowRGB
= write_rgb_span_front
;
1329 rb
->PutMonoRow
= write_mono_rgba_span_front
;
1330 rb
->PutValues
= write_rgba_pixels_front
;
1331 rb
->PutMonoValues
= write_mono_rgba_pixels_front
;
1332 rb
->GetRow
= read_rgba_span_front
;
1333 rb
->GetValues
= read_rgba_pixels_front
;
1334 rb
->RedBits
= 8; /* XXX fix these (565?) */
1341 * Called by ctx->Driver.ResizeBuffers()
1342 * Resize the front/back colorbuffers to match the latest window size.
1345 wmesa_resize_buffers(GLcontext
*ctx
, GLframebuffer
*buffer
,
1346 GLuint width
, GLuint height
)
1348 WMesaContext pwc
= wmesa_context(ctx
);
1349 WMesaFramebuffer pwfb
= wmesa_framebuffer(buffer
);
1351 if (pwfb
->Base
.Width
!= width
|| pwfb
->Base
.Height
!= height
) {
1352 /* Realloc back buffer */
1353 if (ctx
->Visual
.doubleBufferMode
== 1) {
1354 wmDeleteBackingStore(pwfb
);
1355 wmCreateBackingStore(pwfb
, width
, height
);
1358 _mesa_resize_framebuffer(ctx
, buffer
, width
, height
);
1363 * Called by glViewport.
1364 * This is a good time for us to poll the current window size and adjust
1365 * our renderbuffers to match the current window size.
1366 * Remember, we have no opportunity to respond to conventional
1367 * resize events since the driver has no event loop.
1369 * MakeCurrent also ends up making a call here, so that ensures
1370 * we get the viewport set correctly, even if the app does not call
1371 * glViewport and relies on the defaults.
1373 static void wmesa_viewport(GLcontext
*ctx
,
1375 GLsizei width
, GLsizei height
)
1377 WMesaContext pwc
= wmesa_context(ctx
);
1378 GLuint new_width
, new_height
;
1380 wmesa_get_buffer_size(ctx
->WinSysDrawBuffer
, &new_width
, &new_height
);
1383 * Resize buffers if the window size changed.
1385 wmesa_resize_buffers(ctx
, ctx
->WinSysDrawBuffer
, new_width
, new_height
);
1386 ctx
->NewState
|= _NEW_BUFFERS
; /* to update scissor / window bounds */
1393 * Called when the driver should update it's state, based on the new_state
1396 static void wmesa_update_state(GLcontext
*ctx
, GLuint new_state
)
1398 _swrast_InvalidateState(ctx
, new_state
);
1399 _swsetup_InvalidateState(ctx
, new_state
);
1400 _vbo_InvalidateState(ctx
, new_state
);
1401 _tnl_InvalidateState(ctx
, new_state
);
1403 /* TODO - This code is not complete yet because I
1404 * don't know what to do for all state updates.
1407 if (new_state
& _NEW_BUFFERS
) {
1415 /**********************************************************************/
1416 /***** WMESA Functions *****/
1417 /**********************************************************************/
1419 WMesaContext
WMesaCreateContext(HDC hDC
,
1423 GLboolean alpha_flag
)
1426 struct dd_function_table functions
;
1427 GLint red_bits
, green_bits
, blue_bits
, alpha_bits
;
1433 /* Indexed mode not supported */
1437 /* Allocate wmesa context */
1438 c
= CALLOC_STRUCT(wmesa_context
);
1443 /* I do not understand this contributed code */
1444 /* Support memory and device contexts */
1445 if(WindowFromDC(hDC
) != NULL
) {
1446 c
->hDC
= GetDC(WindowFromDC(hDC
)); /* huh ???? */
1455 /* Get data for visual */
1456 /* Dealing with this is actually a bit of overkill because Mesa will end
1457 * up treating all color component size requests less than 8 by using
1458 * a single byte per channel. In addition, the interface to the span
1459 * routines passes colors as an entire byte per channel anyway, so there
1460 * is nothing to be saved by telling the visual to be 16 bits if the device
1461 * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per
1463 * But we go through the motions here anyway.
1465 switch (GetDeviceCaps(c
->hDC
, BITSPIXEL
)) {
1467 red_bits
= green_bits
= blue_bits
= 5;
1471 red_bits
= green_bits
= blue_bits
= 8;
1475 /* Create visual based on flags */
1476 visual
= _mesa_create_visual(rgb_flag
,
1477 db_flag
, /* db_flag */
1478 GL_FALSE
, /* stereo */
1479 red_bits
, green_bits
, blue_bits
, /* color RGB */
1480 alpha_flag
? alpha_bits
: 0, /* color A */
1482 DEFAULT_SOFTWARE_DEPTH_BITS
, /* depth_bits */
1483 8, /* stencil_bits */
1484 16,16,16, /* accum RGB */
1485 alpha_flag
? 16 : 0, /* accum A */
1486 1); /* num samples */
1493 /* Set up driver functions */
1494 _mesa_init_driver_functions(&functions
);
1495 functions
.GetString
= wmesa_get_string
;
1496 functions
.UpdateState
= wmesa_update_state
;
1497 functions
.GetBufferSize
= wmesa_get_buffer_size
;
1498 functions
.Flush
= wmesa_flush
;
1499 functions
.Clear
= clear
;
1500 functions
.ClearIndex
= clear_index
;
1501 functions
.ClearColor
= clear_color
;
1502 functions
.ResizeBuffers
= wmesa_resize_buffers
;
1503 functions
.Viewport
= wmesa_viewport
;
1505 /* initialize the Mesa context data */
1507 _mesa_initialize_context(ctx
, visual
, NULL
, &functions
, (void *)c
);
1509 /* visual no longer needed - it was copied by _mesa_initialize_context() */
1510 _mesa_destroy_visual(visual
);
1512 _mesa_enable_sw_extensions(ctx
);
1513 _mesa_enable_1_3_extensions(ctx
);
1514 _mesa_enable_1_4_extensions(ctx
);
1515 _mesa_enable_1_5_extensions(ctx
);
1516 _mesa_enable_2_0_extensions(ctx
);
1517 _mesa_enable_2_1_extensions(ctx
);
1519 _mesa_meta_init(ctx
);
1521 /* Initialize the software rasterizer and helper modules. */
1522 if (!_swrast_CreateContext(ctx
) ||
1523 !_vbo_CreateContext(ctx
) ||
1524 !_tnl_CreateContext(ctx
) ||
1525 !_swsetup_CreateContext(ctx
)) {
1526 _mesa_free_context_data(ctx
);
1530 _swsetup_Wakeup(ctx
);
1531 TNL_CONTEXT(ctx
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
1537 void WMesaDestroyContext( WMesaContext pwc
)
1539 GLcontext
*ctx
= &pwc
->gl_ctx
;
1540 WMesaFramebuffer pwfb
;
1541 GET_CURRENT_CONTEXT(cur_ctx
);
1543 if (cur_ctx
== ctx
) {
1544 /* unbind current if deleting current context */
1545 WMesaMakeCurrent(NULL
, NULL
);
1548 /* clean up frame buffer resources */
1549 pwfb
= wmesa_lookup_framebuffer(pwc
->hDC
);
1551 if (ctx
->Visual
.doubleBufferMode
== 1)
1552 wmDeleteBackingStore(pwfb
);
1553 wmesa_free_framebuffer(pwc
->hDC
);
1556 /* Release for device, not memory contexts */
1557 if (WindowFromDC(pwc
->hDC
) != NULL
)
1559 ReleaseDC(WindowFromDC(pwc
->hDC
), pwc
->hDC
);
1561 DeleteObject(pwc
->clearPen
);
1562 DeleteObject(pwc
->clearBrush
);
1564 _mesa_meta_free(ctx
);
1566 _swsetup_DestroyContext(ctx
);
1567 _tnl_DestroyContext(ctx
);
1568 _vbo_DestroyContext(ctx
);
1569 _swrast_DestroyContext(ctx
);
1571 _mesa_free_context_data(ctx
);
1577 * Create a new color renderbuffer.
1579 struct gl_renderbuffer
*
1580 wmesa_new_renderbuffer(void)
1582 struct gl_renderbuffer
*rb
= CALLOC_STRUCT(gl_renderbuffer
);
1586 _mesa_init_renderbuffer(rb
, (GLuint
)0);
1588 rb
->_BaseFormat
= GL_RGBA
;
1589 rb
->InternalFormat
= GL_RGBA
;
1590 rb
->DataType
= CHAN_TYPE
;
1591 rb
->Delete
= wmesa_delete_renderbuffer
;
1592 rb
->AllocStorage
= wmesa_renderbuffer_storage
;
1597 void WMesaMakeCurrent(WMesaContext c
, HDC hdc
)
1599 WMesaFramebuffer pwfb
;
1602 /* return if already current */
1603 GET_CURRENT_CONTEXT(ctx
);
1604 WMesaContext pwc
= wmesa_context(ctx
);
1605 if (pwc
&& c
== pwc
&& pwc
->hDC
== hdc
)
1609 pwfb
= wmesa_lookup_framebuffer(hdc
);
1611 /* Lazy creation of framebuffers */
1612 if (c
&& !pwfb
&& hdc
) {
1613 struct gl_renderbuffer
*rb
;
1614 GLvisual
*visual
= &c
->gl_ctx
.Visual
;
1615 GLuint width
, height
;
1617 get_window_size(hdc
, &width
, &height
);
1619 c
->clearPen
= CreatePen(PS_SOLID
, 1, 0);
1620 c
->clearBrush
= CreateSolidBrush(0);
1622 pwfb
= wmesa_new_framebuffer(hdc
, visual
);
1624 /* Create back buffer if double buffered */
1625 if (visual
->doubleBufferMode
== 1) {
1626 wmCreateBackingStore(pwfb
, width
, height
);
1629 /* make render buffers */
1630 if (visual
->doubleBufferMode
== 1) {
1631 rb
= wmesa_new_renderbuffer();
1632 _mesa_add_renderbuffer(&pwfb
->Base
, BUFFER_BACK_LEFT
, rb
);
1633 wmesa_set_renderbuffer_funcs(rb
, pwfb
->pixelformat
, pwfb
->cColorBits
, 1);
1635 rb
= wmesa_new_renderbuffer();
1636 _mesa_add_renderbuffer(&pwfb
->Base
, BUFFER_FRONT_LEFT
, rb
);
1637 wmesa_set_renderbuffer_funcs(rb
, pwfb
->pixelformat
, pwfb
->cColorBits
, 0);
1639 /* Let Mesa own the Depth, Stencil, and Accum buffers */
1640 _mesa_add_soft_renderbuffers(&pwfb
->Base
,
1641 GL_FALSE
, /* color */
1642 visual
->depthBits
> 0,
1643 visual
->stencilBits
> 0,
1644 visual
->accumRedBits
> 0,
1645 visual
->alphaBits
>0,
1650 _mesa_make_current(&c
->gl_ctx
, &pwfb
->Base
, &pwfb
->Base
);
1652 _mesa_make_current(NULL
, NULL
, NULL
);
1656 void WMesaSwapBuffers( HDC hdc
)
1658 GET_CURRENT_CONTEXT(ctx
);
1659 WMesaContext pwc
= wmesa_context(ctx
);
1660 WMesaFramebuffer pwfb
= wmesa_lookup_framebuffer(hdc
);
1663 _mesa_problem(NULL
, "wmesa: swapbuffers on unknown hdc");
1667 /* If we're swapping the buffer associated with the current context
1668 * we have to flush any pending rendering commands first.
1670 if (pwc
->hDC
== hdc
) {
1671 _mesa_notifySwapBuffers(ctx
);
1673 BitBlt(pwfb
->hDC
, 0, 0, pwfb
->Base
.Width
, pwfb
->Base
.Height
,
1674 pwfb
->dib_hDC
, 0, 0, SRCCOPY
);
1677 /* XXX for now only allow swapping current window */
1678 _mesa_problem(NULL
, "wmesa: can't swap non-current window");
1682 void WMesaShareLists(WMesaContext ctx_to_share
, WMesaContext ctx
)
1684 _mesa_share_state(&ctx
->gl_ctx
, &ctx_to_share
->gl_ctx
);