softpipe: Simplify softpipe_create's prototype.
[mesa.git] / src / gallium / winsys / g3dvl / xsp_winsys.c
1 #include "vl_winsys.h"
2 #include <X11/Xutil.h>
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>
10
11 /* pipe_winsys implementation */
12
13 struct xsp_pipe_winsys
14 {
15 struct pipe_winsys base;
16 XImage fbimage;
17 };
18
19 struct xsp_context
20 {
21 Display *display;
22 int screen;
23 Drawable drawable;
24 int drawable_bound;
25 };
26
27 struct xsp_buffer
28 {
29 struct pipe_buffer base;
30 boolean is_user_buffer;
31 void *data;
32 void *mapped_data;
33 };
34
35 static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size)
36 {
37 struct xsp_buffer *buffer;
38
39 assert(pws);
40
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);
47
48 return (struct pipe_buffer*)buffer;
49 }
50
51 static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size)
52 {
53 struct xsp_buffer *buffer;
54
55 assert(pws);
56
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;
61 buffer->data = data;
62
63 return (struct pipe_buffer*)buffer;
64 }
65
66 static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags)
67 {
68 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
69
70 assert(pws);
71 assert(buffer);
72
73 xsp_buf->mapped_data = xsp_buf->data;
74
75 return xsp_buf->mapped_data;
76 }
77
78 static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer)
79 {
80 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
81
82 assert(pws);
83 assert(buffer);
84
85 xsp_buf->mapped_data = NULL;
86 }
87
88 static void xsp_buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buffer)
89 {
90 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
91
92 assert(pws);
93 assert(buffer);
94
95 if (!xsp_buf->is_user_buffer)
96 align_free(xsp_buf->data);
97
98 free(xsp_buf);
99 }
100
101 static struct pipe_buffer* xsp_surface_buffer_create
102 (
103 struct pipe_winsys *pws,
104 unsigned width,
105 unsigned height,
106 enum pipe_format format,
107 unsigned usage,
108 unsigned *stride
109 )
110 {
111 const unsigned int ALIGNMENT = 1;
112 struct pipe_format_block block;
113 unsigned nblocksx, nblocksy;
114
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);
119
120 return pws->buffer_create(pws, ALIGNMENT,
121 usage,
122 *stride * nblocksy);
123 }
124
125 static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence)
126 {
127 assert(pws);
128 assert(ptr);
129 assert(fence);
130 }
131
132 static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
133 {
134 assert(pws);
135 assert(fence);
136
137 return 0;
138 }
139
140 static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
141 {
142 assert(pws);
143 assert(fence);
144
145 return 0;
146 }
147
148 static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private)
149 {
150 struct xsp_pipe_winsys *xsp_winsys;
151 struct xsp_context *xsp_context;
152
153 assert(pws);
154 assert(surface);
155 assert(context_private);
156
157 xsp_winsys = (struct xsp_pipe_winsys*)pws;
158 xsp_context = (struct xsp_context*)context_private;
159
160 if (!xsp_context->drawable_bound)
161 return;
162
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;
167
168 XPutImage
169 (
170 xsp_context->display,
171 xsp_context->drawable,
172 XDefaultGC(xsp_context->display, xsp_context->screen),
173 &xsp_winsys->fbimage,
174 0,
175 0,
176 0,
177 0,
178 surface->width,
179 surface->height
180 );
181 XFlush(xsp_context->display);
182 }
183
184 static const char* xsp_get_name(struct pipe_winsys *pws)
185 {
186 assert(pws);
187 return "X11 SoftPipe";
188 }
189
190 /* Show starts here */
191
192 int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable)
193 {
194 struct xsp_context *xsp_context;
195
196 assert(pipe);
197
198 xsp_context = pipe->priv;
199 xsp_context->drawable = drawable;
200 xsp_context->drawable_bound = 1;
201
202 return 0;
203 }
204
205 int unbind_pipe_drawable(struct pipe_context *pipe)
206 {
207 struct xsp_context *xsp_context;
208
209 assert(pipe);
210
211 xsp_context = pipe->priv;
212 xsp_context->drawable_bound = 0;
213
214 return 0;
215 }
216
217 struct pipe_context* create_pipe_context(Display *display, int screen)
218 {
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;
223
224 assert(display);
225
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;
238
239 {
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
244 (
245 display,
246 XDefaultVisual(display, XDefaultScreen(display)),
247 XDefaultDepth(display, XDefaultScreen(display)),
248 ZPixmap,
249 0,
250 NULL,
251 0, /* Don't know the width and height until flush_frontbuffer */
252 0,
253 32,
254 0
255 );
256
257 memcpy(&xsp_winsys->fbimage, template, sizeof(XImage));
258 XInitImage(&xsp_winsys->fbimage);
259
260 XDestroyImage(template);
261 }
262
263 sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys);
264 sp_pipe = softpipe_create(sp_screen);
265
266 xsp_context = calloc(1, sizeof(struct xsp_context));
267 xsp_context->display = display;
268 xsp_context->screen = screen;
269
270 sp_pipe->priv = xsp_context;
271
272 return sp_pipe;
273 }
274
275 int destroy_pipe_context(struct pipe_context *pipe)
276 {
277 struct pipe_screen *screen;
278 struct pipe_winsys *winsys;
279
280 assert(pipe);
281
282 screen = pipe->screen;
283 winsys = pipe->winsys;
284 free(pipe->priv);
285 pipe->destroy(pipe);
286 screen->destroy(screen);
287 free(winsys);
288
289 return 0;
290 }