Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / windows / gldirect / mesasw / gld_wgl_mesasw.c
1 /****************************************************************************
2 *
3 * Mesa 3-D graphics library
4 * Direct3D Driver Interface
5 *
6 * ========================================================================
7 *
8 * Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 * ======================================================================
29 *
30 * Language: ANSI C
31 * Environment: Windows 9x/2000/XP/XBox (Win32)
32 *
33 * Description: Mesa Software WGL (WindowsGL)
34 *
35 ****************************************************************************/
36
37 #include <windows.h>
38 #define GL_GLEXT_PROTOTYPES
39 #include <GL/gl.h>
40 #include <GL/glext.h>
41
42 #include "glheader.h"
43 #include "colors.h"
44 #include "context.h"
45 #include "colormac.h"
46 #include "dd.h"
47 #include "depth.h"
48 #include "extensions.h"
49 #include "macros.h"
50 #include "matrix.h"
51 // #include "mem.h"
52 //#include "mmath.h"
53 #include "mtypes.h"
54 #include "texformat.h"
55 #include "texstore.h"
56 #include "teximage.h"
57 #include "vbo/vbo.h"
58 #include "swrast/swrast.h"
59 #include "swrast_setup/swrast_setup.h"
60 #include "swrast/s_context.h"
61 #include "swrast/s_depth.h"
62 #include "swrast/s_lines.h"
63 #include "swrast/s_triangle.h"
64 #include "swrast/s_trispan.h"
65 #include "tnl/tnl.h"
66 #include "tnl/t_context.h"
67 #include "tnl/t_pipeline.h"
68
69 #include "dglcontext.h"
70 #include "gld_driver.h"
71
72 //---------------------------------------------------------------------------
73 //---------------------------------------------------------------------------
74
75 DGL_pixelFormat pfTemplateMesaSW =
76 {
77 {
78 sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure
79 1, // Structure version - should be 1
80 // Flags:
81 PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface.
82 PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM)
83 PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM)
84 PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing.
85 PFD_DOUBLEBUFFER | // The buffer is double-buffered.
86 0, // Placeholder for easy commenting of above flags
87 PFD_TYPE_RGBA, // Pixel type RGBA.
88 32, // Total colour bitplanes (excluding alpha bitplanes)
89 8, 0, // Red bits, shift
90 8, 8, // Green bits, shift
91 8, 16, // Blue bits, shift
92 8, 24, // Alpha bits, shift (destination alpha)
93 64, // Accumulator bits (total)
94 16, 16, 16, 16, // Accumulator bits: Red, Green, Blue, Alpha
95 16, // Depth bits
96 8, // Stencil bits
97 0, // Number of auxiliary buffers
98 0, // Layer type
99 0, // Specifies the number of overlay and underlay planes.
100 0, // Layer mask
101 0, // Specifies the transparent color or index of an underlay plane.
102 0 // Damage mask
103 },
104 0, // Unused
105 };
106
107 //---------------------------------------------------------------------------
108 // Extensions
109 //---------------------------------------------------------------------------
110
111 typedef struct {
112 PROC proc;
113 char *name;
114 } GLD_extension;
115
116 static GLD_extension GLD_extList[] = {
117 #ifdef GL_EXT_polygon_offset
118 { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" },
119 #endif
120 { (PROC)glBlendEquationEXT, "glBlendEquationEXT" },
121 { (PROC)glBlendColorEXT, "glBlendColorExt" },
122 { (PROC)glVertexPointerEXT, "glVertexPointerEXT" },
123 { (PROC)glNormalPointerEXT, "glNormalPointerEXT" },
124 { (PROC)glColorPointerEXT, "glColorPointerEXT" },
125 { (PROC)glIndexPointerEXT, "glIndexPointerEXT" },
126 { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" },
127 { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" },
128 { (PROC)glGetPointervEXT, "glGetPointervEXT" },
129 { (PROC)glArrayElementEXT, "glArrayElementEXT" },
130 { (PROC)glDrawArraysEXT, "glDrawArrayEXT" },
131 { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" },
132 { (PROC)glBindTextureEXT, "glBindTextureEXT" },
133 { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" },
134 { (PROC)glGenTexturesEXT, "glGenTexturesEXT" },
135 { (PROC)glIsTextureEXT, "glIsTextureEXT" },
136 { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" },
137 { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" },
138 { (PROC)glTexImage3DEXT, "glTexImage3DEXT" },
139 { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" },
140 { (PROC)glPointParameterfEXT, "glPointParameterfEXT" },
141 { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" },
142 { (PROC)glLockArraysEXT, "glLockArraysEXT" },
143 { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" },
144 { NULL, "\0" }
145 };
146
147 //---------------------------------------------------------------------------
148 // WMesa Internal Functions
149 //---------------------------------------------------------------------------
150
151 #define PAGE_FILE 0xffffffff
152
153 #define REDBITS 0x03
154 #define REDSHIFT 0x00
155 #define GREENBITS 0x03
156 #define GREENSHIFT 0x03
157 #define BLUEBITS 0x02
158 #define BLUESHIFT 0x06
159
160 typedef struct _dibSection {
161 HDC hDC;
162 HANDLE hFileMap;
163 BOOL fFlushed;
164 LPVOID base;
165 } WMDIBSECTION, *PWMDIBSECTION;
166
167 typedef struct wmesa_context {
168 HWND Window;
169 HDC hDC;
170 HPALETTE hPalette;
171 HPALETTE hOldPalette;
172 HPEN hPen;
173 HPEN hOldPen;
174 HCURSOR hOldCursor;
175 COLORREF crColor;
176 // 3D projection stuff
177 RECT drawRect;
178 UINT uiDIBoffset;
179 // OpenGL stuff
180 HPALETTE hGLPalette;
181 GLuint width;
182 GLuint height;
183 GLuint ScanWidth;
184 GLboolean db_flag; //* double buffered?
185 GLboolean rgb_flag; //* RGB mode?
186 GLboolean dither_flag; //* use dither when 256 color mode for RGB?
187 GLuint depth; //* bits per pixel (1, 8, 24, etc)
188 ULONG pixel; // current color index or RGBA pixel value
189 ULONG clearpixel; //* pixel for clearing the color buffers
190 PBYTE ScreenMem; // WinG memory
191 BITMAPINFO *IndexFormat;
192 HPALETTE hPal; // Current Palette
193 HPALETTE hPalHalfTone;
194
195
196 WMDIBSECTION dib;
197 BITMAPINFO bmi;
198 HBITMAP hbmDIB;
199 HBITMAP hOldBitmap;
200 HBITMAP Old_Compat_BM;
201 HBITMAP Compat_BM; // Bitmap for double buffering
202 PBYTE pbPixels;
203 int nColors;
204 BYTE cColorBits;
205 int pixelformat;
206
207 RECT rectOffScreen;
208 RECT rectSurface;
209 // HWND hwnd;
210 DWORD pitch;
211 PBYTE addrOffScreen;
212
213 // We always double-buffer, for performance reasons, but
214 // we need to know which of SwapBuffers() or glFlush() to
215 // handle. If we're emulating, then we update on Flush(),
216 // otherwise we update on SwapBufers(). KeithH
217 BOOL bEmulateSingleBuffer;
218 } WMesaContext, *PWMC;
219
220 #define GLD_GET_WMESA_DRIVER(c) (WMesaContext*)(c)->glPriv
221
222 // TODO:
223 GLint stereo_flag = 0 ;
224
225 /* If we are double-buffering, we want to get the DC for the
226 * off-screen DIB, otherwise the DC for the window.
227 */
228 #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
229 #define DD_RELEASEDC
230
231 #define FLIP(Y) (Current->height-(Y)-1)
232
233 struct DISPLAY_OPTIONS {
234 int stereo;
235 int fullScreen;
236 int mode;
237 int bpp;
238 };
239
240 struct DISPLAY_OPTIONS displayOptions;
241
242 //---------------------------------------------------------------------------
243
244 static unsigned char threeto8[8] = {
245 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
246 };
247
248 static unsigned char twoto8[4] = {
249 0, 0x55, 0xaa, 0xff
250 };
251
252 static unsigned char oneto8[2] = {
253 0, 255
254 };
255
256 //---------------------------------------------------------------------------
257
258 BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline)
259 {
260 char unsigned redtemp, greentemp, bluetemp, paletteindex;
261
262 //*** now, look up each value in the halftone matrix
263 //*** using an 8x8 ordered dither.
264 redtemp = aDividedBy51[red]
265 + (aModulo51[red] > aHalftone8x8[(pixel%8)*8
266 + scanline%8]);
267 greentemp = aDividedBy51[(char unsigned)green]
268 + (aModulo51[green] > aHalftone8x8[
269 (pixel%8)*8 + scanline%8]);
270 bluetemp = aDividedBy51[(char unsigned)blue]
271 + (aModulo51[blue] > aHalftone8x8[
272 (pixel%8)*8 +scanline%8]);
273
274 //*** recombine the halftoned rgb values into a palette index
275 paletteindex =
276 redtemp + aTimes6[greentemp] + aTimes36[bluetemp];
277
278 //*** and translate through the wing halftone palette
279 //*** translation vector to give the correct value.
280 return aWinGHalftoneTranslation[paletteindex];
281 }
282
283 //---------------------------------------------------------------------------
284
285 static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
286 {
287 unsigned char val;
288
289 val = i >> shift;
290 switch (nbits) {
291
292 case 1:
293 val &= 0x1;
294 return oneto8[val];
295
296 case 2:
297 val &= 0x3;
298 return twoto8[val];
299
300 case 3:
301 val &= 0x7;
302 return threeto8[val];
303
304 default:
305 return 0;
306 }
307 }
308
309 //---------------------------------------------------------------------------
310
311
312 void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
313 {
314 WMesaContext *Current = pwc;
315
316 // Test for invalid scanline parameter. KeithH
317 if ((iScanLine < 0) || (iScanLine >= pwc->height))
318 return;
319
320 if (Current->db_flag) {
321 LPBYTE lpb = pwc->pbPixels;
322 UINT nBypp = pwc->cColorBits >> 3;
323 UINT nOffset = iPixel % nBypp;
324
325 lpb += pwc->ScanWidth * iScanLine;
326 lpb += iPixel * nBypp;
327
328 if(nBypp == 1){
329 if(pwc->dither_flag)
330 *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel);
331 else
332 *lpb = BGR8(r,g,b);
333 }
334 else if(nBypp == 2)
335 *((LPWORD)lpb) = BGR16(r,g,b);
336 else if (nBypp == 3)
337 *((LPDWORD)lpb) = BGR24(r,g,b);
338 else if (nBypp == 4)
339 *((LPDWORD)lpb) = BGR32(r,g,b);
340 }
341 else{
342 SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b));
343 }
344 }
345
346 //---------------------------------------------------------------------------
347
348 void wmCreateDIBSection(
349 HDC hDC,
350 PWMC pwc, // handle of device context
351 CONST BITMAPINFO *pbmi, // bitmap size, format, and color data
352 UINT iUsage // color data type indicator: RGB values or palette indices
353 )
354 {
355 DWORD dwSize = 0;
356 DWORD dwScanWidth;
357 UINT nBypp = pwc->cColorBits / 8;
358 HDC hic;
359
360 dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
361
362 pwc->ScanWidth =pwc->pitch = dwScanWidth;
363
364 if (stereo_flag)
365 pwc->ScanWidth = 2* pwc->pitch;
366
367 dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
368
369 pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
370 NULL,
371 PAGE_READWRITE | SEC_COMMIT,
372 0,
373 dwSize,
374 NULL);
375
376 if (!pwc->dib.hFileMap)
377 return;
378
379 pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
380 FILE_MAP_ALL_ACCESS,
381 0,
382 0,
383 0);
384
385 if(!pwc->dib.base){
386 CloseHandle(pwc->dib.hFileMap);
387 return;
388 }
389
390
391 CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
392
393 hic = CreateIC("display", NULL, NULL, NULL);
394 pwc->dib.hDC = CreateCompatibleDC(hic);
395
396
397 pwc->hbmDIB = CreateDIBSection(hic,
398 &(pwc->bmi),
399 (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS),
400 &(pwc->pbPixels),
401 pwc->dib.hFileMap,
402 0);
403 pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels;
404 pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
405
406 DeleteDC(hic);
407
408 return;
409
410 }
411
412 //---------------------------------------------------------------------------
413
414 void wmCreatePalette( PWMC pwdc )
415 {
416 /* Create a compressed and re-expanded 3:3:2 palette */
417 int i;
418 LOGPALETTE *pPal;
419 BYTE rb, rs, gb, gs, bb, bs;
420
421 pwdc->nColors = 0x100;
422
423 pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) +
424 pwdc->nColors * sizeof(PALETTEENTRY));
425 memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
426
427 pPal->palVersion = 0x300;
428
429 rb = REDBITS;
430 rs = REDSHIFT;
431 gb = GREENBITS;
432 gs = GREENSHIFT;
433 bb = BLUEBITS;
434 bs = BLUESHIFT;
435
436 if (pwdc->db_flag) {
437
438 /* Need to make two palettes: one for the screen DC and one for the DIB. */
439 pPal->palNumEntries = pwdc->nColors;
440 for (i = 0; i < pwdc->nColors; i++) {
441 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
442 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
443 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
444 pPal->palPalEntry[i].peFlags = 0;
445 }
446 pwdc->hGLPalette = CreatePalette( pPal );
447 pwdc->hPalette = CreatePalette( pPal );
448 }
449
450 else {
451 pPal->palNumEntries = pwdc->nColors;
452 for (i = 0; i < pwdc->nColors; i++) {
453 pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
454 pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
455 pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
456 pPal->palPalEntry[i].peFlags = 0;
457 }
458 pwdc->hGLPalette = CreatePalette( pPal );
459 }
460
461 free(pPal);
462
463 }
464
465 //---------------------------------------------------------------------------
466
467 /* This function sets the color table of a DIB section
468 * to match that of the destination DC
469 */
470 BOOL wmSetDibColors(PWMC pwc)
471 {
472 RGBQUAD *pColTab, *pRGB;
473 PALETTEENTRY *pPal, *pPE;
474 int i, nColors;
475 BOOL bRet=TRUE;
476 DWORD dwErr=0;
477
478 /* Build a color table in the DIB that maps to the
479 * selected palette in the DC.
480 */
481 nColors = 1 << pwc->cColorBits;
482 pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
483 memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
484 GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
485 pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
486 for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
487 pRGB->rgbRed = pPE->peRed;
488 pRGB->rgbGreen = pPE->peGreen;
489 pRGB->rgbBlue = pPE->peBlue;
490 }
491 if(pwc->db_flag)
492 bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab );
493
494 if(!bRet)
495 dwErr = GetLastError();
496
497 free( pColTab );
498 free( pPal );
499
500 return bRet;
501 }
502
503 //---------------------------------------------------------------------------
504
505 static void wmSetPixelFormat( PWMC wc, HDC hDC)
506 {
507 if(wc->rgb_flag)
508 wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);
509 else
510 wc->cColorBits = 8;
511 switch(wc->cColorBits){
512 case 8:
513 if(wc->dither_flag != GL_TRUE)
514 wc->pixelformat = PF_INDEX8;
515 else
516 wc->pixelformat = PF_DITHER8;
517 break;
518 case 16:
519 wc->pixelformat = PF_5R6G5B;
520 break;
521 case 32:
522 wc->pixelformat = PF_8R8G8B;
523 break;
524 default:
525 wc->pixelformat = PF_BADFORMAT;
526 }
527 }
528
529 //---------------------------------------------------------------------------
530
531 /*
532 * This function creates the DIB section that is used for combined
533 * GL and GDI calls
534 */
535 BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
536 {
537 HDC hdc = pwc->hDC;
538 LPBITMAPINFO pbmi = &(pwc->bmi);
539 int iUsage;
540
541 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
542 pbmi->bmiHeader.biWidth = lxSize;
543 pbmi->bmiHeader.biHeight= -lySize;
544 pbmi->bmiHeader.biPlanes = 1;
545 if(pwc->rgb_flag)
546 pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
547 else
548 pbmi->bmiHeader.biBitCount = 8;
549 pbmi->bmiHeader.biCompression = BI_RGB;
550 pbmi->bmiHeader.biSizeImage = 0;
551 pbmi->bmiHeader.biXPelsPerMeter = 0;
552 pbmi->bmiHeader.biYPelsPerMeter = 0;
553 pbmi->bmiHeader.biClrUsed = 0;
554 pbmi->bmiHeader.biClrImportant = 0;
555
556 iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
557
558 pwc->cColorBits = pbmi->bmiHeader.biBitCount;
559 pwc->ScanWidth = pwc->pitch = lxSize;
560 pwc->width = lxSize;
561 pwc->height = lySize;
562
563 wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
564
565 if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
566 wmCreatePalette( pwc );
567 wmSetDibColors( pwc );
568 }
569 wmSetPixelFormat(pwc, pwc->hDC);
570 return TRUE;
571 }
572
573 //---------------------------------------------------------------------------
574
575 /*
576 * Free up the dib section that was created
577 */
578 BOOL wmDeleteBackingStore(PWMC pwc)
579 {
580 SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
581 DeleteDC(pwc->dib.hDC);
582 DeleteObject(pwc->hbmDIB);
583 UnmapViewOfFile(pwc->dib.base);
584 CloseHandle(pwc->dib.hFileMap);
585 return TRUE;
586 }
587
588 //---------------------------------------------------------------------------
589
590 /*
591 * Blit memory DC to screen DC
592 */
593 BOOL wmFlush(PWMC pwc, HDC hDC)
594 {
595 BOOL bRet = 0;
596 DWORD dwErr = 0;
597
598 // Now using bEmulateSingleBuffer in the calling function. KeithH
599
600 // if(pwc->db_flag){
601 bRet = BitBlt(hDC, 0, 0, pwc->width, pwc->height,
602 pwc->dib.hDC, 0, 0, SRCCOPY);
603 // }
604
605 return bRet;
606
607 }
608
609 //---------------------------------------------------------------------------
610 // Support Functions
611 //---------------------------------------------------------------------------
612
613 static void flush(struct gl_context* ctx)
614 {
615 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
616 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
617 /*
618 if((Current->rgb_flag &&!(Current->db_flag))
619 ||(!Current->rgb_flag))
620 {
621 wmFlush(Current, Current->hDC);
622 }
623 */
624 // Only flush if we're not in double-buffer mode. KeithH
625 // The demo fractal.c calls glutSwapBuffers() then glFlush()!
626 if (Current->bEmulateSingleBuffer) {
627 wmFlush(Current, Current->hDC);
628 }
629 }
630
631
632 //---------------------------------------------------------------------------
633
634 /*
635 * Set the color used to clear the color buffer.
636 */
637 //static void clear_color( struct gl_context* ctx, const GLchan color[4] )
638 // Changed for Mesa 5.x. KeithH
639 static void clear_color(
640 struct gl_context* ctx,
641 const GLfloat color[4])
642 {
643 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
644 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
645 GLubyte col[4];
646 CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
647 CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
648 CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
649 Current->clearpixel = RGB(col[0], col[1], col[2]);
650 }
651
652
653 //---------------------------------------------------------------------------
654
655
656 /*
657 * Clear the specified region of the color buffer using the clear color
658 * or index as specified by one of the two functions above.
659 *
660 * This procedure clears either the front and/or the back COLOR buffers.
661 * Only the "left" buffer is cleared since we are not stereo.
662 * Clearing of the other non-color buffers is left to the swrast.
663 * We also only clear the color buffers if the color masks are all 1's.
664 * Otherwise, we let swrast do it.
665 */
666
667 static clear(struct gl_context* ctx, GLbitfield mask,
668 GLboolean all, GLint x, GLint y, GLint width, GLint height)
669 {
670 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
671 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
672 DWORD dwColor;
673 WORD wColor;
674 BYTE bColor;
675 LPDWORD lpdw = (LPDWORD)Current->pbPixels;
676 LPWORD lpw = (LPWORD)Current->pbPixels;
677 LPBYTE lpb = Current->pbPixels;
678 int lines;
679 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask;
680
681 if (all){
682 x=y=0;
683 width=Current->width;
684 height=Current->height;
685 }
686
687
688 /* sanity check - can't have right(stereo) buffers */
689 assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0);
690
691 /* clear alpha */
692 if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_RIGHT_BIT)) &&
693 ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
694 ctx->Color.ColorMask[ACOMP]) {
695 _swrast_clear_alpha_buffers( ctx );
696 }
697
698 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) {
699 if (mask & DD_BACK_LEFT_BIT) {
700 /* Double-buffering - clear back buffer */
701 UINT nBypp = Current->cColorBits / 8;
702 int i = 0;
703 int iSize = 0;
704
705 assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */
706 if(nBypp ==1 ){
707 iSize = Current->width/4;
708 bColor = BGR8(GetRValue(Current->clearpixel),
709 GetGValue(Current->clearpixel),
710 GetBValue(Current->clearpixel));
711 wColor = MAKEWORD(bColor,bColor);
712 dwColor = MAKELONG(wColor, wColor);
713 }
714 if(nBypp == 2){
715 iSize = Current->width / 2;
716 wColor = BGR16(GetRValue(Current->clearpixel),
717 GetGValue(Current->clearpixel),
718 GetBValue(Current->clearpixel));
719 dwColor = MAKELONG(wColor, wColor);
720 }
721 else if(nBypp == 4){
722 iSize = Current->width;
723 dwColor = BGR32(GetRValue(Current->clearpixel),
724 GetGValue(Current->clearpixel),
725 GetBValue(Current->clearpixel));
726 }
727
728 /* clear a line */
729 while(i < iSize){
730 *lpdw = dwColor;
731 lpdw++;
732 i++;
733 }
734
735 /* This is the 24bit case */
736 if (nBypp == 3) {
737 iSize = Current->width *3/4;
738 dwColor = BGR24(GetRValue(Current->clearpixel),
739 GetGValue(Current->clearpixel),
740 GetBValue(Current->clearpixel));
741 while(i < iSize){
742 *lpdw = dwColor;
743 lpb += nBypp;
744 lpdw = (LPDWORD)lpb;
745 i++;
746 }
747 }
748
749 i = 0;
750 if (stereo_flag)
751 lines = height /2;
752 else
753 lines = height;
754 /* copy cleared line to other lines in buffer */
755 do {
756 memcpy(lpb, Current->pbPixels, iSize*4);
757 lpb += Current->ScanWidth;
758 i++;
759 }
760 while (i<lines-1);
761 mask &= ~DD_BACK_LEFT_BIT;
762 } /* double-buffer */
763
764 if (mask & DD_FRONT_LEFT_BIT) {
765 /* single-buffer */
766 HDC DC=DD_GETDC;
767 HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
768 HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
769 HPEN Old_Pen=SelectObject(DC,Pen);
770 HBRUSH Old_Brush=SelectObject(DC,Brush);
771 Rectangle(DC,x,y,x+width,y+height);
772 SelectObject(DC,Old_Pen);
773 SelectObject(DC,Old_Brush);
774 DeleteObject(Pen);
775 DeleteObject(Brush);
776 DD_RELEASEDC;
777 mask &= ~DD_FRONT_LEFT_BIT;
778 } /* single-buffer */
779 } /* if masks are all 1's */
780
781 /* Call swrast if there is anything left to clear (like DEPTH) */
782 if (mask)
783 _swrast_Clear( ctx, mask, all, x, y, width, height );
784 }
785
786
787 //---------------------------------------------------------------------------
788
789
790 static void enable( struct gl_context* ctx, GLenum pname, GLboolean enable )
791 {
792 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
793 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
794
795 if (!Current)
796 return;
797
798 if (pname == GL_DITHER) {
799 if(enable == GL_FALSE){
800 Current->dither_flag = GL_FALSE;
801 if(Current->cColorBits == 8)
802 Current->pixelformat = PF_INDEX8;
803 }
804 else{
805 if (Current->rgb_flag && Current->cColorBits == 8){
806 Current->pixelformat = PF_DITHER8;
807 Current->dither_flag = GL_TRUE;
808 }
809 else
810 Current->dither_flag = GL_FALSE;
811 }
812 }
813 }
814
815 //---------------------------------------------------------------------------
816
817 static GLboolean set_draw_buffer( struct gl_context* ctx, GLenum mode )
818 {
819 /* TODO: this could be better */
820 if (mode==GL_FRONT_LEFT || mode==GL_BACK_LEFT) {
821 return GL_TRUE;
822 }
823 else {
824 return GL_FALSE;
825 }
826 }
827
828 //---------------------------------------------------------------------------
829
830
831 static void set_read_buffer(struct gl_context *ctx, struct gl_framebuffer *colorBuffer,
832 GLenum buffer )
833 {
834 /* XXX todo */
835 return;
836 }
837
838
839 //---------------------------------------------------------------------------
840
841
842 /* Return characteristics of the output buffer. */
843 //static void buffer_size( struct gl_context* ctx, GLuint *width, GLuint *height )
844 // Altered for Mesa 5.x. KeithH
845 static void buffer_size(
846 struct gl_framebuffer *buffer,
847 GLuint *width,
848 GLuint *height)
849 {
850 // For some reason the context is not passed into this function.
851 // Therefore we have to explicitly retrieve it.
852 GET_CURRENT_CONTEXT(ctx);
853
854 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
855 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
856 int New_Size;
857 RECT CR;
858
859 GetClientRect(Current->Window,&CR);
860
861 *width=CR.right;
862 *height=CR.bottom;
863
864 New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
865
866 if (New_Size){
867 Current->width=*width;
868 Current->height=*height;
869 Current->ScanWidth=Current->width;
870 if ((Current->ScanWidth%sizeof(long))!=0)
871 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
872
873 if (Current->db_flag){
874 if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){
875 wmDeleteBackingStore(Current);
876 wmCreateBackingStore(Current, Current->width, Current->height);
877 }
878 }
879
880 }
881 }
882
883
884
885 /**********************************************************************/
886 /***** Accelerated point, line, polygon rendering *****/
887 /**********************************************************************/
888
889 /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */
890
891 static void fast_rgb_points( struct gl_context* ctx, GLuint first, GLuint last )
892 {
893 }
894
895 //---------------------------------------------------------------------------
896
897 /* Return pointer to accelerated points function */
898 extern tnl_points_func choose_points_function( struct gl_context* ctx )
899 {
900 return NULL;
901 }
902
903 //---------------------------------------------------------------------------
904
905 static void fast_flat_rgb_line( struct gl_context* ctx, GLuint v0,
906 GLuint v1, GLuint pv )
907 {
908 }
909
910 //---------------------------------------------------------------------------
911
912 static tnl_line_func choose_line_function( struct gl_context* ctx )
913 {
914 }
915
916
917 /**********************************************************************/
918 /***** Span-based pixel drawing *****/
919 /**********************************************************************/
920
921
922 /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */
923 static void write_ci32_span( const struct gl_context* ctx,
924 GLuint n, GLint x, GLint y,
925 const GLuint index[],
926 const GLubyte mask[] )
927 {
928 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
929 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
930 GLuint i;
931 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
932 assert(Current->rgb_flag==GL_FALSE);
933 for (i=0; i<n; i++)
934 if (mask[i])
935 Mem[i]=index[i];
936 }
937
938
939 //---------------------------------------------------------------------------
940
941 /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */
942 static void write_ci8_span( const struct gl_context* ctx,
943 GLuint n, GLint x, GLint y,
944 const GLubyte index[],
945 const GLubyte mask[] )
946 {
947 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
948 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
949 GLuint i;
950 PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
951 assert(Current->rgb_flag==GL_FALSE);
952 for (i=0; i<n; i++)
953 if (mask[i])
954 Mem[i]=index[i];
955 }
956
957
958 //---------------------------------------------------------------------------
959
960
961 /*
962 * Write a horizontal span of pixels with a boolean mask. The current
963 * color index is used for all pixels.
964 */
965 static void write_mono_ci_span(const struct gl_context* ctx,
966 GLuint n,GLint x,GLint y,
967 GLuint colorIndex, const GLubyte mask[])
968 {
969 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
970 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
971 GLuint i;
972 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
973 assert(Current->rgb_flag==GL_FALSE);
974 for (i=0; i<n; i++)
975 if (mask[i])
976 Mem[i]=colorIndex;
977 }
978
979 //---------------------------------------------------------------------------
980
981 /*
982 * To improve the performance of this routine, frob the data into an actual
983 * scanline and call bitblt on the complete scan line instead of SetPixel.
984 */
985
986 /* Write a horizontal span of RGBA color pixels with a boolean mask. */
987 static void write_rgba_span( const struct gl_context* ctx, GLuint n, GLint x, GLint y,
988 const GLubyte rgba[][4], const GLubyte mask[] )
989 {
990 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
991 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
992 PWMC pwc = Current;
993
994 if (pwc->rgb_flag==GL_TRUE)
995 {
996 GLuint i;
997 HDC DC=DD_GETDC;
998 y=FLIP(y);
999 if (mask) {
1000 for (i=0; i<n; i++)
1001 if (mask[i])
1002 wmSetPixel(pwc, y, x + i,
1003 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1004 }
1005 else {
1006 for (i=0; i<n; i++)
1007 wmSetPixel(pwc, y, x + i,
1008 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] );
1009 }
1010 DD_RELEASEDC;
1011 }
1012 else
1013 {
1014 GLuint i;
1015 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
1016 y = FLIP(y);
1017 if (mask) {
1018 for (i=0; i<n; i++)
1019 if (mask[i])
1020 Mem[i] = GetNearestPaletteIndex(Current->hPal,
1021 RGB(rgba[i][RCOMP],
1022 rgba[i][GCOMP],
1023 rgba[i][BCOMP]));
1024 }
1025 else {
1026 for (i=0; i<n; i++)
1027 Mem[i] = GetNearestPaletteIndex(Current->hPal,
1028 RGB(rgba[i][RCOMP],
1029 rgba[i][GCOMP],
1030 rgba[i][BCOMP]));
1031 }
1032 }
1033 }
1034
1035 //---------------------------------------------------------------------------
1036
1037 /* Write a horizontal span of RGB color pixels with a boolean mask. */
1038 static void write_rgb_span( const struct gl_context* ctx,
1039 GLuint n, GLint x, GLint y,
1040 const GLubyte rgb[][3], const GLubyte mask[] )
1041 {
1042 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1043 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1044 PWMC pwc = Current;
1045
1046 if (pwc->rgb_flag==GL_TRUE)
1047 {
1048 GLuint i;
1049 HDC DC=DD_GETDC;
1050 y=FLIP(y);
1051 if (mask) {
1052 for (i=0; i<n; i++)
1053 if (mask[i])
1054 wmSetPixel(pwc, y, x + i,
1055 rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]);
1056 }
1057 else {
1058 for (i=0; i<n; i++)
1059 wmSetPixel(pwc, y, x + i,
1060 rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] );
1061 }
1062 DD_RELEASEDC;
1063 }
1064 else
1065 {
1066 GLuint i;
1067 BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
1068 y = FLIP(y);
1069 if (mask) {
1070 for (i=0; i<n; i++)
1071 if (mask[i])
1072 Mem[i] = GetNearestPaletteIndex(Current->hPal,
1073 RGB(rgb[i][RCOMP],
1074 rgb[i][GCOMP],
1075 rgb[i][BCOMP]));
1076 }
1077 else {
1078 for (i=0; i<n; i++)
1079 Mem[i] = GetNearestPaletteIndex(Current->hPal,
1080 RGB(rgb[i][RCOMP],
1081 rgb[i][GCOMP],
1082 rgb[i][BCOMP]));
1083 }
1084 }
1085 }
1086
1087 //---------------------------------------------------------------------------
1088
1089 /*
1090 * Write a horizontal span of pixels with a boolean mask. The current color
1091 * is used for all pixels.
1092 */
1093 static void write_mono_rgba_span( const struct gl_context* ctx,
1094 GLuint n, GLint x, GLint y,
1095 const GLchan color[4], const GLubyte mask[])
1096 {
1097 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1098 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1099 ULONG pixel = RGB( color[RCOMP], color[GCOMP], color[BCOMP] );
1100 GLuint i;
1101 HDC DC=DD_GETDC;
1102 PWMC pwc = Current;
1103 assert(Current->rgb_flag==GL_TRUE);
1104 y=FLIP(y);
1105 if(Current->rgb_flag==GL_TRUE){
1106 for (i=0; i<n; i++)
1107 if (mask[i])
1108 wmSetPixel(pwc,y,x+i,color[RCOMP], color[GCOMP], color[BCOMP]);
1109 }
1110 else {
1111 for (i=0; i<n; i++)
1112 if (mask[i])
1113 SetPixel(DC, y, x+i, pixel);
1114 }
1115 DD_RELEASEDC;
1116 }
1117
1118
1119
1120 /**********************************************************************/
1121 /***** Array-based pixel drawing *****/
1122 /**********************************************************************/
1123
1124
1125 /* Write an array of 32-bit index pixels with a boolean mask. */
1126 static void write_ci32_pixels( const struct gl_context* ctx,
1127 GLuint n, const GLint x[], const GLint y[],
1128 const GLuint index[], const GLubyte mask[] )
1129 {
1130 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1131 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1132 GLuint i;
1133 assert(Current->rgb_flag==GL_FALSE);
1134 for (i=0; i<n; i++) {
1135 if (mask[i]) {
1136 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
1137 *Mem = index[i];
1138 }
1139 }
1140 }
1141
1142
1143 //---------------------------------------------------------------------------
1144
1145
1146 /*
1147 * Write an array of pixels with a boolean mask. The current color
1148 * index is used for all pixels.
1149 */
1150 static void write_mono_ci_pixels( const struct gl_context* ctx,
1151 GLuint n,
1152 const GLint x[], const GLint y[],
1153 GLuint colorIndex, const GLubyte mask[] )
1154 {
1155 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1156 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1157 GLuint i;
1158 assert(Current->rgb_flag==GL_FALSE);
1159 for (i=0; i<n; i++) {
1160 if (mask[i]) {
1161 BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i];
1162 *Mem = colorIndex;
1163 }
1164 }
1165 }
1166
1167
1168 //---------------------------------------------------------------------------
1169
1170
1171 /* Write an array of RGBA pixels with a boolean mask. */
1172 static void write_rgba_pixels( const struct gl_context* ctx,
1173 GLuint n, const GLint x[], const GLint y[],
1174 const GLubyte rgba[][4], const GLubyte mask[] )
1175 {
1176 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1177 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1178 GLuint i;
1179 PWMC pwc = Current;
1180 HDC DC=DD_GETDC;
1181 assert(Current->rgb_flag==GL_TRUE);
1182 for (i=0; i<n; i++)
1183 if (mask[i])
1184 wmSetPixel(pwc, FLIP(y[i]), x[i],
1185 rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]);
1186 DD_RELEASEDC;
1187 }
1188
1189
1190 //---------------------------------------------------------------------------
1191
1192
1193 /*
1194 * Write an array of pixels with a boolean mask. The current color
1195 * is used for all pixels.
1196 */
1197 static void write_mono_rgba_pixels( const struct gl_context* ctx,
1198 GLuint n,
1199 const GLint x[], const GLint y[],
1200 const GLchan color[4],
1201 const GLubyte mask[] )
1202 {
1203 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1204 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1205 GLuint i;
1206 PWMC pwc = Current;
1207 HDC DC=DD_GETDC;
1208 assert(Current->rgb_flag==GL_TRUE);
1209 for (i=0; i<n; i++)
1210 if (mask[i])
1211 wmSetPixel(pwc, FLIP(y[i]),x[i],color[RCOMP],
1212 color[GCOMP], color[BCOMP]);
1213 DD_RELEASEDC;
1214 }
1215
1216 /**********************************************************************/
1217 /***** Read spans/arrays of pixels *****/
1218 /**********************************************************************/
1219
1220 /* Read a horizontal span of color-index pixels. */
1221 static void read_ci32_span( const struct gl_context* ctx, GLuint n, GLint x, GLint y,
1222 GLuint index[])
1223 {
1224 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1225 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1226 GLuint i;
1227 BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x;
1228 assert(Current->rgb_flag==GL_FALSE);
1229 for (i=0; i<n; i++)
1230 index[i]=Mem[i];
1231 }
1232
1233 //---------------------------------------------------------------------------
1234
1235 /* Read an array of color index pixels. */
1236 static void read_ci32_pixels( const struct gl_context* ctx,
1237 GLuint n, const GLint x[], const GLint y[],
1238 GLuint indx[], const GLubyte mask[] )
1239 {
1240 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1241 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1242 GLuint i;
1243 assert(Current->rgb_flag==GL_FALSE);
1244 for (i=0; i<n; i++) {
1245 if (mask[i]) {
1246 indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]);
1247 }
1248 }
1249 }
1250
1251 //---------------------------------------------------------------------------
1252
1253 /* Read a horizontal span of color pixels. */
1254 static void read_rgba_span( const struct gl_context* ctx,
1255 GLuint n, GLint x, GLint y,
1256 GLubyte rgba[][4] )
1257 {
1258 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1259 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1260 UINT i;
1261 COLORREF Color;
1262 HDC DC=DD_GETDC;
1263 assert(Current->rgb_flag==GL_TRUE);
1264 y = Current->height - y - 1;
1265 for (i=0; i<n; i++) {
1266 Color=GetPixel(DC,x+i,y);
1267 rgba[i][RCOMP] = GetRValue(Color);
1268 rgba[i][GCOMP] = GetGValue(Color);
1269 rgba[i][BCOMP] = GetBValue(Color);
1270 rgba[i][ACOMP] = 255;
1271 }
1272 DD_RELEASEDC;
1273 }
1274
1275 //---------------------------------------------------------------------------
1276
1277 /* Read an array of color pixels. */
1278 static void read_rgba_pixels( const struct gl_context* ctx,
1279 GLuint n, const GLint x[], const GLint y[],
1280 GLubyte rgba[][4], const GLubyte mask[] )
1281 {
1282 GLD_context *gldCtx = GLD_GET_CONTEXT(ctx);
1283 WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx);
1284 GLuint i;
1285 COLORREF Color;
1286 HDC DC=DD_GETDC;
1287 assert(Current->rgb_flag==GL_TRUE);
1288 for (i=0; i<n; i++) {
1289 if (mask[i]) {
1290 GLint y2 = Current->height - y[i] - 1;
1291 Color=GetPixel(DC,x[i],y2);
1292 rgba[i][RCOMP] = GetRValue(Color);
1293 rgba[i][GCOMP] = GetGValue(Color);
1294 rgba[i][BCOMP] = GetBValue(Color);
1295 rgba[i][ACOMP] = 255;
1296 }
1297 }
1298 DD_RELEASEDC;
1299 }
1300
1301 //---------------------------------------------------------------------------
1302
1303 static void wmesa_update_state(
1304 struct gl_context *ctx,
1305 GLuint new_state)
1306 {
1307 _swrast_InvalidateState( ctx, new_state );
1308 _swsetup_InvalidateState( ctx, new_state );
1309 _vbo_InvalidateState( ctx, new_state );
1310 _tnl_InvalidateState( ctx, new_state );
1311 }
1312
1313 //---------------------------------------------------------------------------
1314
1315 static void wmesa_viewport(
1316 struct gl_context *ctx,
1317 GLint x,
1318 GLint y,
1319 GLsizei w,
1320 GLsizei h)
1321 {
1322 // ctx->Driver.ResizeBuffersMESA(ctx);
1323 }
1324
1325 //---------------------------------------------------------------------------
1326
1327 static void wmesa_update_state_first_time(
1328 struct gl_context *ctx,
1329 GLuint new_state)
1330 {
1331 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
1332 TNLcontext *tnl = TNL_CONTEXT(ctx);
1333
1334 _mesa_init_driver_functions(&ctx->Driver);
1335
1336 /*
1337 * XXX these function pointers could be initialized just once during
1338 * context creation since they don't depend on any state changes.
1339 * kws - This is true - this function gets called a lot and it
1340 * would be good to minimize setting all this when not needed.
1341 */
1342 // Good idea, so I'll do it. KeithH. :-)
1343
1344 ctx->Driver.GetString = _gldGetStringGeneric;
1345 ctx->Driver.UpdateState = wmesa_update_state;
1346 ctx->Driver.DrawBuffer = set_draw_buffer;
1347 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
1348 ctx->Driver.GetBufferSize = buffer_size;
1349
1350 ctx->Driver.Viewport = wmesa_viewport;
1351
1352 ctx->Driver.Clear = clear;
1353
1354 ctx->Driver.Flush = flush;
1355 ctx->Driver.ClearColor = clear_color;
1356 ctx->Driver.Enable = enable;
1357
1358
1359 // Does not apply for Mesa 5.x
1360 //ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
1361 //ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
1362 //ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
1363
1364 swdd->SetBuffer = set_read_buffer;
1365
1366
1367 /* Pixel/span writing functions: */
1368 swdd->WriteRGBASpan = write_rgba_span;
1369 swdd->WriteRGBSpan = write_rgb_span;
1370 swdd->WriteMonoRGBASpan = write_mono_rgba_span;
1371 swdd->WriteRGBAPixels = write_rgba_pixels;
1372 swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1373 swdd->WriteCI32Span = write_ci32_span;
1374 swdd->WriteCI8Span = write_ci8_span;
1375 swdd->WriteMonoCISpan = write_mono_ci_span;
1376 swdd->WriteCI32Pixels = write_ci32_pixels;
1377 swdd->WriteMonoCIPixels = write_mono_ci_pixels;
1378
1379 swdd->ReadCI32Span = read_ci32_span;
1380 swdd->ReadRGBASpan = read_rgba_span;
1381 swdd->ReadCI32Pixels = read_ci32_pixels;
1382 swdd->ReadRGBAPixels = read_rgba_pixels;
1383
1384
1385 tnl->Driver.RunPipeline = _tnl_run_pipeline;
1386
1387 wmesa_update_state(ctx, new_state);
1388 }
1389
1390 //---------------------------------------------------------------------------
1391 // Driver interface functions
1392 //---------------------------------------------------------------------------
1393
1394 BOOL gldCreateDrawable_MesaSW(
1395 DGL_ctx *pCtx,
1396 BOOL bPersistantInterface,
1397 BOOL bPersistantBuffers)
1398 {
1399 WMesaContext *c;
1400 GLboolean true_color_flag;
1401 GLboolean rgb_flag = GL_TRUE;
1402 GLboolean db_flag = GL_TRUE;
1403
1404 if (pCtx == NULL)
1405 return FALSE;
1406
1407 c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
1408 if (!c)
1409 return FALSE;
1410
1411 pCtx->glPriv = c;
1412
1413 c->hDC = pCtx->hDC;
1414 c->Window = pCtx->hWnd;
1415
1416 true_color_flag = GetDeviceCaps(pCtx->hDC, BITSPIXEL) > 8;
1417
1418
1419 #ifdef DITHER
1420 if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){
1421 c->dither_flag = GL_TRUE;
1422 c->hPalHalfTone = WinGCreateHalftonePalette();
1423 }
1424 else
1425 c->dither_flag = GL_FALSE;
1426 #else
1427 c->dither_flag = GL_FALSE;
1428 #endif
1429
1430
1431 if (rgb_flag==GL_FALSE)
1432 {
1433 c->rgb_flag = GL_FALSE;
1434 #if 0
1435 /* Old WinG stuff???? */
1436 c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */
1437 printf("Single buffer is not supported in color index mode, ",
1438 "setting to double buffer.\n");
1439 #endif
1440 }
1441 else
1442 {
1443 c->rgb_flag = GL_TRUE;
1444 }
1445
1446 // db_flag = pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? GL_TRUE : GL_FALSE;
1447 db_flag = GL_TRUE; // Force double-buffer
1448 if (db_flag) {
1449 c->db_flag = 1;
1450 /* Double buffered */
1451 {
1452 wmCreateBackingStore(c, pCtx->dwWidth, pCtx->dwHeight);
1453
1454 }
1455 } else {
1456 /* Single Buffered */
1457 if (c->rgb_flag)
1458 c->db_flag = 0;
1459 }
1460
1461 c->bEmulateSingleBuffer = (pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER)
1462 ? FALSE : TRUE;
1463
1464 return TRUE;
1465 }
1466
1467 //---------------------------------------------------------------------------
1468
1469 BOOL gldResizeDrawable_MesaSW(
1470 DGL_ctx *ctx,
1471 BOOL bDefaultDriver,
1472 BOOL bPersistantInterface,
1473 BOOL bPersistantBuffers)
1474 {
1475 WMesaContext *c;
1476
1477 if (ctx == NULL)
1478 return FALSE;
1479
1480 c = ctx->glPriv;
1481 if (c == NULL)
1482 return FALSE;
1483
1484 c->hDC = ctx->hDC;
1485 c->Window = ctx->hWnd;
1486 // c->width = ctx->dwWidth;
1487 // c->height = ctx->dwHeight;
1488
1489 if (c->db_flag) {
1490 wmDeleteBackingStore(c);
1491 wmCreateBackingStore(c, ctx->dwWidth, ctx->dwHeight);
1492 }
1493
1494 return TRUE;
1495 }
1496
1497 //---------------------------------------------------------------------------
1498
1499 BOOL gldDestroyDrawable_MesaSW(
1500 DGL_ctx *ctx)
1501 {
1502 WMesaContext *c;
1503
1504 if (ctx == NULL)
1505 return FALSE;
1506
1507 c = ctx->glPriv;
1508 if (c == NULL)
1509 return FALSE;
1510
1511 if (c->hPalHalfTone != NULL)
1512 DeleteObject(c->hPalHalfTone);
1513
1514 if (c->db_flag)
1515 wmDeleteBackingStore(c);
1516
1517 free(c);
1518
1519 ctx->glPriv = NULL;
1520
1521 return TRUE;
1522 }
1523
1524 //---------------------------------------------------------------------------
1525
1526 BOOL gldCreatePrivateGlobals_MesaSW(void)
1527 {
1528 // Mesa Software driver needs no private globals
1529 return TRUE;
1530 }
1531
1532 //---------------------------------------------------------------------------
1533
1534 BOOL gldDestroyPrivateGlobals_MesaSW(void)
1535 {
1536 // Mesa Software driver needs no private globals
1537 return TRUE;
1538 }
1539
1540 //---------------------------------------------------------------------------
1541
1542 BOOL gldBuildPixelformatList_MesaSW(void)
1543 {
1544 // Release any existing pixelformat list
1545 if (glb.lpPF) {
1546 free(glb.lpPF);
1547 }
1548
1549 glb.nPixelFormatCount = 0;
1550 glb.lpPF = NULL;
1551
1552 glb.lpPF = (DGL_pixelFormat *)calloc(2, sizeof(DGL_pixelFormat));
1553 if (glb.lpPF == NULL)
1554 return FALSE;
1555 // Single-buffered
1556 memcpy(&glb.lpPF[0], &pfTemplateMesaSW, sizeof(DGL_pixelFormat));
1557 glb.lpPF[0].pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag
1558 // Double-buffered
1559 memcpy(&glb.lpPF[1], &pfTemplateMesaSW, sizeof(DGL_pixelFormat));
1560 glb.nPixelFormatCount = 2;
1561
1562 // Mark list as 'current'
1563 glb.bPixelformatsDirty = FALSE;
1564
1565 return TRUE;
1566 }
1567
1568 //---------------------------------------------------------------------------
1569
1570 BOOL gldInitialiseMesa_MesaSW(
1571 DGL_ctx *gld)
1572 {
1573 struct gl_context *ctx;
1574
1575 if (gld == NULL)
1576 return FALSE;
1577
1578 ctx = gld->glCtx;
1579
1580 // Set max texture size to 256
1581 ctx->Const.MaxTextureLevels = 8;
1582
1583 // Multitexture enable/disable
1584 ctx->Const.MaxTextureUnits = (glb.bMultitexture) ? MAX_TEXTURE_UNITS : 1;
1585
1586 /* Initialize the software rasterizer and helper modules.*/
1587
1588 // Added this to force max texture diminsion to 256. KeithH
1589 ctx->Const.MaxTextureLevels = 8;
1590 ctx->Const.MaxDrawBuffers = 1;
1591
1592 _mesa_enable_sw_extensions(ctx);
1593 _mesa_enable_imaging_extensions(ctx);
1594 _mesa_enable_1_3_extensions(ctx);
1595
1596 // _swrast_CreateContext( ctx );
1597 // _vbo_CreateContext( ctx );
1598 // _tnl_CreateContext( ctx );
1599 // _swsetup_CreateContext( ctx );
1600
1601 _swsetup_Wakeup( ctx );
1602
1603 wmesa_update_state_first_time(ctx, ~0);
1604
1605 return TRUE;
1606 }
1607
1608 //---------------------------------------------------------------------------
1609
1610 BOOL gldSwapBuffers_MesaSW(
1611 DGL_ctx *ctx,
1612 HDC hDC,
1613 HWND hWnd)
1614 {
1615 WMesaContext *c;
1616
1617 if (ctx == NULL)
1618 return FALSE;
1619
1620 c = ctx->glPriv;
1621 if (c == NULL)
1622 return FALSE;
1623
1624 /* If we're swapping the buffer associated with the current context
1625 * we have to flush any pending rendering commands first.
1626 */
1627
1628 // Altered to respect bEmulateSingleBuffer. KeithH
1629 // if (c->db_flag)
1630 if (!c->bEmulateSingleBuffer)
1631 wmFlush(c, hDC);
1632
1633 return TRUE;
1634 }
1635
1636 //---------------------------------------------------------------------------
1637
1638 PROC gldGetProcAddress_MesaSW(
1639 LPCSTR a)
1640 {
1641 int i;
1642 PROC proc = NULL;
1643
1644 for (i=0; GLD_extList[i].proc; i++) {
1645 if (!strcmp(a, GLD_extList[i].name)) {
1646 proc = GLD_extList[i].proc;
1647 break;
1648 }
1649 }
1650
1651 gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed");
1652
1653 return proc;
1654 }
1655
1656 //---------------------------------------------------------------------------
1657
1658 BOOL gldGetDisplayMode_MesaSW(
1659 DGL_ctx *ctx,
1660 GLD_displayMode *glddm)
1661 {
1662 HDC hdcDesktop;
1663
1664 if (glddm == NULL)
1665 return FALSE;
1666
1667 //
1668 // A bit hacky... KeithH
1669 //
1670
1671 hdcDesktop = GetDC(NULL);
1672 glddm->Width = GetDeviceCaps(hdcDesktop, HORZRES);
1673 glddm->Height = GetDeviceCaps(hdcDesktop, VERTRES);
1674 glddm->BPP = GetDeviceCaps(hdcDesktop, BITSPIXEL);
1675 glddm->Refresh = 0;
1676 ReleaseDC(0, hdcDesktop);
1677
1678 return TRUE;
1679 }
1680
1681 //---------------------------------------------------------------------------
1682