3 #include <pipe/internal/p_winsys_screen.h>
4 #include <pipe/p_state.h>
5 #include <pipe/p_inlines.h>
6 #include <util/u_memory.h>
7 #include <util/u_math.h>
8 #include <softpipe/sp_winsys.h>
9 #include <softpipe/sp_texture.h>
11 /* pipe_winsys implementation */
13 struct xsp_pipe_winsys
15 struct pipe_winsys base
;
29 struct pipe_buffer base
;
30 boolean is_user_buffer
;
35 static struct pipe_buffer
* xsp_buffer_create(struct pipe_winsys
*pws
, unsigned alignment
, unsigned usage
, unsigned size
)
37 struct xsp_buffer
*buffer
;
41 buffer
= calloc(1, sizeof(struct xsp_buffer
));
42 pipe_reference_init(&buffer
->base
.reference
, 1);
43 buffer
->base
.alignment
= alignment
;
44 buffer
->base
.usage
= usage
;
45 buffer
->base
.size
= size
;
46 buffer
->data
= align_malloc(size
, alignment
);
48 return (struct pipe_buffer
*)buffer
;
51 static struct pipe_buffer
* xsp_user_buffer_create(struct pipe_winsys
*pws
, void *data
, unsigned size
)
53 struct xsp_buffer
*buffer
;
57 buffer
= calloc(1, sizeof(struct xsp_buffer
));
58 pipe_reference_init(&buffer
->base
.reference
, 1);
59 buffer
->base
.size
= size
;
60 buffer
->is_user_buffer
= TRUE
;
63 return (struct pipe_buffer
*)buffer
;
66 static void* xsp_buffer_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buffer
, unsigned flags
)
68 struct xsp_buffer
*xsp_buf
= (struct xsp_buffer
*)buffer
;
73 xsp_buf
->mapped_data
= xsp_buf
->data
;
75 return xsp_buf
->mapped_data
;
78 static void xsp_buffer_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buffer
)
80 struct xsp_buffer
*xsp_buf
= (struct xsp_buffer
*)buffer
;
85 xsp_buf
->mapped_data
= NULL
;
88 static void xsp_buffer_destroy(struct pipe_winsys
*pws
, struct pipe_buffer
*buffer
)
90 struct xsp_buffer
*xsp_buf
= (struct xsp_buffer
*)buffer
;
95 if (!xsp_buf
->is_user_buffer
)
96 align_free(xsp_buf
->data
);
101 static struct pipe_buffer
* xsp_surface_buffer_create
103 struct pipe_winsys
*pws
,
106 enum pipe_format format
,
111 const unsigned int ALIGNMENT
= 1;
112 struct pipe_format_block block
;
113 unsigned nblocksx
, nblocksy
;
115 pf_get_block(format
, &block
);
116 nblocksx
= pf_get_nblocksx(&block
, width
);
117 nblocksy
= pf_get_nblocksy(&block
, height
);
118 *stride
= align(nblocksx
* block
.size
, ALIGNMENT
);
120 return pws
->buffer_create(pws
, ALIGNMENT
,
125 static void xsp_fence_reference(struct pipe_winsys
*pws
, struct pipe_fence_handle
**ptr
, struct pipe_fence_handle
*fence
)
132 static int xsp_fence_signalled(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
140 static int xsp_fence_finish(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
148 static void xsp_flush_frontbuffer(struct pipe_winsys
*pws
, struct pipe_surface
*surface
, void *context_private
)
150 struct xsp_pipe_winsys
*xsp_winsys
;
151 struct xsp_context
*xsp_context
;
155 assert(context_private
);
157 xsp_winsys
= (struct xsp_pipe_winsys
*)pws
;
158 xsp_context
= (struct xsp_context
*)context_private
;
160 if (!xsp_context
->drawable_bound
)
163 xsp_winsys
->fbimage
.width
= surface
->width
;
164 xsp_winsys
->fbimage
.height
= surface
->height
;
165 xsp_winsys
->fbimage
.bytes_per_line
= surface
->width
* (xsp_winsys
->fbimage
.bits_per_pixel
>> 3);
166 xsp_winsys
->fbimage
.data
= ((struct xsp_buffer
*)softpipe_texture(surface
->texture
)->buffer
)->data
+ surface
->offset
;
170 xsp_context
->display
,
171 xsp_context
->drawable
,
172 XDefaultGC(xsp_context
->display
, xsp_context
->screen
),
173 &xsp_winsys
->fbimage
,
181 XFlush(xsp_context
->display
);
184 static const char* xsp_get_name(struct pipe_winsys
*pws
)
187 return "X11 SoftPipe";
190 /* Show starts here */
192 int bind_pipe_drawable(struct pipe_context
*pipe
, Drawable drawable
)
194 struct xsp_context
*xsp_context
;
198 xsp_context
= pipe
->priv
;
199 xsp_context
->drawable
= drawable
;
200 xsp_context
->drawable_bound
= 1;
205 int unbind_pipe_drawable(struct pipe_context
*pipe
)
207 struct xsp_context
*xsp_context
;
211 xsp_context
= pipe
->priv
;
212 xsp_context
->drawable_bound
= 0;
217 struct pipe_context
* create_pipe_context(Display
*display
, int screen
)
219 struct xsp_pipe_winsys
*xsp_winsys
;
220 struct xsp_context
*xsp_context
;
221 struct pipe_screen
*sp_screen
;
222 struct pipe_context
*sp_pipe
;
226 xsp_winsys
= calloc(1, sizeof(struct xsp_pipe_winsys
));
227 xsp_winsys
->base
.buffer_create
= xsp_buffer_create
;
228 xsp_winsys
->base
.user_buffer_create
= xsp_user_buffer_create
;
229 xsp_winsys
->base
.buffer_map
= xsp_buffer_map
;
230 xsp_winsys
->base
.buffer_unmap
= xsp_buffer_unmap
;
231 xsp_winsys
->base
.buffer_destroy
= xsp_buffer_destroy
;
232 xsp_winsys
->base
.surface_buffer_create
= xsp_surface_buffer_create
;
233 xsp_winsys
->base
.fence_reference
= xsp_fence_reference
;
234 xsp_winsys
->base
.fence_signalled
= xsp_fence_signalled
;
235 xsp_winsys
->base
.fence_finish
= xsp_fence_finish
;
236 xsp_winsys
->base
.flush_frontbuffer
= xsp_flush_frontbuffer
;
237 xsp_winsys
->base
.get_name
= xsp_get_name
;
240 /* XXX: Can't use the returned XImage* directly,
241 since we don't have control over winsys destruction
242 and we wouldn't be able to free it */
243 XImage
*template = XCreateImage
246 XDefaultVisual(display
, XDefaultScreen(display
)),
247 XDefaultDepth(display
, XDefaultScreen(display
)),
251 0, /* Don't know the width and height until flush_frontbuffer */
257 memcpy(&xsp_winsys
->fbimage
, template, sizeof(XImage
));
258 XInitImage(&xsp_winsys
->fbimage
);
260 XDestroyImage(template);
263 sp_screen
= softpipe_create_screen((struct pipe_winsys
*)xsp_winsys
);
264 sp_pipe
= softpipe_create(sp_screen
);
266 xsp_context
= calloc(1, sizeof(struct xsp_context
));
267 xsp_context
->display
= display
;
268 xsp_context
->screen
= screen
;
270 sp_pipe
->priv
= xsp_context
;
275 int destroy_pipe_context(struct pipe_context
*pipe
)
277 struct pipe_screen
*screen
;
278 struct pipe_winsys
*winsys
;
282 screen
= pipe
->screen
;
283 winsys
= pipe
->winsys
;
286 screen
->destroy(screen
);