3 #include <pipe/p_winsys.h>
4 #include <pipe/p_state.h>
5 #include <pipe/p_inlines.h>
6 #include <util/u_memory.h>
7 #include <softpipe/sp_winsys.h>
9 /* pipe_winsys implementation */
11 struct xsp_pipe_winsys
13 struct pipe_winsys base
;
27 struct pipe_buffer base
;
28 boolean is_user_buffer
;
33 static struct pipe_buffer
* xsp_buffer_create(struct pipe_winsys
*pws
, unsigned alignment
, unsigned usage
, unsigned size
)
35 struct xsp_buffer
*buffer
;
39 buffer
= calloc(1, sizeof(struct xsp_buffer
));
40 buffer
->base
.refcount
= 1;
41 buffer
->base
.alignment
= alignment
;
42 buffer
->base
.usage
= usage
;
43 buffer
->base
.size
= size
;
44 buffer
->data
= align_malloc(size
, alignment
);
46 return (struct pipe_buffer
*)buffer
;
49 static struct pipe_buffer
* xsp_user_buffer_create(struct pipe_winsys
*pws
, void *data
, unsigned size
)
51 struct xsp_buffer
*buffer
;
55 buffer
= calloc(1, sizeof(struct xsp_buffer
));
56 buffer
->base
.refcount
= 1;
57 buffer
->base
.size
= size
;
58 buffer
->is_user_buffer
= TRUE
;
61 return (struct pipe_buffer
*)buffer
;
64 static void* xsp_buffer_map(struct pipe_winsys
*pws
, struct pipe_buffer
*buffer
, unsigned flags
)
66 struct xsp_buffer
*xsp_buf
= (struct xsp_buffer
*)buffer
;
71 xsp_buf
->mapped_data
= xsp_buf
->data
;
73 return xsp_buf
->mapped_data
;
76 static void xsp_buffer_unmap(struct pipe_winsys
*pws
, struct pipe_buffer
*buffer
)
78 struct xsp_buffer
*xsp_buf
= (struct xsp_buffer
*)buffer
;
83 xsp_buf
->mapped_data
= NULL
;
86 static void xsp_buffer_destroy(struct pipe_winsys
*pws
, struct pipe_buffer
*buffer
)
88 struct xsp_buffer
*xsp_buf
= (struct xsp_buffer
*)buffer
;
93 if (!xsp_buf
->is_user_buffer
)
94 align_free(xsp_buf
->data
);
99 static struct pipe_surface
* xsp_surface_alloc(struct pipe_winsys
*pws
)
101 struct pipe_surface
*surface
;
105 surface
= calloc(1, sizeof(struct pipe_surface
));
106 surface
->refcount
= 1;
107 surface
->winsys
= pws
;
112 /* Borrowed from Mesa's xm_winsys */
113 static unsigned int round_up(unsigned n
, unsigned multiple
)
115 return (n
+ multiple
- 1) & ~(multiple
- 1);
118 static int xsp_surface_alloc_storage
120 struct pipe_winsys
*pws
,
121 struct pipe_surface
*surface
,
124 enum pipe_format format
,
129 const unsigned int ALIGNMENT
= 1;
134 surface
->width
= width
;
135 surface
->height
= height
;
136 surface
->format
= format
;
137 pf_get_block(format
, &surface
->block
);
138 surface
->nblocksx
= pf_get_nblocksx(&surface
->block
, width
);
139 surface
->nblocksy
= pf_get_nblocksy(&surface
->block
, height
);
140 surface
->stride
= round_up(surface
->nblocksx
* surface
->block
.size
, ALIGNMENT
);
141 surface
->usage
= flags
;
142 surface
->buffer
= pws
->buffer_create(pws
, ALIGNMENT
, PIPE_BUFFER_USAGE_PIXEL
, surface
->stride
* surface
->nblocksy
);
147 static void xsp_surface_release(struct pipe_winsys
*pws
, struct pipe_surface
**surface
)
149 struct pipe_surface
*s
;
159 if (s
->refcount
== 0)
161 winsys_buffer_reference(pws
, &s
->buffer
, NULL
);
168 static void xsp_fence_reference(struct pipe_winsys
*pws
, struct pipe_fence_handle
**ptr
, struct pipe_fence_handle
*fence
)
175 static int xsp_fence_signalled(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
183 static int xsp_fence_finish(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
191 static void xsp_flush_frontbuffer(struct pipe_winsys
*pws
, struct pipe_surface
*surface
, void *context_private
)
193 struct xsp_pipe_winsys
*xsp_winsys
;
194 struct xsp_context
*xsp_context
;
198 assert(context_private
);
200 xsp_winsys
= (struct xsp_pipe_winsys
*)pws
;
201 xsp_context
= (struct xsp_context
*)context_private
;
203 if (!xsp_context
->drawable_bound
)
206 xsp_winsys
->fbimage
.width
= surface
->width
;
207 xsp_winsys
->fbimage
.height
= surface
->height
;
208 xsp_winsys
->fbimage
.bytes_per_line
= surface
->width
* (xsp_winsys
->fbimage
.bits_per_pixel
>> 3);
209 xsp_winsys
->fbimage
.data
= pipe_surface_map(surface
, 0);
213 xsp_context
->display
,
214 xsp_context
->drawable
,
215 XDefaultGC(xsp_context
->display
, xsp_context
->screen
),
216 &xsp_winsys
->fbimage
,
224 XFlush(xsp_context
->display
);
225 pipe_surface_unmap(surface
);
228 static const char* xsp_get_name(struct pipe_winsys
*pws
)
231 return "X11 SoftPipe";
234 /* Show starts here */
236 int bind_pipe_drawable(struct pipe_context
*pipe
, Drawable drawable
)
238 struct xsp_context
*xsp_context
;
242 xsp_context
= pipe
->priv
;
243 xsp_context
->drawable
= drawable
;
244 xsp_context
->drawable_bound
= 1;
249 int unbind_pipe_drawable(struct pipe_context
*pipe
)
251 struct xsp_context
*xsp_context
;
255 xsp_context
= pipe
->priv
;
256 xsp_context
->drawable_bound
= 0;
261 struct pipe_context
* create_pipe_context(Display
*display
, int screen
)
263 struct xsp_pipe_winsys
*xsp_winsys
;
264 struct xsp_context
*xsp_context
;
265 struct pipe_screen
*sp_screen
;
266 struct pipe_context
*sp_pipe
;
270 xsp_winsys
= calloc(1, sizeof(struct xsp_pipe_winsys
));
271 xsp_winsys
->base
.buffer_create
= xsp_buffer_create
;
272 xsp_winsys
->base
.user_buffer_create
= xsp_user_buffer_create
;
273 xsp_winsys
->base
.buffer_map
= xsp_buffer_map
;
274 xsp_winsys
->base
.buffer_unmap
= xsp_buffer_unmap
;
275 xsp_winsys
->base
.buffer_destroy
= xsp_buffer_destroy
;
276 xsp_winsys
->base
.surface_alloc
= xsp_surface_alloc
;
277 xsp_winsys
->base
.surface_alloc_storage
= xsp_surface_alloc_storage
;
278 xsp_winsys
->base
.surface_release
= xsp_surface_release
;
279 xsp_winsys
->base
.fence_reference
= xsp_fence_reference
;
280 xsp_winsys
->base
.fence_signalled
= xsp_fence_signalled
;
281 xsp_winsys
->base
.fence_finish
= xsp_fence_finish
;
282 xsp_winsys
->base
.flush_frontbuffer
= xsp_flush_frontbuffer
;
283 xsp_winsys
->base
.get_name
= xsp_get_name
;
286 /* XXX: Can't use the returned XImage* directly,
287 since we don't have control over winsys destruction
288 and we wouldn't be able to free it */
289 XImage
*template = XCreateImage
292 XDefaultVisual(display
, XDefaultScreen(display
)),
293 XDefaultDepth(display
, XDefaultScreen(display
)),
297 0, /* Don't know the width and height until flush_frontbuffer */
303 memcpy(&xsp_winsys
->fbimage
, template, sizeof(XImage
));
304 XInitImage(&xsp_winsys
->fbimage
);
306 XDestroyImage(template);
309 sp_screen
= softpipe_create_screen((struct pipe_winsys
*)xsp_winsys
);
310 sp_pipe
= softpipe_create(sp_screen
, (struct pipe_winsys
*)xsp_winsys
, NULL
);
312 xsp_context
= calloc(1, sizeof(struct xsp_context
));
313 xsp_context
->display
= display
;
314 xsp_context
->screen
= screen
;
316 sp_pipe
->priv
= xsp_context
;
321 int destroy_pipe_context(struct pipe_context
*pipe
)
323 struct pipe_screen
*screen
;
324 struct pipe_winsys
*winsys
;
328 screen
= pipe
->screen
;
329 winsys
= pipe
->winsys
;
332 screen
->destroy(screen
);