Merge branch 'master' of ssh://git.freedesktop.org/git/mesa/mesa into pipe-video
[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/Xlibint.h>
30 #include <state_tracker/xlib_sw_winsys.h>
31 #include <util/u_memory.h>
32 #include <util/u_format.h>
33 #include <softpipe/sp_public.h>
34 #include <softpipe/sp_video_context.h>
35
36 struct vl_xsp_screen
37 {
38 struct vl_screen base;
39 Display *display;
40 int screen;
41 Visual visual;
42 struct xlib_drawable xdraw;
43 struct pipe_surface *drawable_surface;
44 };
45
46 struct pipe_surface*
47 vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
48 {
49 struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen;
50 Window root;
51 int x, y;
52 unsigned int width, height;
53 unsigned int border_width;
54 unsigned int depth;
55 struct pipe_resource templat, *drawable_tex;
56 struct pipe_surface *drawable_surface = NULL;
57
58 assert(vscreen);
59 assert(drawable != None);
60
61 if (XGetGeometry(xsp_screen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
62 return NULL;
63
64 xsp_screen->xdraw.drawable = drawable;
65
66 if (xsp_screen->drawable_surface) {
67 if (xsp_screen->drawable_surface->width == width &&
68 xsp_screen->drawable_surface->height == height) {
69 pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface);
70 return drawable_surface;
71 }
72 else
73 pipe_surface_reference(&xsp_screen->drawable_surface, NULL);
74 }
75
76 memset(&templat, 0, sizeof(struct pipe_resource));
77 templat.target = PIPE_TEXTURE_2D;
78 /* XXX: Need to figure out drawable's format */
79 templat.format = PIPE_FORMAT_B8G8R8X8_UNORM;
80 templat.last_level = 0;
81 templat.width0 = width;
82 templat.height0 = height;
83 templat.depth0 = 1;
84 templat.usage = PIPE_USAGE_DEFAULT;
85 templat.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET;
86 templat.flags = 0;
87
88 drawable_tex = vscreen->pscreen->resource_create(vscreen->pscreen, &templat);
89 if (!drawable_tex)
90 return NULL;
91
92 xsp_screen->drawable_surface = vscreen->pscreen->get_tex_surface(vscreen->pscreen, drawable_tex,
93 0, 0, 0,
94 templat.bind);
95 pipe_resource_reference(&drawable_tex, NULL);
96
97 if (!xsp_screen->drawable_surface)
98 return NULL;
99
100 pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface);
101
102 xsp_screen->xdraw.depth = 24/*util_format_get_blocksizebits(templat.format) /
103 util_format_get_blockwidth(templat.format)*/;
104
105 return drawable_surface;
106 }
107
108 void*
109 vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface)
110 {
111 struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vctx->vscreen;
112
113 assert(vctx);
114 assert(drawable_surface);
115 assert(xsp_screen->drawable_surface == drawable_surface);
116
117 return &xsp_screen->xdraw;
118 }
119
120 struct vl_screen*
121 vl_screen_create(Display *display, int screen)
122 {
123 struct vl_xsp_screen *xsp_screen;
124 struct sw_winsys *winsys;
125
126 assert(display);
127
128 xsp_screen = CALLOC_STRUCT(vl_xsp_screen);
129 if (!xsp_screen)
130 return NULL;
131
132 winsys = xlib_create_sw_winsys(display);
133 if (!winsys) {
134 FREE(xsp_screen);
135 return NULL;
136 }
137
138 xsp_screen->base.pscreen = softpipe_create_screen(winsys);
139 if (!xsp_screen->base.pscreen) {
140 winsys->destroy(winsys);
141 FREE(xsp_screen);
142 return NULL;
143 }
144
145 xsp_screen->display = display;
146 xsp_screen->screen = screen;
147 xsp_screen->xdraw.visual = XDefaultVisual(display, screen);
148
149 return &xsp_screen->base;
150 }
151
152 void vl_screen_destroy(struct vl_screen *vscreen)
153 {
154 struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen;
155
156 assert(vscreen);
157
158 pipe_surface_reference(&xsp_screen->drawable_surface, NULL);
159 vscreen->pscreen->destroy(vscreen->pscreen);
160 FREE(vscreen);
161 }
162
163 struct vl_context*
164 vl_video_create(struct vl_screen *vscreen,
165 enum pipe_video_profile profile,
166 enum pipe_video_chroma_format chroma_format,
167 unsigned width, unsigned height)
168 {
169 struct pipe_video_context *vpipe;
170 struct vl_context *vctx;
171
172 assert(vscreen);
173 assert(width && height);
174 assert(vscreen->pscreen->video_context_create);
175
176 vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen,
177 profile,
178 chroma_format,
179 width, height, NULL);
180 if (!vpipe)
181 return NULL;
182
183 vctx = CALLOC_STRUCT(vl_context);
184 if (!vctx) {
185 vpipe->destroy(vpipe);
186 return NULL;
187 }
188
189 vpipe->priv = vctx;
190 vctx->vpipe = vpipe;
191 vctx->vscreen = vscreen;
192
193 return vctx;
194 }
195
196 void vl_video_destroy(struct vl_context *vctx)
197 {
198 assert(vctx);
199
200 vctx->vpipe->destroy(vctx->vpipe);
201 FREE(vctx);
202 }