Revert "mesa: Remove pointless comparison of unsigned integer with a negative constant."
[mesa.git] / src / gallium / winsys / g3dvl / xlib / xsp_winsys.c
1 /**************************************************************************
2 *
3 * Copyright 2009 Younes Manton.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <vl_winsys.h>
29 #include <X11/Xutil.h>
30 #include <util/u_simple_screen.h>
31 #include <pipe/p_state.h>
32 #include <util/u_inlines.h>
33 #include <util/u_format.h>
34 #include <util/u_memory.h>
35 #include <util/u_math.h>
36 #include <softpipe/sp_winsys.h>
37 #include <softpipe/sp_video_context.h>
38 #include <softpipe/sp_texture.h>
39
40 /* pipe_winsys implementation */
41
42 struct xsp_pipe_winsys
43 {
44 struct pipe_winsys base;
45 Display *display;
46 int screen;
47 XImage *fbimage;
48 };
49
50 struct xsp_context
51 {
52 Drawable drawable;
53
54 void (*pipe_destroy)(struct pipe_video_context *vpipe);
55 };
56
57 struct xsp_buffer
58 {
59 struct pipe_buffer base;
60 boolean is_user_buffer;
61 void *data;
62 void *mapped_data;
63 };
64
65 static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size)
66 {
67 struct xsp_buffer *buffer;
68
69 assert(pws);
70
71 buffer = calloc(1, sizeof(struct xsp_buffer));
72 pipe_reference_init(&buffer->base.reference, 1);
73 buffer->base.alignment = alignment;
74 buffer->base.usage = usage;
75 buffer->base.size = size;
76 buffer->data = align_malloc(size, alignment);
77
78 return (struct pipe_buffer*)buffer;
79 }
80
81 static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size)
82 {
83 struct xsp_buffer *buffer;
84
85 assert(pws);
86
87 buffer = calloc(1, sizeof(struct xsp_buffer));
88 pipe_reference_init(&buffer->base.reference, 1);
89 buffer->base.size = size;
90 buffer->is_user_buffer = TRUE;
91 buffer->data = data;
92
93 return (struct pipe_buffer*)buffer;
94 }
95
96 static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags)
97 {
98 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
99
100 assert(pws);
101 assert(buffer);
102
103 xsp_buf->mapped_data = xsp_buf->data;
104
105 return xsp_buf->mapped_data;
106 }
107
108 static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer)
109 {
110 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
111
112 assert(pws);
113 assert(buffer);
114
115 xsp_buf->mapped_data = NULL;
116 }
117
118 static void xsp_buffer_destroy(struct pipe_buffer *buffer)
119 {
120 struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
121
122 assert(buffer);
123
124 if (!xsp_buf->is_user_buffer)
125 align_free(xsp_buf->data);
126
127 free(xsp_buf);
128 }
129
130 static struct pipe_buffer* xsp_surface_buffer_create
131 (
132 struct pipe_winsys *pws,
133 unsigned width,
134 unsigned height,
135 enum pipe_format format,
136 unsigned usage,
137 unsigned tex_usage,
138 unsigned *stride
139 )
140 {
141 const unsigned int ALIGNMENT = 1;
142 unsigned nblocksy;
143
144 nblocksy = util_format_get_nblocksy(format, height);
145 *stride = align(util_format_get_stride(format, width), ALIGNMENT);
146
147 return pws->buffer_create(pws, ALIGNMENT, usage,
148 *stride * nblocksy);
149 }
150
151 static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence)
152 {
153 assert(pws);
154 assert(ptr);
155 assert(fence);
156 }
157
158 static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
159 {
160 assert(pws);
161 assert(fence);
162
163 return 0;
164 }
165
166 static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
167 {
168 assert(pws);
169 assert(fence);
170
171 return 0;
172 }
173
174 static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private)
175 {
176 struct xsp_pipe_winsys *xsp_winsys;
177 struct xsp_context *xsp_context;
178
179 assert(pws);
180 assert(surface);
181 assert(context_private);
182
183 xsp_winsys = (struct xsp_pipe_winsys*)pws;
184 xsp_context = (struct xsp_context*)context_private;
185 xsp_winsys->fbimage->width = surface->width;
186 xsp_winsys->fbimage->height = surface->height;
187 xsp_winsys->fbimage->bytes_per_line = surface->width * (xsp_winsys->fbimage->bits_per_pixel >> 3);
188 xsp_winsys->fbimage->data = (char*)((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset;
189
190 XPutImage
191 (
192 xsp_winsys->display, xsp_context->drawable,
193 XDefaultGC(xsp_winsys->display, xsp_winsys->screen),
194 xsp_winsys->fbimage, 0, 0, 0, 0,
195 surface->width, surface->height
196 );
197 XFlush(xsp_winsys->display);
198 }
199
200 static const char* xsp_get_name(struct pipe_winsys *pws)
201 {
202 assert(pws);
203 return "X11 SoftPipe";
204 }
205
206 static void xsp_destroy(struct pipe_winsys *pws)
207 {
208 struct xsp_pipe_winsys *xsp_winsys = (struct xsp_pipe_winsys*)pws;
209
210 assert(pws);
211
212 /* XDestroyImage() wants to free the data as well */
213 xsp_winsys->fbimage->data = NULL;
214
215 XDestroyImage(xsp_winsys->fbimage);
216 FREE(xsp_winsys);
217 }
218
219 /* Called through pipe_video_context::destroy() */
220 static void xsp_pipe_destroy(struct pipe_video_context *vpipe)
221 {
222 struct xsp_context *xsp_context;
223
224 assert(vpipe);
225
226 xsp_context = vpipe->priv;
227
228 /* Call the original destroy */
229 xsp_context->pipe_destroy(vpipe);
230
231 FREE(xsp_context);
232 }
233
234 /* Show starts here */
235
236 Drawable
237 vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable)
238 {
239 struct xsp_context *xsp_context;
240 Drawable old_drawable;
241
242 assert(vpipe);
243
244 xsp_context = vpipe->priv;
245 old_drawable = xsp_context->drawable;
246 xsp_context->drawable = drawable;
247
248 return old_drawable;
249 }
250
251 struct pipe_screen*
252 vl_screen_create(Display *display, int screen)
253 {
254 struct xsp_pipe_winsys *xsp_winsys;
255
256 assert(display);
257
258 xsp_winsys = CALLOC_STRUCT(xsp_pipe_winsys);
259 if (!xsp_winsys)
260 return NULL;
261
262 xsp_winsys->base.buffer_create = xsp_buffer_create;
263 xsp_winsys->base.user_buffer_create = xsp_user_buffer_create;
264 xsp_winsys->base.buffer_map = xsp_buffer_map;
265 xsp_winsys->base.buffer_unmap = xsp_buffer_unmap;
266 xsp_winsys->base.buffer_destroy = xsp_buffer_destroy;
267 xsp_winsys->base.surface_buffer_create = xsp_surface_buffer_create;
268 xsp_winsys->base.fence_reference = xsp_fence_reference;
269 xsp_winsys->base.fence_signalled = xsp_fence_signalled;
270 xsp_winsys->base.fence_finish = xsp_fence_finish;
271 xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer;
272 xsp_winsys->base.get_name = xsp_get_name;
273 xsp_winsys->base.destroy = xsp_destroy;
274 xsp_winsys->display = display;
275 xsp_winsys->screen = screen;
276 xsp_winsys->fbimage = XCreateImage
277 (
278 display,
279 XDefaultVisual(display, screen),
280 XDefaultDepth(display, screen),
281 ZPixmap,
282 0,
283 NULL,
284 0, /* Don't know the width and height until flush_frontbuffer */
285 0,
286 32,
287 0
288 );
289
290 if (!xsp_winsys->fbimage) {
291 FREE(xsp_winsys);
292 return NULL;
293 }
294
295 XInitImage(xsp_winsys->fbimage);
296
297 return softpipe_create_screen(&xsp_winsys->base);
298 }
299
300 struct pipe_video_context*
301 vl_video_create(Display *display, int screen,
302 struct pipe_screen *p_screen,
303 enum pipe_video_profile profile,
304 enum pipe_video_chroma_format chroma_format,
305 unsigned width, unsigned height)
306 {
307 struct pipe_video_context *vpipe;
308 struct xsp_context *xsp_context;
309
310 assert(p_screen);
311 assert(width && height);
312
313 vpipe = sp_video_create(p_screen, profile, chroma_format, width, height);
314 if (!vpipe)
315 return NULL;
316
317 xsp_context = CALLOC_STRUCT(xsp_context);
318 if (!xsp_context) {
319 vpipe->destroy(vpipe);
320 return NULL;
321 }
322
323 /* Override this so we can free our xsp_context when the pipe is freed */
324 xsp_context->pipe_destroy = vpipe->destroy;
325 vpipe->destroy = xsp_pipe_destroy;
326
327 vpipe->priv = xsp_context;
328
329 return vpipe;
330 }