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 "gdi/gdi_sw_winsys.h"
37 #include "common/native_helper.h"
38 #include "common/native.h"
41 struct native_display base
;
44 struct native_event_handler
*event_handler
;
46 struct native_config
*configs
;
51 struct native_surface base
;
54 enum pipe_format color_format
;
56 struct gdi_display
*gdpy
;
58 unsigned int server_stamp
;
59 unsigned int client_stamp
;
61 struct resource_surface
*rsurf
;
64 static INLINE
struct gdi_display
*
65 gdi_display(const struct native_display
*ndpy
)
67 return (struct gdi_display
*) ndpy
;
70 static INLINE
struct gdi_surface
*
71 gdi_surface(const struct native_surface
*nsurf
)
73 return (struct gdi_surface
*) nsurf
;
77 * Update the geometry of the surface. This is a slow functions.
80 gdi_surface_update_geometry(struct native_surface
*nsurf
)
82 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
86 GetClientRect(gsurf
->hWnd
, &rect
);
87 w
= rect
.right
- rect
.left
;
88 h
= rect
.bottom
- rect
.top
;
90 if (resource_surface_set_size(gsurf
->rsurf
, w
, h
))
91 gsurf
->server_stamp
++;
95 * Update the buffers of the surface.
98 gdi_surface_update_buffers(struct native_surface
*nsurf
, uint buffer_mask
)
100 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
102 if (gsurf
->client_stamp
!= gsurf
->server_stamp
) {
103 gdi_surface_update_geometry(&gsurf
->base
);
104 gsurf
->client_stamp
= gsurf
->server_stamp
;
107 return resource_surface_add_resources(gsurf
->rsurf
, buffer_mask
);
111 * Emulate an invalidate event.
114 gdi_surface_invalidate(struct native_surface
*nsurf
)
116 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
117 struct gdi_display
*gdpy
= gsurf
->gdpy
;
119 gsurf
->server_stamp
++;
120 gdpy
->event_handler
->invalid_surface(&gdpy
->base
,
121 &gsurf
->base
, gsurf
->server_stamp
);
125 gdi_surface_flush_frontbuffer(struct native_surface
*nsurf
)
127 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
131 hDC
= GetDC(gsurf
->hWnd
);
132 ret
= resource_surface_present(gsurf
->rsurf
,
133 NATIVE_ATTACHMENT_FRONT_LEFT
, (void *) hDC
);
134 ReleaseDC(gsurf
->hWnd
, hDC
);
136 /* force buffers to be updated in next validation call */
137 gdi_surface_invalidate(&gsurf
->base
);
143 gdi_surface_swap_buffers(struct native_surface
*nsurf
)
145 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
149 hDC
= GetDC(gsurf
->hWnd
);
150 ret
= resource_surface_present(gsurf
->rsurf
,
151 NATIVE_ATTACHMENT_BACK_LEFT
, (void *) hDC
);
152 ReleaseDC(gsurf
->hWnd
, hDC
);
154 resource_surface_swap_buffers(gsurf
->rsurf
,
155 NATIVE_ATTACHMENT_FRONT_LEFT
, NATIVE_ATTACHMENT_BACK_LEFT
, TRUE
);
156 /* the front/back buffers have been swapped */
157 gdi_surface_invalidate(&gsurf
->base
);
163 gdi_surface_validate(struct native_surface
*nsurf
, uint attachment_mask
,
164 unsigned int *seq_num
, struct pipe_resource
**textures
,
165 int *width
, int *height
)
167 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
170 if (!gdi_surface_update_buffers(&gsurf
->base
, attachment_mask
))
174 *seq_num
= gsurf
->client_stamp
;
177 resource_surface_get_resources(gsurf
->rsurf
, textures
, attachment_mask
);
179 resource_surface_get_size(gsurf
->rsurf
, &w
, &h
);
189 gdi_surface_wait(struct native_surface
*nsurf
)
195 gdi_surface_destroy(struct native_surface
*nsurf
)
197 struct gdi_surface
*gsurf
= gdi_surface(nsurf
);
199 resource_surface_destroy(gsurf
->rsurf
);
203 static struct native_surface
*
204 gdi_display_create_window_surface(struct native_display
*ndpy
,
205 EGLNativeWindowType win
,
206 const struct native_config
*nconf
)
208 struct gdi_display
*gdpy
= gdi_display(ndpy
);
209 struct gdi_surface
*gsurf
;
211 gsurf
= CALLOC_STRUCT(gdi_surface
);
216 gsurf
->color_format
= nconf
->color_format
;
217 gsurf
->hWnd
= (HWND
) win
;
219 gsurf
->rsurf
= resource_surface_create(gdpy
->base
.screen
,
221 PIPE_BIND_RENDER_TARGET
|
222 PIPE_BIND_SAMPLER_VIEW
|
223 PIPE_BIND_DISPLAY_TARGET
|
230 /* initialize the geometry */
231 gdi_surface_update_geometry(&gsurf
->base
);
233 gsurf
->base
.destroy
= gdi_surface_destroy
;
234 gsurf
->base
.swap_buffers
= gdi_surface_swap_buffers
;
235 gsurf
->base
.flush_frontbuffer
= gdi_surface_flush_frontbuffer
;
236 gsurf
->base
.validate
= gdi_surface_validate
;
237 gsurf
->base
.wait
= gdi_surface_wait
;
243 fill_color_formats(struct native_display
*ndpy
, enum pipe_format formats
[8])
245 struct pipe_screen
*screen
= ndpy
->screen
;
248 enum pipe_format candidates
[] = {
250 PIPE_FORMAT_B8G8R8A8_UNORM
,
251 PIPE_FORMAT_A8R8G8B8_UNORM
,
253 PIPE_FORMAT_B8G8R8X8_UNORM
,
254 PIPE_FORMAT_X8R8G8B8_UNORM
,
256 PIPE_FORMAT_B5G6R5_UNORM
259 assert(Elements(candidates
) <= 8);
261 for (i
= 0; i
< Elements(candidates
); i
++) {
262 if (screen
->is_format_supported(screen
, candidates
[i
],
263 PIPE_TEXTURE_2D
, 0, PIPE_BIND_RENDER_TARGET
, 0))
264 formats
[count
++] = candidates
[i
];
270 static const struct native_config
**
271 gdi_display_get_configs(struct native_display
*ndpy
, int *num_configs
)
273 struct gdi_display
*gdpy
= gdi_display(ndpy
);
274 const struct native_config
**configs
;
278 if (!gdpy
->configs
) {
279 enum pipe_format formats
[8];
282 count
= fill_color_formats(&gdpy
->base
, formats
);
284 gdpy
->configs
= CALLOC(count
, sizeof(*gdpy
->configs
));
288 for (i
= 0; i
< count
; i
++) {
289 struct native_config
*nconf
= &gdpy
->configs
[i
];
292 (1 << NATIVE_ATTACHMENT_FRONT_LEFT
) |
293 (1 << NATIVE_ATTACHMENT_BACK_LEFT
);
294 nconf
->color_format
= formats
[i
];
296 nconf
->window_bit
= TRUE
;
297 nconf
->slow_config
= TRUE
;
300 gdpy
->num_configs
= count
;
303 configs
= MALLOC(gdpy
->num_configs
* sizeof(*configs
));
305 for (i
= 0; i
< gdpy
->num_configs
; i
++)
306 configs
[i
] = (const struct native_config
*) &gdpy
->configs
[i
];
308 *num_configs
= gdpy
->num_configs
;
314 gdi_display_get_param(struct native_display
*ndpy
,
315 enum native_param_type param
)
320 case NATIVE_PARAM_USE_NATIVE_BUFFER
:
321 /* private buffers are allocated */
333 gdi_display_destroy(struct native_display
*ndpy
)
335 struct gdi_display
*gdpy
= gdi_display(ndpy
);
340 gdpy
->base
.screen
->destroy(gdpy
->base
.screen
);
345 static struct native_display
*
346 gdi_create_display(HDC hDC
, struct native_event_handler
*event_handler
,
349 struct gdi_display
*gdpy
;
350 struct sw_winsys
*winsys
;
352 gdpy
= CALLOC_STRUCT(gdi_display
);
357 gdpy
->event_handler
= event_handler
;
358 gdpy
->base
.user_data
= user_data
;
360 winsys
= gdi_create_sw_winsys();
366 gdpy
->base
.screen
= gdpy
->event_handler
->create_sw_screen(winsys
);
367 if (!gdpy
->base
.screen
) {
369 winsys
->destroy(winsys
);
374 gdpy
->base
.destroy
= gdi_display_destroy
;
375 gdpy
->base
.get_param
= gdi_display_get_param
;
377 gdpy
->base
.get_configs
= gdi_display_get_configs
;
378 gdpy
->base
.create_window_surface
= gdi_display_create_window_surface
;
383 static struct native_display
*
384 native_create_display(void *dpy
, struct native_event_handler
*event_handler
,
387 return gdi_create_display((HDC
) dpy
, event_handler
, user_data
);
390 static const struct native_platform gdi_platform
= {
392 native_create_display
395 const struct native_platform
*
396 native_get_gdi_platform(void)
398 return &gdi_platform
;