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 /* Borrowed from Mesa's xm_winsys */
100 static unsigned int round_up(unsigned n
, unsigned multiple
)
102 return (n
+ multiple
- 1) & ~(multiple
- 1);
105 static struct pipe_buffer
* xsp_surface_buffer_create
107 struct pipe_winsys
*pws
,
110 enum pipe_format format
,
115 const unsigned int ALIGNMENT
= 1;
116 struct pipe_format_block block
;
117 unsigned nblocksx
, nblocksy
;
119 pf_get_block(format
, &block
);
120 nblocksx
= pf_get_nblocksx(&block
, width
);
121 nblocksy
= pf_get_nblocksy(&block
, height
);
122 *stride
= round_up(nblocksx
* block
.size
, ALIGNMENT
);
124 return winsys
->buffer_create(winsys
, ALIGNMENT
,
129 static void xsp_fence_reference(struct pipe_winsys
*pws
, struct pipe_fence_handle
**ptr
, struct pipe_fence_handle
*fence
)
136 static int xsp_fence_signalled(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
144 static int xsp_fence_finish(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
152 static void xsp_flush_frontbuffer(struct pipe_winsys
*pws
, struct pipe_surface
*surface
, void *context_private
)
154 struct xsp_pipe_winsys
*xsp_winsys
;
155 struct xsp_context
*xsp_context
;
159 assert(context_private
);
161 xsp_winsys
= (struct xsp_pipe_winsys
*)pws
;
162 xsp_context
= (struct xsp_context
*)context_private
;
164 if (!xsp_context
->drawable_bound
)
167 xsp_winsys
->fbimage
.width
= surface
->width
;
168 xsp_winsys
->fbimage
.height
= surface
->height
;
169 xsp_winsys
->fbimage
.bytes_per_line
= surface
->width
* (xsp_winsys
->fbimage
.bits_per_pixel
>> 3);
170 xsp_winsys
->fbimage
.data
= pipe_surface_map(surface
, 0);
174 xsp_context
->display
,
175 xsp_context
->drawable
,
176 XDefaultGC(xsp_context
->display
, xsp_context
->screen
),
177 &xsp_winsys
->fbimage
,
185 XFlush(xsp_context
->display
);
186 pipe_surface_unmap(surface
);
189 static const char* xsp_get_name(struct pipe_winsys
*pws
)
192 return "X11 SoftPipe";
195 /* Show starts here */
197 int bind_pipe_drawable(struct pipe_context
*pipe
, Drawable drawable
)
199 struct xsp_context
*xsp_context
;
203 xsp_context
= pipe
->priv
;
204 xsp_context
->drawable
= drawable
;
205 xsp_context
->drawable_bound
= 1;
210 int unbind_pipe_drawable(struct pipe_context
*pipe
)
212 struct xsp_context
*xsp_context
;
216 xsp_context
= pipe
->priv
;
217 xsp_context
->drawable_bound
= 0;
222 struct pipe_context
* create_pipe_context(Display
*display
, int screen
)
224 struct xsp_pipe_winsys
*xsp_winsys
;
225 struct xsp_context
*xsp_context
;
226 struct pipe_screen
*sp_screen
;
227 struct pipe_context
*sp_pipe
;
231 xsp_winsys
= calloc(1, sizeof(struct xsp_pipe_winsys
));
232 xsp_winsys
->base
.buffer_create
= xsp_buffer_create
;
233 xsp_winsys
->base
.user_buffer_create
= xsp_user_buffer_create
;
234 xsp_winsys
->base
.buffer_map
= xsp_buffer_map
;
235 xsp_winsys
->base
.buffer_unmap
= xsp_buffer_unmap
;
236 xsp_winsys
->base
.buffer_destroy
= xsp_buffer_destroy
;
237 xsp_winsys
->base
.surface_buffer_create
= xsp_surface_buffer_create
;
238 xsp_winsys
->base
.fence_reference
= xsp_fence_reference
;
239 xsp_winsys
->base
.fence_signalled
= xsp_fence_signalled
;
240 xsp_winsys
->base
.fence_finish
= xsp_fence_finish
;
241 xsp_winsys
->base
.flush_frontbuffer
= xsp_flush_frontbuffer
;
242 xsp_winsys
->base
.get_name
= xsp_get_name
;
245 /* XXX: Can't use the returned XImage* directly,
246 since we don't have control over winsys destruction
247 and we wouldn't be able to free it */
248 XImage
*template = XCreateImage
251 XDefaultVisual(display
, XDefaultScreen(display
)),
252 XDefaultDepth(display
, XDefaultScreen(display
)),
256 0, /* Don't know the width and height until flush_frontbuffer */
262 memcpy(&xsp_winsys
->fbimage
, template, sizeof(XImage
));
263 XInitImage(&xsp_winsys
->fbimage
);
265 XDestroyImage(template);
268 sp_screen
= softpipe_create_screen((struct pipe_winsys
*)xsp_winsys
);
269 sp_pipe
= softpipe_create(sp_screen
, (struct pipe_winsys
*)xsp_winsys
, NULL
);
271 xsp_context
= calloc(1, sizeof(struct xsp_context
));
272 xsp_context
->display
= display
;
273 xsp_context
->screen
= screen
;
275 sp_pipe
->priv
= xsp_context
;
280 int destroy_pipe_context(struct pipe_context
*pipe
)
282 struct pipe_screen
*screen
;
283 struct pipe_winsys
*winsys
;
287 screen
= pipe
->screen
;
288 winsys
= pipe
->winsys
;
291 screen
->destroy(screen
);