2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 LunarG Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 * Chia-I Wu <olv@lunarg.com>
31 #include "pipe/p_compiler.h"
32 #include "util/u_memory.h"
33 #include "util/u_format.h"
34 #include "util/u_inlines.h"
35 #include "target-helpers/wrap_screen.h"
36 #include "llvmpipe/lp_public.h"
37 #include "softpipe/sp_public.h"
38 #include "gdi/gdi_sw_winsys.h"
40 #include "common/native_helper.h"
41 #include "common/native.h"
44 struct native_display base
;
47 struct native_event_handler
*event_handler
;
49 struct native_config
*configs
;
54 struct native_surface base
;
57 enum pipe_format color_format
;
59 struct gdi_display
*gdpy
;
61 unsigned int server_stamp
;
62 unsigned int client_stamp
;
64 struct resource_surface
*rsurf
;
67 static INLINE
struct gdi_display
*
68 gdi_display(const struct native_display
*ndpy
)
70 return (struct gdi_display
*) ndpy
;
73 static INLINE
struct gdi_surface
*
74 gdi_surface(const struct native_surface
*nsurf
)
76 return (struct gdi_surface
*) nsurf
;
80 * Update the geometry of the surface. This is a slow functions.
83 gdi_surface_update_geometry(struct native_surface
*nsurf
)
85 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
89 GetClientRect(gsurf
->hWnd
, &rect
);
90 w
= rect
.right
- rect
.left
;
91 h
= rect
.bottom
- rect
.top
;
93 if (resource_surface_set_size(gsurf
->rsurf
, w
, h
))
94 gsurf
->server_stamp
++;
98 * Update the buffers of the surface.
101 gdi_surface_update_buffers(struct native_surface
*nsurf
, uint buffer_mask
)
103 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
106 gdi_surface_update_geometry(&gsurf
->base
);
107 ret
= resource_surface_add_resources(gsurf
->rsurf
, buffer_mask
);
108 gsurf
->client_stamp
= gsurf
->server_stamp
;
114 * Emulate an invalidate event.
117 gdi_surface_invalidate(struct native_surface
*nsurf
)
119 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
120 struct gdi_display
*gdpy
= gsurf
->gdpy
;
122 gsurf
->server_stamp
++;
123 gdpy
->event_handler
->invalid_surface(&gdpy
->base
,
124 &gsurf
->base
, gsurf
->server_stamp
);
128 gdi_surface_flush_frontbuffer(struct native_surface
*nsurf
)
130 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
134 hDC
= GetDC(gsurf
->hWnd
);
135 ret
= resource_surface_present(gsurf
->rsurf
,
136 NATIVE_ATTACHMENT_FRONT_LEFT
, (void *) hDC
);
137 ReleaseDC(gsurf
->hWnd
, hDC
);
139 /* force buffers to be updated in next validation call */
140 gdi_surface_invalidate(&gsurf
->base
);
146 gdi_surface_swap_buffers(struct native_surface
*nsurf
)
148 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
152 hDC
= GetDC(gsurf
->hWnd
);
153 ret
= resource_surface_present(gsurf
->rsurf
,
154 NATIVE_ATTACHMENT_BACK_LEFT
, (void *) hDC
);
155 ReleaseDC(gsurf
->hWnd
, hDC
);
157 resource_surface_swap_buffers(gsurf
->rsurf
,
158 NATIVE_ATTACHMENT_FRONT_LEFT
, NATIVE_ATTACHMENT_BACK_LEFT
, TRUE
);
159 /* the front/back buffers have been swapped */
160 gdi_surface_invalidate(&gsurf
->base
);
166 gdi_surface_validate(struct native_surface
*nsurf
, uint attachment_mask
,
167 unsigned int *seq_num
, struct pipe_resource
**textures
,
168 int *width
, int *height
)
170 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
173 if (gsurf
->client_stamp
!= gsurf
->server_stamp
) {
174 if (!gdi_surface_update_buffers(&gsurf
->base
, attachment_mask
))
179 *seq_num
= gsurf
->client_stamp
;
182 resource_surface_get_resources(gsurf
->rsurf
, textures
, attachment_mask
);
184 resource_surface_get_size(gsurf
->rsurf
, &w
, &h
);
194 gdi_surface_wait(struct native_surface
*nsurf
)
200 gdi_surface_destroy(struct native_surface
*nsurf
)
202 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
204 resource_surface_destroy(gsurf
->rsurf
);
208 static struct native_surface
*
209 gdi_display_create_window_surface(struct native_display
*ndpy
,
210 EGLNativeWindowType win
,
211 const struct native_config
*nconf
)
213 struct gdi_display
*gdpy
= gdi_display(ndpy
);
214 struct gdi_surface
*gsurf
;
216 gsurf
= CALLOC_STRUCT(gdi_surface
);
221 gsurf
->color_format
= nconf
->color_format
;
222 gsurf
->hWnd
= (HWND
) win
;
224 gsurf
->rsurf
= resource_surface_create(gdpy
->base
.screen
,
226 PIPE_BIND_RENDER_TARGET
|
227 PIPE_BIND_SAMPLER_VIEW
|
228 PIPE_BIND_DISPLAY_TARGET
|
235 /* initialize the geometry */
236 gdi_surface_update_buffers(&gsurf
->base
, 0x0);
238 gsurf
->base
.destroy
= gdi_surface_destroy
;
239 gsurf
->base
.swap_buffers
= gdi_surface_swap_buffers
;
240 gsurf
->base
.flush_frontbuffer
= gdi_surface_flush_frontbuffer
;
241 gsurf
->base
.validate
= gdi_surface_validate
;
242 gsurf
->base
.wait
= gdi_surface_wait
;
248 fill_color_formats(struct native_display
*ndpy
, enum pipe_format formats
[8])
250 struct pipe_screen
*screen
= ndpy
->screen
;
253 enum pipe_format candidates
[] = {
255 PIPE_FORMAT_B8G8R8A8_UNORM
,
256 PIPE_FORMAT_A8R8G8B8_UNORM
,
258 PIPE_FORMAT_B8G8R8X8_UNORM
,
259 PIPE_FORMAT_X8R8G8B8_UNORM
,
261 PIPE_FORMAT_B5G6R5_UNORM
264 assert(Elements(candidates
) <= 8);
266 for (i
= 0; i
< Elements(candidates
); i
++) {
267 if (screen
->is_format_supported(screen
, candidates
[i
],
268 PIPE_TEXTURE_2D
, 0, PIPE_BIND_RENDER_TARGET
, 0))
269 formats
[count
++] = candidates
[i
];
275 static const struct native_config
**
276 gdi_display_get_configs(struct native_display
*ndpy
, int *num_configs
)
278 struct gdi_display
*gdpy
= gdi_display(ndpy
);
279 const struct native_config
**configs
;
283 if (!gdpy
->configs
) {
284 enum pipe_format formats
[8];
287 count
= fill_color_formats(&gdpy
->base
, formats
);
289 gdpy
->configs
= CALLOC(count
, sizeof(*gdpy
->configs
));
293 for (i
= 0; i
< count
; i
++) {
294 struct native_config
*nconf
= &gdpy
->configs
[i
];
297 (1 << NATIVE_ATTACHMENT_FRONT_LEFT
) |
298 (1 << NATIVE_ATTACHMENT_BACK_LEFT
);
299 nconf
->color_format
= formats
[i
];
301 nconf
->window_bit
= TRUE
;
302 nconf
->slow_config
= TRUE
;
305 gdpy
->num_configs
= count
;
308 configs
= MALLOC(gdpy
->num_configs
* sizeof(*configs
));
310 for (i
= 0; i
< gdpy
->num_configs
; i
++)
311 configs
[i
] = (const struct native_config
*) &gdpy
->configs
[i
];
313 *num_configs
= gdpy
->num_configs
;
319 gdi_display_get_param(struct native_display
*ndpy
,
320 enum native_param_type param
)
325 case NATIVE_PARAM_USE_NATIVE_BUFFER
:
326 /* private buffers are allocated */
338 gdi_display_destroy(struct native_display
*ndpy
)
340 struct gdi_display
*gdpy
= gdi_display(ndpy
);
345 gdpy
->base
.screen
->destroy(gdpy
->base
.screen
);
350 static struct native_display
*
351 gdi_create_display(HDC hDC
, struct pipe_screen
*screen
,
352 struct native_event_handler
*event_handler
)
354 struct gdi_display
*gdpy
;
356 gdpy
= CALLOC_STRUCT(gdi_display
);
361 gdpy
->event_handler
= event_handler
;
363 gdpy
->base
.screen
= screen
;
365 gdpy
->base
.destroy
= gdi_display_destroy
;
366 gdpy
->base
.get_param
= gdi_display_get_param
;
368 gdpy
->base
.get_configs
= gdi_display_get_configs
;
369 gdpy
->base
.create_window_surface
= gdi_display_create_window_surface
;
374 static struct pipe_screen
*
375 gdi_create_screen(void)
377 struct sw_winsys
*winsys
;
378 struct pipe_screen
*screen
= NULL
;
380 winsys
= gdi_create_sw_winsys();
384 #if defined(GALLIUM_LLVMPIPE)
385 if (!screen
&& !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE
))
386 screen
= llvmpipe_create_screen(winsys
);
389 screen
= softpipe_create_screen(winsys
);
393 winsys
->destroy(winsys
);
397 return gallium_wrap_screen(screen
);
400 struct native_probe
*
401 native_create_probe(EGLNativeDisplayType dpy
)
406 enum native_probe_result
407 native_get_probe_result(struct native_probe
*nprobe
)
409 return NATIVE_PROBE_UNKNOWN
;
413 native_get_name(void)
418 struct native_display
*
419 native_create_display(EGLNativeDisplayType dpy
,
420 struct native_event_handler
*event_handler
)
422 struct pipe_screen
*screen
;
424 screen
= gdi_create_screen();
428 return gdi_create_display((HDC
) dpy
, screen
, event_handler
);