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/formats.h>
13 #include <main/framebuffer.h>
14 #include <main/renderbuffer.h>
15 #include <main/shared.h>
16 #include <main/viewport.h>
17 #include <swrast/s_context.h>
18 #include <swrast/s_renderbuffer.h>
19 #include <swrast_setup/swrast_setup.h>
20 #include <tnl/t_context.h>
21 #include <tnl/t_pipeline.h>
23 #include <drivers/common/driverfuncs.h>
24 #include <drivers/common/meta.h>
26 #include <wine/debug.h>
27 WINE_DEFAULT_DEBUG_CHANNEL(opengl32
);
29 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
35 BYTE red_bits
, red_shift
; DWORD red_mask
;
36 BYTE green_bits
, green_shift
; DWORD green_mask
;
37 BYTE blue_bits
, blue_shift
; DWORD blue_mask
;
38 BYTE alpha_bits
, alpha_shift
; DWORD alpha_mask
;
42 DWORD bmp_compression
;
45 { MESA_FORMAT_ARGB8888
, 32, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 8, 0, 0xFF000000, 16, 32, 8, BI_BITFIELDS
},
46 { MESA_FORMAT_ARGB8888
, 32, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 8, 0, 0xFF000000, 16, 16, 8, BI_BITFIELDS
},
47 { MESA_FORMAT_RGBA8888_REV
, 32, 8, 8, 0x000000FF, 8, 16, 0x0000FF00, 8, 24, 0x00FF0000, 8, 0, 0xFF000000, 16, 32, 8, BI_BITFIELDS
},
48 { MESA_FORMAT_RGBA8888_REV
, 32, 8, 8, 0x000000FF, 8, 16, 0x0000FF00, 8, 24, 0x00FF0000, 8, 0, 0xFF000000, 16, 16, 8, BI_BITFIELDS
},
49 { MESA_FORMAT_RGBA8888
, 32, 8, 0, 0xFF000000, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 16, 32, 8, BI_BITFIELDS
},
50 { MESA_FORMAT_RGBA8888
, 32, 8, 0, 0xFF000000, 8, 8, 0x00FF0000, 8, 16, 0x0000FF00, 8, 24, 0x000000FF, 16, 16, 8, BI_BITFIELDS
},
51 { MESA_FORMAT_ARGB8888_REV
, 32, 8, 16, 0x0000FF00, 8, 8, 0x00FF0000, 8, 0, 0xFF000000, 8, 24, 0x000000FF, 16, 32, 8, BI_BITFIELDS
},
52 { MESA_FORMAT_ARGB8888_REV
, 32, 8, 16, 0x0000FF00, 8, 8, 0x00FF0000, 8, 0, 0xFF000000, 8, 24, 0x000000FF, 16, 16, 8, BI_BITFIELDS
},
53 { MESA_FORMAT_RGB888
, 24, 8, 0, 0x00000000, 8, 8, 0x00000000, 8, 16, 0x00000000, 0, 0, 0x00000000, 16, 32, 8, BI_RGB
},
54 { MESA_FORMAT_RGB888
, 24, 8, 0, 0x00000000, 8, 8, 0x00000000, 8, 16, 0x00000000, 0, 0, 0x00000000, 16, 16, 8, BI_RGB
},
55 // { MESA_FORMAT_BGR888, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 32, 8 },
56 // { MESA_FORMAT_BGR888, 24, 8, 16, 8, 8, 8, 0, 0, 0, 16, 16, 8 },
57 { MESA_FORMAT_RGB565
, 16, 5, 0, 0x00000000, 6, 5, 0x00000000, 5, 11, 0x00000000, 0, 0, 0x00000000, 16, 32, 8, BI_BITFIELDS
},
58 { MESA_FORMAT_RGB565
, 16, 5, 0, 0x0000F800, 6, 5, 0x000007E0, 5, 11, 0x0000001F, 0, 0, 0x00000000, 16, 16, 8, BI_BITFIELDS
},
61 #define SW_BACK_RENDERBUFFER_CLASS 0x8911
62 #define SW_FRONT_RENDERBUFFER_CLASS 0x8910
63 struct sw_front_renderbuffer
65 struct swrast_renderbuffer swrast
;
73 #define SW_FB_DOUBLEBUFFERED 0x1
74 #define SW_FB_DIRTY_SIZE 0x2
81 /* The mesa objects */
82 struct gl_config
*gl_visual
; /* Describes the buffers */
83 struct gl_framebuffer
*gl_buffer
; /* The mesa representation of frame buffer */
84 struct sw_front_renderbuffer frontbuffer
;
85 struct swrast_renderbuffer backbuffer
;
86 /* The bitmapi info we will use for rendering to display */
92 struct gl_context mesa
; /* Base class - this must be first */
93 /* This is to keep track of the size of the front buffer */
95 /* Framebuffer currently owning the context */
96 struct sw_framebuffer framebuffer
;
99 /* mesa opengl32 "driver" specific */
100 static const GLubyte
*
101 sw_get_string( struct gl_context
*ctx
, GLenum name
)
104 if(name
== GL_RENDERER
)
106 static const GLubyte renderer
[] = { 'R','e','a','c','t','O','S',' ',
107 'S','o','f','t','w','a','r','e',' ',
108 'I','m','p','l','e','m','e','n','t','a','t','i','o','n',0 };
111 /* Don't claim to support the fancy extensions that mesa supports, they will be slow anyway */
112 if(name
== GL_EXTENSIONS
)
114 static const GLubyte extensions
[] = { 0 };
121 sw_update_state( struct gl_context
*ctx
, GLuint new_state
)
123 /* easy - just propogate */
124 _swrast_InvalidateState( ctx
, new_state
);
125 _swsetup_InvalidateState( ctx
, new_state
);
126 _tnl_InvalidateState( ctx
, new_state
);
127 _vbo_InvalidateState( ctx
, new_state
);
130 /* Renderbuffer routines */
132 sw_bb_renderbuffer_storage(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
133 GLenum internalFormat
,
134 GLuint width
, GLuint height
)
136 struct swrast_renderbuffer
*srb
= swrast_renderbuffer(rb
);
137 struct sw_framebuffer
* fb
= CONTAINING_RECORD(srb
, struct sw_framebuffer
, backbuffer
);
138 UINT widthBytes
= WIDTH_BYTES_ALIGN32(width
, pixel_formats
[fb
->format_index
].color_bits
);
139 srb
->Base
.Format
= pixel_formats
[fb
->format_index
].mesa
;
142 srb
->Buffer
= HeapReAlloc(GetProcessHeap(), 0, srb
->Buffer
, widthBytes
*height
);
144 srb
->Buffer
= HeapAlloc(GetProcessHeap(), 0, widthBytes
*height
);
147 srb
->Base
.Format
= MESA_FORMAT_NONE
;
150 srb
->Base
.Width
= width
;
151 srb
->Base
.Height
= height
;
152 srb
->RowStride
= widthBytes
;
157 sw_bb_renderbuffer_delete(struct gl_renderbuffer
*rb
)
159 struct swrast_renderbuffer
*srb
= swrast_renderbuffer(rb
);
163 HeapFree(GetProcessHeap(), 0, srb
->Buffer
);
169 sw_fb_renderbuffer_delete(struct gl_renderbuffer
*rb
)
171 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
175 srb
->hbmp
= SelectObject(srb
->hdcmem
, srb
->hbmp
);
176 DeleteDC(srb
->hdcmem
);
177 DeleteObject(srb
->hbmp
);
180 srb
->swrast
.Buffer
= NULL
;
185 sw_fb_renderbuffer_storage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
186 GLenum internalFormat
,
187 GLuint width
, GLuint height
)
189 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
190 struct sw_framebuffer
* fb
= CONTAINING_RECORD(srb
, struct sw_framebuffer
, frontbuffer
);
191 HDC hdc
= IntGetCurrentDC();
193 /* Don't bother if the size doesn't change */
194 if(rb
->Width
== width
&& rb
->Height
== height
)
197 /* Delete every objects which could have been used before */
198 sw_fb_renderbuffer_delete(&srb
->swrast
.Base
);
200 /* So the app wants to use the frontbuffer, allocate a DIB for it */
201 srb
->hbmp
= CreateDIBSection(
205 (void**)&srb
->swrast
.Buffer
,
209 ERR("Failed to create the DIB section for the front buffer, %lu.\n", GetLastError());
212 /* Create the DC and attach the DIB section to it */
213 srb
->hdcmem
= CreateCompatibleDC(hdc
);
214 assert(srb
->hdcmem
!= NULL
);
215 srb
->hbmp
= SelectObject(srb
->hdcmem
, srb
->hbmp
);
216 assert(srb
->hbmp
!= NULL
);
217 /* Set formats, width and height */
218 srb
->swrast
.Base
.Format
= pixel_formats
[fb
->format_index
].mesa
;
219 srb
->swrast
.Base
.Width
= width
;
220 srb
->swrast
.Base
.Height
= height
;
226 sw_init_renderbuffers(struct sw_framebuffer
*fb
)
228 _mesa_init_renderbuffer(&fb
->frontbuffer
.swrast
.Base
, 0);
229 fb
->frontbuffer
.swrast
.Base
.ClassID
= SW_FRONT_RENDERBUFFER_CLASS
;
230 fb
->frontbuffer
.swrast
.Base
.AllocStorage
= sw_fb_renderbuffer_storage
;
231 fb
->frontbuffer
.swrast
.Base
.Delete
= sw_fb_renderbuffer_delete
;
232 fb
->frontbuffer
.swrast
.Base
.InternalFormat
= GL_RGBA
;
233 fb
->frontbuffer
.swrast
.Base
._BaseFormat
= GL_RGBA
;
234 _mesa_remove_renderbuffer(fb
->gl_buffer
, BUFFER_FRONT_LEFT
);
235 _mesa_add_renderbuffer(fb
->gl_buffer
, BUFFER_FRONT_LEFT
, &fb
->frontbuffer
.swrast
.Base
);
237 if(fb
->flags
& SW_FB_DOUBLEBUFFERED
)
239 _mesa_init_renderbuffer(&fb
->backbuffer
.Base
, 0);
240 fb
->backbuffer
.Base
.ClassID
= SW_BACK_RENDERBUFFER_CLASS
;
241 fb
->backbuffer
.Base
.AllocStorage
= sw_bb_renderbuffer_storage
;
242 fb
->backbuffer
.Base
.Delete
= sw_bb_renderbuffer_delete
;
243 fb
->backbuffer
.Base
.InternalFormat
= GL_RGBA
;
244 fb
->backbuffer
.Base
._BaseFormat
= GL_RGBA
;
245 _mesa_remove_renderbuffer(fb
->gl_buffer
, BUFFER_BACK_LEFT
);
246 _mesa_add_renderbuffer(fb
->gl_buffer
, BUFFER_BACK_LEFT
, &fb
->backbuffer
.Base
);
253 sw_MapRenderbuffer(struct gl_context
*ctx
,
254 struct gl_renderbuffer
*rb
,
255 GLuint x
, GLuint y
, GLuint w
, GLuint h
,
257 GLubyte
**mapOut
, GLint
*rowStrideOut
)
259 if(rb
->ClassID
== SW_FRONT_RENDERBUFFER_CLASS
)
261 /* This is our front buffer */
262 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
263 struct sw_framebuffer
* fb
= CONTAINING_RECORD(srb
, struct sw_framebuffer
, frontbuffer
);
265 *rowStrideOut
= WIDTH_BYTES_ALIGN32(rb
->Width
, pixel_formats
[fb
->format_index
].color_bits
);
266 /* Remember where we "mapped" */
267 srb
->x
= x
; srb
->y
= y
; srb
->w
= w
; srb
->h
= h
;
268 /* Remember if we should write it later */
269 srb
->write
= !!(mode
& GL_MAP_WRITE_BIT
);
270 /* Get the bits, if needed */
271 if(mode
& GL_MAP_READ_BIT
)
273 BitBlt(srb
->hdcmem
, srb
->x
, srb
->y
, srb
->w
, srb
->h
,
274 IntGetCurrentDC(), srb
->x
, srb
->y
, SRCCOPY
);
277 *mapOut
= (BYTE
*)srb
->swrast
.Buffer
+ *rowStrideOut
*y
+ x
*pixel_formats
[fb
->format_index
].color_bits
/8;
281 if(rb
->ClassID
== SW_BACK_RENDERBUFFER_CLASS
)
283 /* This is our front buffer */
284 struct swrast_renderbuffer
* srb
= (struct swrast_renderbuffer
*)rb
;
285 const GLuint bpp
= _mesa_get_format_bytes(rb
->Format
);
287 *rowStrideOut
= srb
->RowStride
;
288 *mapOut
= (BYTE
*)srb
->Buffer
+ srb
->RowStride
*y
+ x
*bpp
;
292 /* Let mesa rasterizer take care of this */
293 _swrast_map_soft_renderbuffer(ctx
, rb
, x
, y
, w
, h
, mode
,
294 mapOut
, rowStrideOut
);
298 sw_UnmapRenderbuffer(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
)
300 if (rb
->ClassID
== SW_FRONT_RENDERBUFFER_CLASS
)
302 /* This is our front buffer */
303 struct sw_front_renderbuffer
* srb
= (struct sw_front_renderbuffer
*)rb
;
306 /* Copy the bits to our display */
307 BitBlt(IntGetCurrentDC(),
308 srb
->x
, srb
->y
, srb
->w
, srb
->h
,
309 srb
->hdcmem
, srb
->x
, srb
->y
, SRCCOPY
);
315 if(rb
->ClassID
== SW_BACK_RENDERBUFFER_CLASS
)
316 return; /* nothing to do */
318 /* Let mesa rasterizer take care of this */
319 _swrast_unmap_soft_renderbuffer(ctx
, rb
);
322 /* WGL <-> mesa glue */
323 static UINT
index_from_format(struct wgl_dc_data
* dc_data
, INT format
, BOOL
* doubleBuffered
)
326 INT nb_win_compat
= 0, start_win_compat
= 0;
330 *doubleBuffered
= FALSE
;
332 if(!(dc_data
->flags
& WGL_DC_OBJ_DC
))
333 return format
- 1; /* OBJ_MEMDC, not double buffered */
335 hdc
= GetDC(dc_data
->owner
.hwnd
);
337 /* Find the window compatible formats */
338 bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
339 for(index
= 0; index
<sizeof(pixel_formats
)/sizeof(pixel_formats
[0]); index
++)
341 if(pixel_formats
[index
].color_bits
== bpp
)
343 if(!start_win_compat
)
344 start_win_compat
= index
+1;
348 ReleaseDC(dc_data
->owner
.hwnd
, hdc
);
350 /* Double buffered format */
351 if(format
< (start_win_compat
+ nb_win_compat
))
353 if(format
>= start_win_compat
)
354 *doubleBuffered
= TRUE
;
358 return format
- nb_win_compat
- 1;
361 INT
sw_DescribePixelFormat(HDC hdc
, INT format
, UINT size
, PIXELFORMATDESCRIPTOR
* descr
)
364 INT nb_win_compat
= 0, start_win_compat
= 0;
365 INT ret
= sizeof(pixel_formats
)/sizeof(pixel_formats
[0]);
367 if(GetObjectType(hdc
) == OBJ_DC
)
369 /* Find the window compatible formats */
370 INT bpp
= GetDeviceCaps(hdc
, BITSPIXEL
);
371 for(index
= 0; index
<sizeof(pixel_formats
)/sizeof(pixel_formats
[0]); index
++)
373 if(pixel_formats
[index
].color_bits
== bpp
)
375 if(!start_win_compat
)
376 start_win_compat
= index
+1;
380 /* Add the double buffered formats */
381 ret
+= nb_win_compat
;
384 index
= (UINT
)format
- 1;
387 if((format
> ret
) || (size
!= sizeof(*descr
)))
391 descr
->dwFlags
= PFD_SUPPORT_GDI
| PFD_SUPPORT_OPENGL
| PFD_DRAW_TO_BITMAP
| PFD_GENERIC_FORMAT
;
392 /* See if this is a format compatible with the window */
393 if(format
>= start_win_compat
&& format
< (start_win_compat
+ nb_win_compat
*2) )
396 descr
->dwFlags
|= PFD_DRAW_TO_WINDOW
;
397 /* See if this should be double buffered */
398 if(format
< (start_win_compat
+ nb_win_compat
))
400 /* No GDI, no bitmap */
401 descr
->dwFlags
&= ~(PFD_SUPPORT_GDI
| PFD_DRAW_TO_BITMAP
);
402 descr
->dwFlags
|= PFD_DOUBLEBUFFER
;
405 /* Normalize the index */
406 if(format
>= start_win_compat
+ nb_win_compat
)
407 index
-= nb_win_compat
;
409 /* Fill the rest of the structure */
410 descr
->nSize
= sizeof(*descr
);
412 descr
->iPixelType
= PFD_TYPE_RGBA
;
413 descr
->cColorBits
= pixel_formats
[index
].color_bits
;
414 descr
->cRedBits
= pixel_formats
[index
].red_bits
;
415 descr
->cRedShift
= pixel_formats
[index
].red_shift
;
416 descr
->cGreenBits
= pixel_formats
[index
].green_bits
;
417 descr
->cGreenShift
= pixel_formats
[index
].green_shift
;
418 descr
->cBlueBits
= pixel_formats
[index
].blue_bits
;
419 descr
->cBlueShift
= pixel_formats
[index
].blue_shift
;
420 descr
->cAlphaBits
= pixel_formats
[index
].alpha_bits
;
421 descr
->cAlphaShift
= pixel_formats
[index
].alpha_shift
;
422 descr
->cAccumBits
= pixel_formats
[index
].accum_bits
;
423 descr
->cAccumRedBits
= pixel_formats
[index
].accum_bits
/ 4;
424 descr
->cAccumGreenBits
= pixel_formats
[index
].accum_bits
/ 4;
425 descr
->cAccumBlueBits
= pixel_formats
[index
].accum_bits
/ 4;
426 descr
->cAccumAlphaBits
= pixel_formats
[index
].accum_bits
/ 4;
427 descr
->cDepthBits
= pixel_formats
[index
].depth_bits
;
428 descr
->cStencilBits
= pixel_formats
[index
].stencil_bits
;
429 descr
->cAuxBuffers
= 0;
430 descr
->iLayerType
= PFD_MAIN_PLANE
;
434 BOOL
sw_SetPixelFormat(HDC hdc
, struct wgl_dc_data
* dc_data
, INT format
)
436 struct sw_framebuffer
* fb
;
439 assert(dc_data
->sw_data
== NULL
);
441 /* So, someone is crazy enough to ask for sw implementation. Announce it. */
442 TRACE("OpenGL software implementation START!\n");
444 /* allocate our structure */
445 fb
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, FIELD_OFFSET(struct sw_framebuffer
, bmi
.bmiColors
[2]));
448 /* Get the format index */
449 fb
->format_index
= index_from_format(dc_data
, format
, &doubleBuffered
);
450 fb
->flags
= doubleBuffered
? SW_FB_DOUBLEBUFFERED
: 0;
451 /* Set the bitmap info describing the framebuffer */
452 fb
->bmi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
453 fb
->bmi
.bmiHeader
.biPlanes
= 1;
454 fb
->bmi
.bmiHeader
.biBitCount
= pixel_formats
[fb
->format_index
].color_bits
;
455 fb
->bmi
.bmiHeader
.biCompression
= pixel_formats
[fb
->format_index
].bmp_compression
;
456 fb
->bmi
.bmiHeader
.biSizeImage
= 0;
457 fb
->bmi
.bmiHeader
.biXPelsPerMeter
= 0;
458 fb
->bmi
.bmiHeader
.biYPelsPerMeter
= 0;
459 fb
->bmi
.bmiHeader
.biClrUsed
= 0;
460 fb
->bmi
.bmiHeader
.biClrImportant
= 0;
461 *((DWORD
*)&fb
->bmi
.bmiColors
[0]) = pixel_formats
[fb
->format_index
].red_mask
;
462 *((DWORD
*)&fb
->bmi
.bmiColors
[1]) = pixel_formats
[fb
->format_index
].green_mask
;
463 *((DWORD
*)&fb
->bmi
.bmiColors
[2]) = pixel_formats
[fb
->format_index
].blue_mask
;
467 /* Allocate the visual structure describing the format */
468 fb
->gl_visual
= _mesa_create_visual(
469 !!(fb
->flags
& SW_FB_DOUBLEBUFFERED
),
470 GL_FALSE
, /* No stereoscopic support */
471 pixel_formats
[fb
->format_index
].red_bits
,
472 pixel_formats
[fb
->format_index
].green_bits
,
473 pixel_formats
[fb
->format_index
].blue_bits
,
474 pixel_formats
[fb
->format_index
].alpha_bits
,
475 pixel_formats
[fb
->format_index
].depth_bits
,
476 pixel_formats
[fb
->format_index
].stencil_bits
,
477 pixel_formats
[fb
->format_index
].accum_bits
,
478 pixel_formats
[fb
->format_index
].accum_bits
,
479 pixel_formats
[fb
->format_index
].accum_bits
,
480 pixel_formats
[fb
->format_index
].alpha_bits
?
481 pixel_formats
[fb
->format_index
].accum_bits
: 0);
485 ERR("Failed to allocate a GL visual.\n");
486 HeapFree(GetProcessHeap(), 0, fb
);
490 /* Allocate the framebuffer structure */
491 fb
->gl_buffer
= _mesa_create_framebuffer(fb
->gl_visual
);
492 if (!fb
->gl_buffer
) {
493 ERR("Failed to allocate the mesa framebuffer structure.\n");
494 _mesa_destroy_visual( fb
->gl_visual
);
495 HeapFree(GetProcessHeap(), 0, fb
);
499 /* Add the depth/stencil/accum buffers */
500 _swrast_add_soft_renderbuffers(fb
->gl_buffer
,
501 GL_FALSE
, /* color */
502 fb
->gl_visual
->haveDepthBuffer
,
503 fb
->gl_visual
->haveStencilBuffer
,
504 fb
->gl_visual
->haveAccumBuffer
,
505 GL_FALSE
, /* alpha */
506 GL_FALSE
/* aux */ );
508 /* Initialize our render buffers */
509 sw_init_renderbuffers(fb
);
511 /* Everything went fine */
512 dc_data
->sw_data
= fb
;
516 DHGLRC
sw_CreateContext(struct wgl_dc_data
* dc_data
)
518 struct sw_context
* sw_ctx
;
519 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
520 struct dd_function_table mesa_drv_functions
;
523 /* We use the mesa memory routines for this function */
524 sw_ctx
= CALLOC_STRUCT(sw_context
);
528 /* Set mesa default functions */
529 _mesa_init_driver_functions(&mesa_drv_functions
);
531 mesa_drv_functions
.GetString
= sw_get_string
;
532 mesa_drv_functions
.UpdateState
= sw_update_state
;
533 mesa_drv_functions
.GetBufferSize
= NULL
;
535 /* Initialize the context */
536 if(!_mesa_initialize_context(&sw_ctx
->mesa
,
542 ERR("Failed to initialize the mesa context.\n");
547 /* Initialize the "meta driver" */
548 _mesa_meta_init(&sw_ctx
->mesa
);
550 /* Initialize helpers */
551 if(!_swrast_CreateContext(&sw_ctx
->mesa
) ||
552 !_vbo_CreateContext(&sw_ctx
->mesa
) ||
553 !_tnl_CreateContext(&sw_ctx
->mesa
) ||
554 !_swsetup_CreateContext(&sw_ctx
->mesa
))
556 ERR("Failed initializing helpers.\n");
557 _mesa_free_context_data(&sw_ctx
->mesa
);
563 _swsetup_Wakeup(&sw_ctx
->mesa
);
565 /* Use TnL defaults */
566 tnl
= TNL_CONTEXT(&sw_ctx
->mesa
);
567 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
569 /* To map the display into user memory */
570 sw_ctx
->mesa
.Driver
.MapRenderbuffer
= sw_MapRenderbuffer
;
571 sw_ctx
->mesa
.Driver
.UnmapRenderbuffer
= sw_UnmapRenderbuffer
;
573 return (DHGLRC
)sw_ctx
;
576 BOOL
sw_DeleteContext(DHGLRC dhglrc
)
578 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
579 /* Those get clobbered by _mesa_free_context_data via _glapi_set{context,dispath_table} */
580 void* icd_save
= IntGetCurrentICDPrivate();
581 const GLDISPATCHTABLE
* table_save
= IntGetCurrentDispatchTable();
583 /* Destroy everything */
584 _mesa_meta_free( &sw_ctx
->mesa
);
586 _swsetup_DestroyContext( &sw_ctx
->mesa
);
587 _tnl_DestroyContext( &sw_ctx
->mesa
);
588 _vbo_DestroyContext( &sw_ctx
->mesa
);
589 _swrast_DestroyContext( &sw_ctx
->mesa
);
591 _mesa_free_context_data( &sw_ctx
->mesa
);
595 IntSetCurrentDispatchTable(table_save
);
596 IntSetCurrentICDPrivate(icd_save
);
601 PROC
sw_GetProcAddress(LPCSTR name
)
603 /* We don't support any extensions */
604 WARN("Asking for proc address %s, returning NULL.\n", name
);
608 BOOL
sw_CopyContext(DHGLRC dhglrcSrc
, DHGLRC dhglrcDst
, UINT mask
)
610 FIXME("Software wglCopyContext is UNIMPLEMENTED, mask %lx.\n", mask
);
614 BOOL
sw_ShareLists(DHGLRC dhglrcSrc
, DHGLRC dhglrcDst
)
616 struct sw_context
* sw_ctx_src
= (struct sw_context
*)dhglrcSrc
;
617 struct sw_context
* sw_ctx_dst
= (struct sw_context
*)dhglrcDst
;
619 /* See if it was already shared */
620 if(sw_ctx_dst
->mesa
.Shared
->RefCount
> 1)
623 /* Unreference the old, share the new */
624 _mesa_reference_shared_state(&sw_ctx_dst
->mesa
,
625 &sw_ctx_dst
->mesa
.Shared
,
626 sw_ctx_src
->mesa
.Shared
);
638 struct wgl_dc_data
* dc_data
= IntGetCurrentDcData();
639 struct sw_context
* ctx
= (struct sw_context
*)IntGetCurrentDHGLRC();
640 struct sw_framebuffer
* fb
;
641 PCWPSTRUCT pParams
= (PCWPSTRUCT
)lParam
;
643 if((!dc_data
) || (!ctx
))
646 if(!(dc_data
->flags
& WGL_DC_OBJ_DC
))
649 if((nCode
< 0) || (dc_data
->owner
.hwnd
!= pParams
->hwnd
) || (dc_data
->sw_data
== NULL
))
650 return CallNextHookEx(ctx
->hook
, nCode
, wParam
, lParam
);
652 fb
= dc_data
->sw_data
;
654 if (pParams
->message
== WM_WINDOWPOSCHANGED
)
656 /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to
657 * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
658 * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
659 * can be masked out by the application. */
660 LPWINDOWPOS lpWindowPos
= (LPWINDOWPOS
)pParams
->lParam
;
661 if((lpWindowPos
->flags
& SWP_SHOWWINDOW
) ||
662 !(lpWindowPos
->flags
& SWP_NOMOVE
) ||
663 !(lpWindowPos
->flags
& SWP_NOSIZE
))
665 /* Size in WINDOWPOS includes the window frame, so get the size
666 * of the client area via GetClientRect. */
669 GetClientRect(pParams
->hwnd
, &client_rect
);
670 width
= client_rect
.right
- client_rect
.left
;
671 height
= client_rect
.bottom
- client_rect
.top
;
672 /* Do not reallocate for minimized windows */
673 if(width
<= 0 || height
<= 0)
675 /* Update framebuffer size */
676 fb
->bmi
.bmiHeader
.biWidth
= width
;
677 fb
->bmi
.bmiHeader
.biHeight
= height
;
678 /* Propagate to mesa */
679 _mesa_resize_framebuffer(&ctx
->mesa
, fb
->gl_buffer
, width
, height
);
684 return CallNextHookEx(ctx
->hook
, nCode
, wParam
, lParam
);
687 BOOL
sw_SetContext(struct wgl_dc_data
* dc_data
, DHGLRC dhglrc
)
689 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
690 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
694 sw_update_state(&sw_ctx
->mesa
, 0);
696 /* Get framebuffer size */
697 if(dc_data
->flags
& WGL_DC_OBJ_DC
)
699 HWND hwnd
= dc_data
->owner
.hwnd
;
703 ERR("Physical DC without a window!\n");
706 if(!GetClientRect(hwnd
, &client_rect
))
708 ERR("GetClientRect failed!\n");
711 /* This is a physical DC. Setup the hook */
712 sw_ctx
->hook
= SetWindowsHookEx(WH_CALLWNDPROC
,
715 GetCurrentThreadId());
716 /* Calculate width & height */
717 width
= client_rect
.right
- client_rect
.left
;
718 height
= client_rect
.bottom
- client_rect
.top
;
724 HDC hdc
= dc_data
->owner
.hdc
;
726 if(fb
->flags
& SW_FB_DOUBLEBUFFERED
)
728 ERR("Memory DC called with a double buffered format.\n");
732 hbmp
= GetCurrentObject( hdc
, OBJ_BITMAP
);
738 if(GetObject(hbmp
, sizeof(bm
), &bm
) == 0)
740 ERR("GetObject failed!\n");
744 height
= bm
.bmHeight
;
747 if(!width
) width
= 1;
748 if(!height
) height
= 1;
750 fb
->bmi
.bmiHeader
.biWidth
= width
;
751 fb
->bmi
.bmiHeader
.biHeight
= height
;
753 /* Also make the mesa context current to mesa */
754 if(!_mesa_make_current(&sw_ctx
->mesa
, fb
->gl_buffer
, fb
->gl_buffer
))
756 ERR("_mesa_make_current filaed!\n");
760 /* Set the viewport if this is the first time we initialize this context */
761 if(sw_ctx
->mesa
.Viewport
.X
== 0 &&
762 sw_ctx
->mesa
.Viewport
.Y
== 0 &&
763 sw_ctx
->mesa
.Viewport
.Width
== 0 &&
764 sw_ctx
->mesa
.Viewport
.Height
== 0)
766 _mesa_set_viewport(&sw_ctx
->mesa
, 0, 0, width
, height
);
769 /* update the framebuffer size */
770 _mesa_resize_framebuffer(&sw_ctx
->mesa
, fb
->gl_buffer
, width
, height
);
776 void sw_ReleaseContext(DHGLRC dhglrc
)
778 struct sw_context
* sw_ctx
= (struct sw_context
*)dhglrc
;
780 /* Forward to mesa */
781 _mesa_make_current(NULL
, NULL
, NULL
);
786 UnhookWindowsHookEx(sw_ctx
->hook
);
791 BOOL
sw_SwapBuffers(HDC hdc
, struct wgl_dc_data
* dc_data
)
793 struct sw_framebuffer
* fb
= dc_data
->sw_data
;
794 struct sw_context
* sw_ctx
= (struct sw_context
*)IntGetCurrentDHGLRC();
798 _mesa_notifySwapBuffers(&sw_ctx
->mesa
);
800 if(!(fb
->flags
& SW_FB_DOUBLEBUFFERED
))
803 /* Upload to the display */
804 return (SetDIBitsToDevice(hdc
,
807 fb
->bmi
.bmiHeader
.biWidth
,
808 fb
->bmi
.bmiHeader
.biHeight
,
812 fb
->bmi
.bmiHeader
.biHeight
,
813 fb
->backbuffer
.Buffer
,
815 DIB_RGB_COLORS
) != 0);