[g3dvl] make pipe_context mandatory for creation pipe_video_context
[mesa.git] / src / gallium / auxiliary / vl / vl_context.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 <pipe/p_video_context.h>
29
30 #include <util/u_memory.h>
31 #include <util/u_rect.h>
32 #include <util/u_video.h>
33
34 #include "vl_context.h"
35 #include "vl_compositor.h"
36 #include "vl_mpeg12_decoder.h"
37
38 static void
39 vl_context_destroy(struct pipe_video_context *context)
40 {
41 struct vl_context *ctx = (struct vl_context*)context;
42
43 assert(context);
44
45 FREE(ctx);
46 }
47
48 static struct pipe_surface *
49 vl_context_create_surface(struct pipe_video_context *context,
50 struct pipe_resource *resource,
51 const struct pipe_surface *templ)
52 {
53 struct vl_context *ctx = (struct vl_context*)context;
54
55 assert(ctx);
56
57 return ctx->pipe->create_surface(ctx->pipe, resource, templ);
58 }
59
60 static struct pipe_sampler_view *
61 vl_context_create_sampler_view(struct pipe_video_context *context,
62 struct pipe_resource *resource,
63 const struct pipe_sampler_view *templ)
64 {
65 struct vl_context *ctx = (struct vl_context*)context;
66
67 assert(ctx);
68
69 return ctx->pipe->create_sampler_view(ctx->pipe, resource, templ);
70 }
71
72 static void
73 vl_context_upload_sampler(struct pipe_video_context *context,
74 struct pipe_sampler_view *dst,
75 const struct pipe_box *dst_box,
76 const void *src, unsigned src_stride,
77 unsigned src_x, unsigned src_y)
78 {
79 struct vl_context *ctx = (struct vl_context*)context;
80 struct pipe_transfer *transfer;
81 void *map;
82
83 assert(context);
84 assert(dst);
85 assert(dst_box);
86 assert(src);
87
88 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
89 if (!transfer)
90 return;
91
92 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
93 if (!transfer)
94 goto error_map;
95
96 util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
97 dst_box->width, dst_box->height,
98 src, src_stride, src_x, src_y);
99
100 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
101
102 error_map:
103 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
104 }
105
106 static void
107 vl_context_clear_sampler(struct pipe_video_context *context,
108 struct pipe_sampler_view *dst,
109 const struct pipe_box *dst_box,
110 const float *rgba)
111 {
112 struct vl_context *ctx = (struct vl_context*)context;
113 struct pipe_transfer *transfer;
114 union util_color uc;
115 void *map;
116 unsigned i;
117
118 assert(context);
119 assert(dst);
120 assert(dst_box);
121 assert(rgba);
122
123 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
124 if (!transfer)
125 return;
126
127 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
128 if (!transfer)
129 goto error_map;
130
131 for ( i = 0; i < 4; ++i)
132 uc.f[i] = rgba[i];
133
134 util_fill_rect(map, dst->texture->format, transfer->stride, 0, 0,
135 dst_box->width, dst_box->height, &uc);
136
137 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
138
139 error_map:
140 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
141 }
142
143 static struct pipe_video_decoder *
144 vl_context_create_decoder(struct pipe_video_context *context,
145 enum pipe_video_profile profile,
146 enum pipe_video_entrypoint entrypoint,
147 enum pipe_video_chroma_format chroma_format,
148 unsigned width, unsigned height)
149 {
150 struct vl_context *ctx = (struct vl_context*)context;
151 unsigned buffer_width, buffer_height;
152 bool pot_buffers;
153
154 assert(context);
155 assert(width > 0 && height > 0);
156
157 pot_buffers = !ctx->base.screen->get_video_param(ctx->base.screen, profile, PIPE_VIDEO_CAP_NPOT_TEXTURES);
158
159 buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH);
160 buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT);
161
162 switch (u_reduce_video_profile(profile)) {
163 case PIPE_VIDEO_CODEC_MPEG12:
164 return vl_create_mpeg12_decoder(context, ctx->pipe, profile, entrypoint,
165 chroma_format, buffer_width, buffer_height);
166 default:
167 return NULL;
168 }
169 return NULL;
170 }
171
172 static struct pipe_video_buffer *
173 vl_context_create_buffer(struct pipe_video_context *context,
174 enum pipe_format buffer_format,
175 enum pipe_video_chroma_format chroma_format,
176 unsigned width, unsigned height)
177 {
178 struct vl_context *ctx = (struct vl_context*)context;
179 const enum pipe_format *resource_formats;
180 struct pipe_video_buffer *result;
181 unsigned buffer_width, buffer_height;
182 bool pot_buffers;
183
184 assert(context);
185 assert(width > 0 && height > 0);
186
187 pot_buffers = !ctx->base.screen->get_video_param
188 (
189 ctx->base.screen,
190 PIPE_VIDEO_PROFILE_UNKNOWN,
191 PIPE_VIDEO_CAP_NPOT_TEXTURES
192 );
193
194 resource_formats = vl_video_buffer_formats(ctx->pipe->screen, buffer_format);
195 if (!resource_formats)
196 return NULL;
197
198 buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH);
199 buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT);
200
201 result = vl_video_buffer_init(context, ctx->pipe,
202 buffer_width, buffer_height, 1,
203 chroma_format,
204 resource_formats,
205 PIPE_USAGE_STATIC);
206 if (result) // TODO move format handling into vl_video_buffer
207 result->buffer_format = buffer_format;
208
209 return result;
210 }
211
212 static struct pipe_video_compositor *
213 vl_context_create_compositor(struct pipe_video_context *context)
214 {
215 struct vl_context *ctx = (struct vl_context*)context;
216
217 assert(context);
218
219 return vl_compositor_init(context, ctx->pipe);
220 }
221
222 struct pipe_video_context *
223 vl_create_context(struct pipe_context *pipe)
224 {
225 struct vl_context *ctx;
226
227 ctx = CALLOC_STRUCT(vl_context);
228
229 if (!ctx)
230 return NULL;
231
232 ctx->base.screen = pipe->screen;
233
234 ctx->base.destroy = vl_context_destroy;
235 ctx->base.create_surface = vl_context_create_surface;
236 ctx->base.create_sampler_view = vl_context_create_sampler_view;
237 ctx->base.clear_sampler = vl_context_clear_sampler;
238 ctx->base.upload_sampler = vl_context_upload_sampler;
239 ctx->base.create_decoder = vl_context_create_decoder;
240 ctx->base.create_buffer = vl_context_create_buffer;
241 ctx->base.create_compositor = vl_context_create_compositor;
242
243 ctx->pipe = pipe;
244
245 return &ctx->base;
246 }