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
,
112 const unsigned int ALIGNMENT
= 1;
113 struct pipe_format_block block
;
114 unsigned nblocksx
, nblocksy
;
116 pf_get_block(format
, &block
);
117 nblocksx
= pf_get_nblocksx(&block
, width
);
118 nblocksy
= pf_get_nblocksy(&block
, height
);
119 *stride
= align(nblocksx
* block
.size
, ALIGNMENT
);
121 return pws
->buffer_create(pws
, ALIGNMENT
,
126 static void xsp_fence_reference(struct pipe_winsys
*pws
, struct pipe_fence_handle
**ptr
, struct pipe_fence_handle
*fence
)
133 static int xsp_fence_signalled(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
141 static int xsp_fence_finish(struct pipe_winsys
*pws
, struct pipe_fence_handle
*fence
, unsigned flag
)
149 static void xsp_flush_frontbuffer(struct pipe_winsys
*pws
, struct pipe_surface
*surface
, void *context_private
)
151 struct xsp_pipe_winsys
*xsp_winsys
;
152 struct xsp_context
*xsp_context
;
156 assert(context_private
);
158 xsp_winsys
= (struct xsp_pipe_winsys
*)pws
;
159 xsp_context
= (struct xsp_context
*)context_private
;
161 if (!xsp_context
->drawable_bound
)
164 xsp_winsys
->fbimage
.width
= surface
->width
;
165 xsp_winsys
->fbimage
.height
= surface
->height
;
166 xsp_winsys
->fbimage
.bytes_per_line
= surface
->width
* (xsp_winsys
->fbimage
.bits_per_pixel
>> 3);
167 xsp_winsys
->fbimage
.data
= ((struct xsp_buffer
*)softpipe_texture(surface
->texture
)->buffer
)->data
+ surface
->offset
;
171 xsp_context
->display
,
172 xsp_context
->drawable
,
173 XDefaultGC(xsp_context
->display
, xsp_context
->screen
),
174 &xsp_winsys
->fbimage
,
182 XFlush(xsp_context
->display
);
185 static const char* xsp_get_name(struct pipe_winsys
*pws
)
188 return "X11 SoftPipe";
191 /* Show starts here */
193 int bind_pipe_drawable(struct pipe_context
*pipe
, Drawable drawable
)
195 struct xsp_context
*xsp_context
;
199 xsp_context
= pipe
->priv
;
200 xsp_context
->drawable
= drawable
;
201 xsp_context
->drawable_bound
= 1;
206 int unbind_pipe_drawable(struct pipe_context
*pipe
)
208 struct xsp_context
*xsp_context
;
212 xsp_context
= pipe
->priv
;
213 xsp_context
->drawable_bound
= 0;
218 struct pipe_context
* create_pipe_context(Display
*display
, int screen
)
220 struct xsp_pipe_winsys
*xsp_winsys
;
221 struct xsp_context
*xsp_context
;
222 struct pipe_screen
*sp_screen
;
223 struct pipe_context
*sp_pipe
;
227 xsp_winsys
= calloc(1, sizeof(struct xsp_pipe_winsys
));
228 xsp_winsys
->base
.buffer_create
= xsp_buffer_create
;
229 xsp_winsys
->base
.user_buffer_create
= xsp_user_buffer_create
;
230 xsp_winsys
->base
.buffer_map
= xsp_buffer_map
;
231 xsp_winsys
->base
.buffer_unmap
= xsp_buffer_unmap
;
232 xsp_winsys
->base
.buffer_destroy
= xsp_buffer_destroy
;
233 xsp_winsys
->base
.surface_buffer_create
= xsp_surface_buffer_create
;
234 xsp_winsys
->base
.fence_reference
= xsp_fence_reference
;
235 xsp_winsys
->base
.fence_signalled
= xsp_fence_signalled
;
236 xsp_winsys
->base
.fence_finish
= xsp_fence_finish
;
237 xsp_winsys
->base
.flush_frontbuffer
= xsp_flush_frontbuffer
;
238 xsp_winsys
->base
.get_name
= xsp_get_name
;
241 /* XXX: Can't use the returned XImage* directly,
242 since we don't have control over winsys destruction
243 and we wouldn't be able to free it */
244 XImage
*template = XCreateImage
247 XDefaultVisual(display
, XDefaultScreen(display
)),
248 XDefaultDepth(display
, XDefaultScreen(display
)),
252 0, /* Don't know the width and height until flush_frontbuffer */
258 memcpy(&xsp_winsys
->fbimage
, template, sizeof(XImage
));
259 XInitImage(&xsp_winsys
->fbimage
);
261 XDestroyImage(template);
264 sp_screen
= softpipe_create_screen((struct pipe_winsys
*)xsp_winsys
);
265 sp_pipe
= softpipe_create(sp_screen
);
267 xsp_context
= calloc(1, sizeof(struct xsp_context
));
268 xsp_context
->display
= display
;
269 xsp_context
->screen
= screen
;
271 sp_pipe
->priv
= xsp_context
;
276 int destroy_pipe_context(struct pipe_context
*pipe
)
278 struct pipe_screen
*screen
;
279 struct pipe_winsys
*winsys
;
283 screen
= pipe
->screen
;
284 winsys
= pipe
->winsys
;
287 screen
->destroy(screen
);