2 * COPYRIGHT: See COPYING in the top level directory
4 * FILE: dll/opengl/opengl32/swimpl.c
5 * PURPOSE: OpenGL32 DLL, opengl software implementation
11 #include <main/context.h>
12 #include <main/framebuffer.h>
13 #include <main/renderbuffer.h>
14 #include <main/shared.h>
15 #include <main/viewport.h>
16 #include <swrast/s_context.h>
17 #include <swrast/s_renderbuffer.h>
18 #include <swrast_setup/swrast_setup.h>
19 #include <tnl/t_pipeline.h>
21 #include <drivers/common/driverfuncs.h>
22 #include <drivers/common/meta.h>
24 WINE_DEFAULT_DEBUG_CHANNEL(opengl32
);
26 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
32 BYTE red_bits
, red_shift
; DWORD red_mask
;
33 BYTE green_bits
, green_shift
; DWORD green_mask
;
34 BYTE blue_bits
, blue_shift
; DWORD blue_mask
;
35 BYTE alpha_bits
, alpha_shift
; DWORD alpha_mask
;
39 DWORD bmp_compression
;
42 { MESA_FORMAT_ARGB8888
, 32, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 8, 0, 0xFF000000, 16, 32, 8, BI_BITFIELDS
},
43 { MESA_FORMAT_ARGB8888
, 32, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 8, 0, 0xFF000000, 16, 16, 8, BI_BITFIELDS
},
44 { MESA_FORMAT_RGBA8888_REV
, 32, 8, 8, 0x000000FF, 8, 16, 0x0000FF00, 8, 24, 0x00FF0000, 8, 0, 0xFF000000, 16, 32, 8, BI_BITFIELDS
},
45 { MESA_FORMAT_RGBA8888_REV
, 32, 8, 8, 0x000000FF, 8, 16, 0x0000FF00, 8, 24, 0x00FF0000, 8, 0, 0xFF000000, 16, 16, 8, BI_BITFIELDS
},
46 { MESA_FORMAT_RGBA8888
, 32, 8, 0, 0xFF000000, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 16, 32, 8, BI_BITFIELDS
},
47 { MESA_FORMAT_RGBA8888
, 32, 8, 0, 0xFF000000, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 16, 16, 8, BI_BITFIELDS
},
48 { MESA_FORMAT_ARGB8888_REV
, 32, 8, 16, 0x0000FF00, 8, 8, 0x00FF0000, 8, 0, 0xFF000000, 8, 24, 0x000000FF, 16, 32, 8, BI_BITFIELDS
},
49 { MESA_FORMAT_ARGB8888_REV
, 32, 8, 16, 0x0000FF00, 8, 8, 0x00FF0000, 8, 0, 0xFF000000, 8, 24, 0x000000FF, 16, 16, 8, BI_BITFIELDS
},
50 { MESA_FORMAT_RGB888
, 24, 8, 0, 0x00000000, 8, 8, 0x00000000, 8, 16, 0x00000000, 0, 0, 0x00000000, 16, 32, 8, BI_RGB
},
51 { MESA_FORMAT_RGB888
, 24, 8, 0, 0x00000000, 8, 8, 0x00000000, 8, 16, 0x00000000, 0, 0, 0x00000000, 16, 16, 8, BI_RGB
},
52 // { MESA_FORMAT_BGR888, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 },
53 // { MESA_FORMAT_BGR888, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 },
54 { MESA_FORMAT_RGB565
, 16, 5, 0, 0x00000000, 6, 5, 0x00000000, 5, 11, 0x00000000, 0, 0, 0x00000000, 16, 32, 8, BI_BITFIELDS
},
55 { MESA_FORMAT_RGB565
, 16, 5, 0, 0x0000F800, 6, 5, 0x000007E0, 5, 11, 0x0000001F, 0, 0, 0x00000000, 16, 16, 8, BI_BITFIELDS
},
58 #define SW_BACK_RENDERBUFFER_CLASS 0x8911
59 #define SW_FRONT_RENDERBUFFER_CLASS 0x8910
60 struct sw_front_renderbuffer
62 struct swrast_renderbuffer swrast
;
70 #define SW_FB_DOUBLEBUFFERED 0x1
71 #define SW_FB_DIRTY_SIZE 0x2
78 /* The mesa objects */
79 struct gl_config
*gl_visual
; /* Describes the buffers */
80 struct gl_framebuffer
*gl_buffer
; /* The mesa representation of frame buffer */
81 struct sw_front_renderbuffer frontbuffer
;
82 struct swrast_renderbuffer backbuffer
;
83 /* The bitmapi info we will use for rendering to display */
89 struct gl_context mesa
; /* Base class - this must be first */
90 /* This is to keep track of the size of the front buffer */
92 /* Framebuffer currently owning the context */
93 struct sw_framebuffer framebuffer
;
96 /* mesa opengl32 "driver" specific */
97 static const GLubyte
*
98 sw_get_string( struct gl_context
*ctx
, GLenum name
)
101 if(name
== GL_RENDERER
)
103 static const GLubyte renderer
[] = { 'R','e','a','c','t','O','S',' ',
104 'S','o','f','t','w','a','r','e',' ',
105 'I','m','p','l','e','m','e','n','t','a','t','i','o','n',0 };
108 /* Don't claim to support the fancy extensions that mesa supports, they will be slow anyway */
109 if(name
== GL_EXTENSIONS
)
111 static const GLubyte extensions
[] = { 0 };
118 sw_update_state( struct gl_context
*ctx
, GLuint new_state
)
120 /* easy - just propogate */
121 _swrast_InvalidateState( ctx
, new_state
);
122 _swsetup_InvalidateState( ctx
, new_state
);
123 _tnl_InvalidateState( ctx
, new_state
);
124 _vbo_InvalidateState( ctx
, new_state
);
127 /* Renderbuffer routines */
129 sw_bb_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
130 GLenum internalFormat
,
131 GLuint width
, GLuint height
)
133 struct swrast_renderbuffer
*srb
= swrast_renderbuffer(rb
);
134 struct sw_framebuffer
* fb
= CONTAINING_RECORD(srb
, struct sw_framebuffer
, backbuffer
);
135 UINT widthBytes
= WIDTH_BYTES_ALIGN32(width
, pixel_formats
[fb
->format_index
].color_bits
);
136 srb
->Base
.Format
= pixel_formats
[fb
->format_index
].mesa
;
139 srb
->Buffer
= HeapReAlloc(GetProcessHeap(), 0, srb
->Buffer
, widthBytes
*height
);
141 srb
->Buffer
= HeapAlloc(GetProcessHeap(), 0, widthBytes
*height
);
144 srb
->Base
.Format
= MESA_FORMAT_NONE
;
147 srb
->Base
.Width
= width
;
148 srb
->Base
.Height
= height
;
149 srb
->RowStride
= widthBytes
;
154 sw_bb_renderbuffer_delete(struct gl_renderbuffer
*rb
)
156 struct swrast_renderbuffer
*srb
= swrast_renderbuffer(rb
);
160 HeapFree(GetProcessHeap(), 0, srb
->Buffer
);
166 sw_fb_renderbuffer_delete(struct gl_renderbuffer
*rb
)
168 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
172 srb
->hbmp
= SelectObject(srb
->hdcmem
, srb
->hbmp
);
173 DeleteDC(srb
->hdcmem
);
174 DeleteObject(srb
->hbmp
);
177 srb
->swrast
.Buffer
= NULL
;
182 sw_fb_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
183 GLenum internalFormat
,
184 GLuint width
, GLuint height
)
186 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
187 struct sw_framebuffer
* fb
= CONTAINING_RECORD(srb
, struct sw_framebuffer
, frontbuffer
);
188 HDC hdc
= IntGetCurrentDC();
190 /* Don't bother if the size doesn't change */
191 if(rb
->Width
== width
&& rb
->Height
== height
)
194 /* Delete every objects which could have been used before */
195 sw_fb_renderbuffer_delete(&srb
->swrast
.Base
);
197 /* So the app wants to use the frontbuffer, allocate a DIB for it */
198 srb
->hbmp
= CreateDIBSection(
202 (void**)&srb
->swrast
.Buffer
,
206 ERR("Failed to create the DIB section for the front buffer, %lu.\n", GetLastError());
209 /* Create the DC and attach the DIB section to it */
210 srb
->hdcmem
= CreateCompatibleDC(hdc
);
211 assert(srb
->hdcmem
!= NULL
);
212 srb
->hbmp
= SelectObject(srb
->hdcmem
, srb
->hbmp
);
213 assert(srb
->hbmp
!= NULL
);
214 /* Set formats, width and height */
215 srb
->swrast
.Base
.Format
= pixel_formats
[fb
->format_index
].mesa
;
216 srb
->swrast
.Base
.Width
= width
;
217 srb
->swrast
.Base
.Height
= height
;
223 sw_init_renderbuffers(struct sw_framebuffer
*fb
)
225 _mesa_init_renderbuffer(&fb
->frontbuffer
.swrast
.Base
, 0);
226 fb
->frontbuffer
.swrast
.Base
.ClassID
= SW_FRONT_RENDERBUFFER_CLASS
;
227 fb
->frontbuffer
.swrast
.Base
.AllocStorage
= sw_fb_renderbuffer_storage
;
228 fb
->frontbuffer
.swrast
.Base
.Delete
= sw_fb_renderbuffer_delete
;
229 fb
->frontbuffer
.swrast
.Base
.InternalFormat
= GL_RGBA
;
230 fb
->frontbuffer
.swrast
.Base
._BaseFormat
= GL_RGBA
;
231 _mesa_remove_renderbuffer(fb
->gl_buffer
, BUFFER_FRONT_LEFT
);
232 _mesa_add_renderbuffer(fb
->gl_buffer
, BUFFER_FRONT_LEFT
, &fb
->frontbuffer
.swrast
.Base
);
234 if(fb
->flags
& SW_FB_DOUBLEBUFFERED
)
236 _mesa_init_renderbuffer(&fb
->backbuffer
.Base
, 0);
237 fb
->backbuffer
.Base
.ClassID
= SW_BACK_RENDERBUFFER_CLASS
;
238 fb
->backbuffer
.Base
.AllocStorage
= sw_bb_renderbuffer_storage
;
239 fb
->backbuffer
.Base
.Delete
= sw_bb_renderbuffer_delete
;
240 fb
->backbuffer
.Base
.InternalFormat
= GL_RGBA
;
241 fb
->backbuffer
.Base
._BaseFormat
= GL_RGBA
;
242 _mesa_remove_renderbuffer(fb
->gl_buffer
, BUFFER_BACK_LEFT
);
243 _mesa_add_renderbuffer(fb
->gl_buffer
, BUFFER_BACK_LEFT
, &fb
->backbuffer
.Base
);
250 sw_MapRenderbuffer(struct gl_context
*ctx
,
251 struct gl_renderbuffer
*rb
,
252 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
254 GLubyte
**mapOut
, GLint
*rowStrideOut
)
256 if(rb
->ClassID
== SW_FRONT_RENDERBUFFER_CLASS
)
258 /* This is our front buffer */
259 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
260 struct sw_framebuffer
* fb
= CONTAINING_RECORD(srb
, struct sw_framebuffer
, frontbuffer
);
262 *rowStrideOut
= WIDTH_BYTES_ALIGN32(rb
->Width
, pixel_formats
[fb
->format_index
].color_bits
);
263 /* Remember where we "mapped" */
264 srb
->x
= x
; srb
->y
= y
; srb
->w
= w
; srb
->h
= h
;
265 /* Remember if we should write it later */
266 srb
->write
= !!(mode
& GL_MAP_WRITE_BIT
);
267 /* Get the bits, if needed */
268 if(mode
& GL_MAP_READ_BIT
)
270 BitBlt(srb
->hdcmem
, srb
->x
, srb
->y
, srb
->w
, srb
->h
,
271 IntGetCurrentDC(), srb
->x
, srb
->y
, SRCCOPY
);
274 *mapOut
= (BYTE
*)srb
->swrast
.Buffer
+ *rowStrideOut
*y
+ x
*pixel_formats
[fb
->format_index
].color_bits
/8;
278 if(rb
->ClassID
== SW_BACK_RENDERBUFFER_CLASS
)
280 /* This is our front buffer */
281 struct swrast_renderbuffer
* srb
= (struct swrast_renderbuffer
*)rb
;
282 const GLuint bpp
= _mesa_get_format_bytes(rb
->Format
);
284 *rowStrideOut
= srb
->RowStride
;
285 *mapOut
= (BYTE
*)srb
->Buffer
+ srb
->RowStride
*y
+ x
*bpp
;
289 /* Let mesa rasterizer take care of this */
290 _swrast_map_soft_renderbuffer(ctx
, rb
, x
, y
, w
, h
, mode
,
291 mapOut
, rowStrideOut
);
295 sw_UnmapRenderbuffer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
)
297 if (rb
->ClassID
== SW_FRONT_RENDERBUFFER_CLASS
)
299 /* This is our front buffer */
300 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
303 /* Copy the bits to our display */
304 BitBlt(IntGetCurrentDC(),
305 srb
->x
, srb
->y
, srb
->w
, srb
->h
,
306 srb
->hdcmem
, srb
->x
, srb
->y
, SRCCOPY
);
312 if(rb
->ClassID
== SW_BACK_RENDERBUFFER_CLASS
)
313 return; /* nothing to do */
315 /* Let mesa rasterizer take care of this */
316 _swrast_unmap_soft_renderbuffer(ctx
, rb
);
319 /* WGL <-> mesa glue */
320 static UINT
index_from_format(struct wgl_dc_data
* dc_data
, INT format
, BOOL
* doubleBuffered
)
323 INT nb_win_compat
= 0, start_win_compat
= 0;
327 *doubleBuffered
= FALSE
;
329 if(!(dc_data
->flags
& WGL_DC_OBJ_DC
))
330 return format
- 1; /* OBJ_MEMDC, not double buffered */
332 hdc
= GetDC(dc_data
->owner
.hwnd
);
334 /* Find the window compatible formats */
335 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
336 for(index
= 0; index
<sizeof(pixel_formats
)/sizeof(pixel_formats
[0]); index
++)
338 if(pixel_formats
[index
].color_bits
== bpp
)
340 if(!start_win_compat
)
341 start_win_compat
= index
+1;
345 ReleaseDC(dc_data
->owner
.hwnd
, hdc
);
347 /* Double buffered format */
348 if(format
< (start_win_compat
+ nb_win_compat
))
350 if(format
>= start_win_compat
)
351 *doubleBuffered
= TRUE
;
355 return format
- nb_win_compat
- 1;
358 INT
sw_DescribePixelFormat(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
* descr
)
361 INT nb_win_compat
= 0, start_win_compat
= 0;
362 INT ret
= sizeof(pixel_formats
)/sizeof(pixel_formats
[0]);
364 if(GetObjectType(hdc
) == OBJ_DC
)
366 /* Find the window compatible formats */
367 INT bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
368 for(index
= 0; index
<sizeof(pixel_formats
)/sizeof(pixel_formats
[0]); index
++)
370 if(pixel_formats
[index
].color_bits
== bpp
)
372 if(!start_win_compat
)
373 start_win_compat
= index
+1;
377 /* Add the double buffered formats */
378 ret
+= nb_win_compat
;
381 index
= (UINT
)format
- 1;
384 if((format
> ret
) || (size
!= sizeof(*descr
)))
388 descr
->dwFlags
= PFD_SUPPORT_GDI
| PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_BITMAP
| PFD_GENERIC_FORMAT
;
389 /* See if this is a format compatible with the window */
390 if(format
>= start_win_compat
&& format
< (start_win_compat
+ nb_win_compat
*2) )
393 descr
->dwFlags
|= PFD_DRAW_TO_WINDOW
;
394 /* See if this should be double buffered */
395 if(format
< (start_win_compat
+ nb_win_compat
))
397 /* No GDI, no bitmap */
398 descr
->dwFlags
&= ~(PFD_SUPPORT_GDI
| PFD_DRAW_TO_BITMAP
);
399 descr
->dwFlags
|= PFD_DOUBLEBUFFER
;
402 /* Normalize the index */
403 if(format
>= start_win_compat
+ nb_win_compat
)
404 index
-= nb_win_compat
;
406 /* Fill the rest of the structure */
407 descr
->nSize
= sizeof(*descr
);
409 descr
->iPixelType
= PFD_TYPE_RGBA
;
410 descr
->cColorBits
= pixel_formats
[index
].color_bits
;
411 descr
->cRedBits
= pixel_formats
[index
].red_bits
;
412 descr
->cRedShift
= pixel_formats
[index
].red_shift
;
413 descr
->cGreenBits
= pixel_formats
[index
].green_bits
;
414 descr
->cGreenShift
= pixel_formats
[index
].green_shift
;
415 descr
->cBlueBits
= pixel_formats
[index
].blue_bits
;
416 descr
->cBlueShift
= pixel_formats
[index
].blue_shift
;
417 descr
->cAlphaBits
= pixel_formats
[index
].alpha_bits
;
418 descr
->cAlphaShift
= pixel_formats
[index
].alpha_shift
;
419 descr
->cAccumBits
= pixel_formats
[index
].accum_bits
;
420 descr
->cAccumRedBits
= pixel_formats
[index
].accum_bits
/ 4;
421 descr
->cAccumGreenBits
= pixel_formats
[index
].accum_bits
/ 4;
422 descr
->cAccumBlueBits
= pixel_formats
[index
].accum_bits
/ 4;
423 descr
->cAccumAlphaBits
= pixel_formats
[index
].accum_bits
/ 4;
424 descr
->cDepthBits
= pixel_formats
[index
].depth_bits
;
425 descr
->cStencilBits
= pixel_formats
[index
].stencil_bits
;
426 descr
->cAuxBuffers
= 0;
427 descr
->iLayerType
= PFD_MAIN_PLANE
;
431 BOOL
sw_SetPixelFormat(HDC hdc
, struct wgl_dc_data
* dc_data
, INT format
)
433 struct sw_framebuffer
* fb
;
436 assert(dc_data
->sw_data
== NULL
);
438 /* So, someone is crazy enough to ask for sw implementation. Announce it. */
439 TRACE("OpenGL software implementation START!\n");
441 /* allocate our structure */
442 fb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, FIELD_OFFSET(struct sw_framebuffer
, bmi
.bmiColors
[2]));
445 /* Get the format index */
446 fb
->format_index
= index_from_format(dc_data
, format
, &doubleBuffered
);
447 fb
->flags
= doubleBuffered
? SW_FB_DOUBLEBUFFERED
: 0;
448 /* Set the bitmap info describing the framebuffer */
449 fb
->bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
450 fb
->bmi
.bmiHeader
.biPlanes
= 1;
451 fb
->bmi
.bmiHeader
.biBitCount
= pixel_formats
[fb
->format_index
].color_bits
;
452 fb
->bmi
.bmiHeader
.biCompression
= pixel_formats
[fb
->format_index
].bmp_compression
;
453 fb
->bmi
.bmiHeader
.biSizeImage
= 0;
454 fb
->bmi
.bmiHeader
.biXPelsPerMeter
= 0;
455 fb
->bmi
.bmiHeader
.biYPelsPerMeter
= 0;
456 fb
->bmi
.bmiHeader
.biClrUsed
= 0;
457 fb
->bmi
.bmiHeader
.biClrImportant
= 0;
458 *((DWORD
*)&fb
->bmi
.bmiColors
[0]) = pixel_formats
[fb
->format_index
].red_mask
;
459 *((DWORD
*)&fb
->bmi
.bmiColors
[1]) = pixel_formats
[fb
->format_index
].green_mask
;
460 *((DWORD
*)&fb
->bmi
.bmiColors
[2]) = pixel_formats
[fb
->format_index
].blue_mask
;
464 /* Allocate the visual structure describing the format */
465 fb
->gl_visual
= _mesa_create_visual(
466 !!(fb
->flags
& SW_FB_DOUBLEBUFFERED
),
467 GL_FALSE
, /* No stereoscopic support */
468 pixel_formats
[fb
->format_index
].red_bits
,
469 pixel_formats
[fb
->format_index
].green_bits
,
470 pixel_formats
[fb
->format_index
].blue_bits
,
471 pixel_formats
[fb
->format_index
].alpha_bits
,
472 pixel_formats
[fb
->format_index
].depth_bits
,
473 pixel_formats
[fb
->format_index
].stencil_bits
,
474 pixel_formats
[fb
->format_index
].accum_bits
,
475 pixel_formats
[fb
->format_index
].accum_bits
,
476 pixel_formats
[fb
->format_index
].accum_bits
,
477 pixel_formats
[fb
->format_index
].alpha_bits
?
478 pixel_formats
[fb
->format_index
].accum_bits
: 0);
482 ERR("Failed to allocate a GL visual.\n");
483 HeapFree(GetProcessHeap(), 0, fb
);
487 /* Allocate the framebuffer structure */
488 fb
->gl_buffer
= _mesa_create_framebuffer(fb
->gl_visual
);
489 if (!fb
->gl_buffer
) {
490 ERR("Failed to allocate the mesa framebuffer structure.\n");
491 _mesa_destroy_visual( fb
->gl_visual
);
492 HeapFree(GetProcessHeap(), 0, fb
);
496 /* Add the depth/stencil/accum buffers */
497 _swrast_add_soft_renderbuffers(fb
->gl_buffer
,
498 GL_FALSE
, /* color */
499 fb
->gl_visual
->haveDepthBuffer
,
500 fb
->gl_visual
->haveStencilBuffer
,
501 fb
->gl_visual
->haveAccumBuffer
,
502 GL_FALSE
, /* alpha */
503 GL_FALSE
/* aux */ );
505 /* Initialize our render buffers */
506 sw_init_renderbuffers(fb
);
508 /* Everything went fine */
509 dc_data
->sw_data
= fb
;
513 DHGLRC
sw_CreateContext(struct wgl_dc_data
* dc_data
)
515 struct sw_context
* sw_ctx
;
516 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
517 struct dd_function_table mesa_drv_functions
;
520 /* We use the mesa memory routines for this function */
521 sw_ctx
= CALLOC_STRUCT(sw_context
);
525 /* Set mesa default functions */
526 _mesa_init_driver_functions(&mesa_drv_functions
);
528 mesa_drv_functions
.GetString
= sw_get_string
;
529 mesa_drv_functions
.UpdateState
= sw_update_state
;
530 mesa_drv_functions
.GetBufferSize
= NULL
;
532 /* Initialize the context */
533 if(!_mesa_initialize_context(&sw_ctx
->mesa
,
539 ERR("Failed to initialize the mesa context.\n");
544 /* Initialize the "meta driver" */
545 _mesa_meta_init(&sw_ctx
->mesa
);
547 /* Initialize helpers */
548 if(!_swrast_CreateContext(&sw_ctx
->mesa
) ||
549 !_vbo_CreateContext(&sw_ctx
->mesa
) ||
550 !_tnl_CreateContext(&sw_ctx
->mesa
) ||
551 !_swsetup_CreateContext(&sw_ctx
->mesa
))
553 ERR("Failed initializing helpers.\n");
554 _mesa_free_context_data(&sw_ctx
->mesa
);
560 _swsetup_Wakeup(&sw_ctx
->mesa
);
562 /* Use TnL defaults */
563 tnl
= TNL_CONTEXT(&sw_ctx
->mesa
);
564 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
566 /* To map the display into user memory */
567 sw_ctx
->mesa
.Driver
.MapRenderbuffer
= sw_MapRenderbuffer
;
568 sw_ctx
->mesa
.Driver
.UnmapRenderbuffer
= sw_UnmapRenderbuffer
;
570 return (DHGLRC
)sw_ctx
;
573 BOOL
sw_DeleteContext(DHGLRC dhglrc
)
575 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
576 /* Those get clobbered by _mesa_free_context_data via _glapi_set{context,dispath_table} */
577 void* icd_save
= IntGetCurrentICDPrivate();
578 const GLDISPATCHTABLE
* table_save
= IntGetCurrentDispatchTable();
580 /* Destroy everything */
581 _mesa_meta_free( &sw_ctx
->mesa
);
583 _swsetup_DestroyContext( &sw_ctx
->mesa
);
584 _tnl_DestroyContext( &sw_ctx
->mesa
);
585 _vbo_DestroyContext( &sw_ctx
->mesa
);
586 _swrast_DestroyContext( &sw_ctx
->mesa
);
588 _mesa_free_context_data( &sw_ctx
->mesa
);
592 IntSetCurrentDispatchTable(table_save
);
593 IntSetCurrentICDPrivate(icd_save
);
598 PROC
sw_GetProcAddress(LPCSTR name
)
600 /* We don't support any extensions */
601 WARN("Asking for proc address %s, returning NULL.\n", name
);
605 BOOL
sw_CopyContext(DHGLRC dhglrcSrc
, DHGLRC dhglrcDst
, UINT mask
)
607 FIXME("Software wglCopyContext is UNIMPLEMENTED, mask %lx.\n", mask
);
611 BOOL
sw_ShareLists(DHGLRC dhglrcSrc
, DHGLRC dhglrcDst
)
613 struct sw_context
* sw_ctx_src
= (struct sw_context
*)dhglrcSrc
;
614 struct sw_context
* sw_ctx_dst
= (struct sw_context
*)dhglrcDst
;
616 /* See if it was already shared */
617 if(sw_ctx_dst
->mesa
.Shared
->RefCount
> 1)
620 /* Unreference the old, share the new */
621 _mesa_reference_shared_state(&sw_ctx_dst
->mesa
,
622 &sw_ctx_dst
->mesa
.Shared
,
623 sw_ctx_src
->mesa
.Shared
);
635 struct wgl_dc_data
* dc_data
= IntGetCurrentDcData();
636 struct sw_context
* ctx
= (struct sw_context
*)IntGetCurrentDHGLRC();
637 struct sw_framebuffer
* fb
;
638 PCWPSTRUCT pParams
= (PCWPSTRUCT
)lParam
;
640 if((!dc_data
) || (!ctx
))
643 if(!(dc_data
->flags
& WGL_DC_OBJ_DC
))
646 if((nCode
< 0) || (dc_data
->owner
.hwnd
!= pParams
->hwnd
) || (dc_data
->sw_data
== NULL
))
647 return CallNextHookEx(ctx
->hook
, nCode
, wParam
, lParam
);
649 fb
= dc_data
->sw_data
;
651 if (pParams
->message
== WM_WINDOWPOSCHANGED
)
653 /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to
654 * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
655 * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
656 * can be masked out by the application. */
657 LPWINDOWPOS lpWindowPos
= (LPWINDOWPOS
)pParams
->lParam
;
658 if((lpWindowPos
->flags
& SWP_SHOWWINDOW
) ||
659 !(lpWindowPos
->flags
& SWP_NOMOVE
) ||
660 !(lpWindowPos
->flags
& SWP_NOSIZE
))
662 /* Size in WINDOWPOS includes the window frame, so get the size
663 * of the client area via GetClientRect. */
666 GetClientRect(pParams
->hwnd
, &client_rect
);
667 width
= client_rect
.right
- client_rect
.left
;
668 height
= client_rect
.bottom
- client_rect
.top
;
669 /* Do not reallocate for minimized windows */
670 if(width
<= 0 || height
<= 0)
672 /* Update framebuffer size */
673 fb
->bmi
.bmiHeader
.biWidth
= width
;
674 fb
->bmi
.bmiHeader
.biHeight
= height
;
675 /* Propagate to mesa */
676 _mesa_resize_framebuffer(&ctx
->mesa
, fb
->gl_buffer
, width
, height
);
681 return CallNextHookEx(ctx
->hook
, nCode
, wParam
, lParam
);
684 BOOL
sw_SetContext(struct wgl_dc_data
* dc_data
, DHGLRC dhglrc
)
686 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
687 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
691 sw_update_state(&sw_ctx
->mesa
, 0);
693 /* Get framebuffer size */
694 if(dc_data
->flags
& WGL_DC_OBJ_DC
)
696 HWND hwnd
= dc_data
->owner
.hwnd
;
700 ERR("Physical DC without a window!\n");
703 if(!GetClientRect(hwnd
, &client_rect
))
705 ERR("GetClientRect failed!\n");
708 /* This is a physical DC. Setup the hook */
709 sw_ctx
->hook
= SetWindowsHookEx(WH_CALLWNDPROC
,
712 GetCurrentThreadId());
713 /* Calculate width & height */
714 width
= client_rect
.right
- client_rect
.left
;
715 height
= client_rect
.bottom
- client_rect
.top
;
721 HDC hdc
= dc_data
->owner
.hdc
;
723 if(fb
->flags
& SW_FB_DOUBLEBUFFERED
)
725 ERR("Memory DC called with a double buffered format.\n");
729 hbmp
= GetCurrentObject( hdc
, OBJ_BITMAP
);
735 if(GetObject(hbmp
, sizeof(bm
), &bm
) == 0)
737 ERR("GetObject failed!\n");
741 height
= bm
.bmHeight
;
744 if(!width
) width
= 1;
745 if(!height
) height
= 1;
747 fb
->bmi
.bmiHeader
.biWidth
= width
;
748 fb
->bmi
.bmiHeader
.biHeight
= height
;
750 /* Also make the mesa context current to mesa */
751 if(!_mesa_make_current(&sw_ctx
->mesa
, fb
->gl_buffer
, fb
->gl_buffer
))
753 ERR("_mesa_make_current filaed!\n");
757 /* Set the viewport if this is the first time we initialize this context */
758 if(sw_ctx
->mesa
.Viewport
.X
== 0 &&
759 sw_ctx
->mesa
.Viewport
.Y
== 0 &&
760 sw_ctx
->mesa
.Viewport
.Width
== 0 &&
761 sw_ctx
->mesa
.Viewport
.Height
== 0)
763 _mesa_set_viewport(&sw_ctx
->mesa
, 0, 0, width
, height
);
766 /* update the framebuffer size */
767 _mesa_resize_framebuffer(&sw_ctx
->mesa
, fb
->gl_buffer
, width
, height
);
773 void sw_ReleaseContext(DHGLRC dhglrc
)
775 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
777 /* Forward to mesa */
778 _mesa_make_current(NULL
, NULL
, NULL
);
783 UnhookWindowsHookEx(sw_ctx
->hook
);
788 BOOL
sw_SwapBuffers(HDC hdc
, struct wgl_dc_data
* dc_data
)
790 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
791 struct sw_context
* sw_ctx
= (struct sw_context
*)IntGetCurrentDHGLRC();
795 _mesa_notifySwapBuffers(&sw_ctx
->mesa
);
797 if(!(fb
->flags
& SW_FB_DOUBLEBUFFERED
))
800 /* Upload to the display */
801 return (SetDIBitsToDevice(hdc
,
804 fb
->bmi
.bmiHeader
.biWidth
,
805 fb
->bmi
.bmiHeader
.biHeight
,
809 fb
->bmi
.bmiHeader
.biHeight
,
810 fb
->backbuffer
.Buffer
,
812 DIB_RGB_COLORS
) != 0);