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