[g3dvl] and finally split the decoder part out of the 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 ctx->pipe->destroy(ctx->pipe);
46
47 FREE(ctx);
48 }
49
50 static int
51 vl_context_get_param(struct pipe_video_context *context, int param)
52 {
53 struct vl_context *ctx = (struct vl_context*)context;
54
55 assert(context);
56
57 if (param == PIPE_CAP_NPOT_TEXTURES)
58 return !ctx->pot_buffers;
59
60 debug_printf("vl_context: Unknown PIPE_CAP %d\n", param);
61 return 0;
62 }
63
64 static boolean
65 vl_context_is_format_supported(struct pipe_video_context *context,
66 enum pipe_format format,
67 unsigned usage)
68 {
69 struct vl_context *ctx = (struct vl_context*)context;
70
71 assert(context);
72
73 return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format,
74 PIPE_TEXTURE_2D,
75 0, usage);
76 }
77
78 static struct pipe_surface *
79 vl_context_create_surface(struct pipe_video_context *context,
80 struct pipe_resource *resource,
81 const struct pipe_surface *templ)
82 {
83 struct vl_context *ctx = (struct vl_context*)context;
84
85 assert(ctx);
86
87 return ctx->pipe->create_surface(ctx->pipe, resource, templ);
88 }
89
90 static struct pipe_sampler_view *
91 vl_context_create_sampler_view(struct pipe_video_context *context,
92 struct pipe_resource *resource,
93 const struct pipe_sampler_view *templ)
94 {
95 struct vl_context *ctx = (struct vl_context*)context;
96
97 assert(ctx);
98
99 return ctx->pipe->create_sampler_view(ctx->pipe, resource, templ);
100 }
101
102 static void
103 vl_context_upload_sampler(struct pipe_video_context *context,
104 struct pipe_sampler_view *dst,
105 const struct pipe_box *dst_box,
106 const void *src, unsigned src_stride,
107 unsigned src_x, unsigned src_y)
108 {
109 struct vl_context *ctx = (struct vl_context*)context;
110 struct pipe_transfer *transfer;
111 void *map;
112
113 assert(context);
114 assert(dst);
115 assert(dst_box);
116 assert(src);
117
118 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
119 if (!transfer)
120 return;
121
122 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
123 if (!transfer)
124 goto error_map;
125
126 util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
127 dst_box->width, dst_box->height,
128 src, src_stride, src_x, src_y);
129
130 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
131
132 error_map:
133 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
134 }
135
136 static void
137 vl_context_clear_sampler(struct pipe_video_context *context,
138 struct pipe_sampler_view *dst,
139 const struct pipe_box *dst_box,
140 const float *rgba)
141 {
142 struct vl_context *ctx = (struct vl_context*)context;
143 struct pipe_transfer *transfer;
144 union util_color uc;
145 void *map;
146 unsigned i;
147
148 assert(context);
149 assert(dst);
150 assert(dst_box);
151 assert(rgba);
152
153 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
154 if (!transfer)
155 return;
156
157 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
158 if (!transfer)
159 goto error_map;
160
161 for ( i = 0; i < 4; ++i)
162 uc.f[i] = rgba[i];
163
164 util_fill_rect(map, dst->texture->format, transfer->stride, 0, 0,
165 dst_box->width, dst_box->height, &uc);
166
167 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
168
169 error_map:
170 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
171 }
172
173 static struct pipe_video_decoder *
174 vl_context_create_decoder(struct pipe_video_context *context,
175 enum pipe_video_profile profile,
176 enum pipe_video_chroma_format chroma_format,
177 unsigned width, unsigned height)
178 {
179 struct vl_context *ctx = (struct vl_context*)context;
180 unsigned buffer_width, buffer_height;
181
182 assert(context);
183 assert(width > 0 && height > 0);
184
185 buffer_width = ctx->pot_buffers ? util_next_power_of_two(width) : width;
186 buffer_height = ctx->pot_buffers ? util_next_power_of_two(height) : height;
187
188 switch (u_reduce_video_profile(profile)) {
189 case PIPE_VIDEO_CODEC_MPEG12:
190 return vl_create_mpeg12_decoder(context, ctx->pipe, profile, chroma_format,
191 buffer_width, buffer_height);
192 default:
193 return NULL;
194 }
195 return NULL;
196 }
197
198 static struct pipe_video_buffer *
199 vl_context_create_buffer(struct pipe_video_context *context,
200 enum pipe_format buffer_format,
201 enum pipe_video_chroma_format chroma_format,
202 unsigned width, unsigned height)
203 {
204 const enum pipe_format resource_formats[3] = {
205 PIPE_FORMAT_R8_SNORM,
206 PIPE_FORMAT_R8_SNORM,
207 PIPE_FORMAT_R8_SNORM
208 };
209
210 struct vl_context *ctx = (struct vl_context*)context;
211 unsigned buffer_width, buffer_height;
212
213 assert(context);
214 assert(width > 0 && height > 0);
215 assert(buffer_format == PIPE_FORMAT_YV12);
216
217 buffer_width = ctx->pot_buffers ? util_next_power_of_two(width) : width;
218 buffer_height = ctx->pot_buffers ? util_next_power_of_two(height) : height;
219
220 return vl_video_buffer_init(context, ctx->pipe,
221 buffer_width, buffer_height, 1,
222 chroma_format, 3,
223 resource_formats,
224 PIPE_USAGE_STATIC);
225 }
226
227 static struct pipe_video_compositor *
228 vl_context_create_compositor(struct pipe_video_context *context)
229 {
230 struct vl_context *ctx = (struct vl_context*)context;
231
232 assert(context);
233
234 return vl_compositor_init(context, ctx->pipe);
235 }
236
237 struct pipe_video_context *
238 vl_create_context(struct pipe_context *pipe, bool pot_buffers)
239 {
240 struct vl_context *ctx;
241
242 ctx = CALLOC_STRUCT(vl_context);
243
244 if (!ctx)
245 return NULL;
246
247 ctx->base.screen = pipe->screen;
248
249 ctx->base.destroy = vl_context_destroy;
250 ctx->base.get_param = vl_context_get_param;
251 ctx->base.is_format_supported = vl_context_is_format_supported;
252 ctx->base.create_surface = vl_context_create_surface;
253 ctx->base.create_sampler_view = vl_context_create_sampler_view;
254 ctx->base.clear_sampler = vl_context_clear_sampler;
255 ctx->base.upload_sampler = vl_context_upload_sampler;
256 ctx->base.create_decoder = vl_context_create_decoder;
257 ctx->base.create_buffer = vl_context_create_buffer;
258 ctx->base.create_compositor = vl_context_create_compositor;
259
260 ctx->pipe = pipe;
261 ctx->pot_buffers = pot_buffers;
262
263 return &ctx->base;
264 }