1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2009 Younes Manton.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "util/u_sampler.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "vl_compositor_gfx.h"
31bf215546Sopenharmony_ci#include "vl_compositor_cs.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_cistatic bool
34bf215546Sopenharmony_ciinit_shaders(struct vl_compositor *c)
35bf215546Sopenharmony_ci{
36bf215546Sopenharmony_ci   assert(c);
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   if (c->pipe_cs_composit_supported) {
39bf215546Sopenharmony_ci      if (!vl_compositor_cs_init_shaders(c))
40bf215546Sopenharmony_ci         return false;
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci   } else if (c->pipe_gfx_supported) {
43bf215546Sopenharmony_ci      c->fs_video_buffer = create_frag_shader_video_buffer(c);
44bf215546Sopenharmony_ci      if (!c->fs_video_buffer) {
45bf215546Sopenharmony_ci         debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
46bf215546Sopenharmony_ci         return false;
47bf215546Sopenharmony_ci      }
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci      c->fs_weave_rgb = create_frag_shader_weave_rgb(c);
50bf215546Sopenharmony_ci      if (!c->fs_weave_rgb) {
51bf215546Sopenharmony_ci         debug_printf("Unable to create YCbCr-to-RGB weave fragment shader.\n");
52bf215546Sopenharmony_ci         return false;
53bf215546Sopenharmony_ci      }
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci      c->fs_yuv.weave.y = create_frag_shader_deint_yuv(c, true, true);
56bf215546Sopenharmony_ci      c->fs_yuv.weave.uv = create_frag_shader_deint_yuv(c, false, true);
57bf215546Sopenharmony_ci      c->fs_yuv.bob.y = create_frag_shader_deint_yuv(c, true, false);
58bf215546Sopenharmony_ci      c->fs_yuv.bob.uv = create_frag_shader_deint_yuv(c, false, false);
59bf215546Sopenharmony_ci      if (!c->fs_yuv.weave.y || !c->fs_yuv.weave.uv ||
60bf215546Sopenharmony_ci          !c->fs_yuv.bob.y || !c->fs_yuv.bob.uv) {
61bf215546Sopenharmony_ci         debug_printf("Unable to create YCbCr i-to-YCbCr p deint fragment shader.\n");
62bf215546Sopenharmony_ci         return false;
63bf215546Sopenharmony_ci      }
64bf215546Sopenharmony_ci   }
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   if (c->pipe_gfx_supported) {
67bf215546Sopenharmony_ci      c->vs = create_vert_shader(c);
68bf215546Sopenharmony_ci      if (!c->vs) {
69bf215546Sopenharmony_ci         debug_printf("Unable to create vertex shader.\n");
70bf215546Sopenharmony_ci         return false;
71bf215546Sopenharmony_ci      }
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci      c->fs_palette.yuv = create_frag_shader_palette(c, true);
74bf215546Sopenharmony_ci      if (!c->fs_palette.yuv) {
75bf215546Sopenharmony_ci         debug_printf("Unable to create YUV-Palette-to-RGB fragment shader.\n");
76bf215546Sopenharmony_ci         return false;
77bf215546Sopenharmony_ci      }
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci      c->fs_palette.rgb = create_frag_shader_palette(c, false);
80bf215546Sopenharmony_ci      if (!c->fs_palette.rgb) {
81bf215546Sopenharmony_ci         debug_printf("Unable to create RGB-Palette-to-RGB fragment shader.\n");
82bf215546Sopenharmony_ci         return false;
83bf215546Sopenharmony_ci      }
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci      c->fs_rgb_yuv.y = create_frag_shader_rgb_yuv(c, true);
86bf215546Sopenharmony_ci      c->fs_rgb_yuv.uv = create_frag_shader_rgb_yuv(c, false);
87bf215546Sopenharmony_ci      if (!c->fs_rgb_yuv.y || !c->fs_rgb_yuv.uv) {
88bf215546Sopenharmony_ci         debug_printf("Unable to create RGB-to-YUV fragment shader.\n");
89bf215546Sopenharmony_ci         return false;
90bf215546Sopenharmony_ci      }
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci      c->fs_rgba = create_frag_shader_rgba(c);
93bf215546Sopenharmony_ci      if (!c->fs_rgba) {
94bf215546Sopenharmony_ci         debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
95bf215546Sopenharmony_ci         return false;
96bf215546Sopenharmony_ci      }
97bf215546Sopenharmony_ci   }
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   return true;
100bf215546Sopenharmony_ci}
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_cistatic void cleanup_shaders(struct vl_compositor *c)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci   assert(c);
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   if (c->pipe_cs_composit_supported) {
107bf215546Sopenharmony_ci      vl_compositor_cs_cleanup_shaders(c);
108bf215546Sopenharmony_ci   } else if (c->pipe_gfx_supported) {
109bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_video_buffer);
110bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_weave_rgb);
111bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_yuv.weave.y);
112bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_yuv.weave.uv);
113bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_yuv.bob.y);
114bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_yuv.bob.uv);
115bf215546Sopenharmony_ci   }
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   if (c->pipe_gfx_supported) {
118bf215546Sopenharmony_ci      c->pipe->delete_vs_state(c->pipe, c->vs);
119bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_palette.yuv);
120bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_palette.rgb);
121bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_rgb_yuv.y);
122bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_rgb_yuv.uv);
123bf215546Sopenharmony_ci      c->pipe->delete_fs_state(c->pipe, c->fs_rgba);
124bf215546Sopenharmony_ci   }
125bf215546Sopenharmony_ci}
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_cistatic bool
128bf215546Sopenharmony_ciinit_pipe_state(struct vl_compositor *c)
129bf215546Sopenharmony_ci{
130bf215546Sopenharmony_ci   struct pipe_rasterizer_state rast;
131bf215546Sopenharmony_ci   struct pipe_sampler_state sampler;
132bf215546Sopenharmony_ci   struct pipe_blend_state blend;
133bf215546Sopenharmony_ci   struct pipe_depth_stencil_alpha_state dsa;
134bf215546Sopenharmony_ci   unsigned i;
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ci   assert(c);
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci   c->fb_state.nr_cbufs = 1;
139bf215546Sopenharmony_ci   c->fb_state.zsbuf = NULL;
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci   memset(&sampler, 0, sizeof(sampler));
142bf215546Sopenharmony_ci   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
143bf215546Sopenharmony_ci   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
144bf215546Sopenharmony_ci   sampler.wrap_r = PIPE_TEX_WRAP_REPEAT;
145bf215546Sopenharmony_ci   sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
146bf215546Sopenharmony_ci   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
147bf215546Sopenharmony_ci   sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
148bf215546Sopenharmony_ci   sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
149bf215546Sopenharmony_ci   sampler.compare_func = PIPE_FUNC_ALWAYS;
150bf215546Sopenharmony_ci   sampler.normalized_coords = 1;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   c->sampler_linear = c->pipe->create_sampler_state(c->pipe, &sampler);
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
155bf215546Sopenharmony_ci   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
156bf215546Sopenharmony_ci   c->sampler_nearest = c->pipe->create_sampler_state(c->pipe, &sampler);
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci   if (c->pipe_gfx_supported) {
159bf215546Sopenharmony_ci           memset(&blend, 0, sizeof blend);
160bf215546Sopenharmony_ci           blend.independent_blend_enable = 0;
161bf215546Sopenharmony_ci           blend.rt[0].blend_enable = 0;
162bf215546Sopenharmony_ci           blend.logicop_enable = 0;
163bf215546Sopenharmony_ci           blend.logicop_func = PIPE_LOGICOP_CLEAR;
164bf215546Sopenharmony_ci           blend.rt[0].colormask = PIPE_MASK_RGBA;
165bf215546Sopenharmony_ci           blend.dither = 0;
166bf215546Sopenharmony_ci           c->blend_clear = c->pipe->create_blend_state(c->pipe, &blend);
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ci           blend.rt[0].blend_enable = 1;
169bf215546Sopenharmony_ci           blend.rt[0].rgb_func = PIPE_BLEND_ADD;
170bf215546Sopenharmony_ci           blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
171bf215546Sopenharmony_ci           blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
172bf215546Sopenharmony_ci           blend.rt[0].alpha_func = PIPE_BLEND_ADD;
173bf215546Sopenharmony_ci           blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
174bf215546Sopenharmony_ci           blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
175bf215546Sopenharmony_ci           c->blend_add = c->pipe->create_blend_state(c->pipe, &blend);
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci           memset(&rast, 0, sizeof rast);
178bf215546Sopenharmony_ci           rast.flatshade = 0;
179bf215546Sopenharmony_ci           rast.front_ccw = 1;
180bf215546Sopenharmony_ci           rast.cull_face = PIPE_FACE_NONE;
181bf215546Sopenharmony_ci           rast.fill_back = PIPE_POLYGON_MODE_FILL;
182bf215546Sopenharmony_ci           rast.fill_front = PIPE_POLYGON_MODE_FILL;
183bf215546Sopenharmony_ci           rast.scissor = 1;
184bf215546Sopenharmony_ci           rast.line_width = 1;
185bf215546Sopenharmony_ci           rast.point_size_per_vertex = 1;
186bf215546Sopenharmony_ci           rast.offset_units = 1;
187bf215546Sopenharmony_ci           rast.offset_scale = 1;
188bf215546Sopenharmony_ci           rast.half_pixel_center = 1;
189bf215546Sopenharmony_ci           rast.bottom_edge_rule = 1;
190bf215546Sopenharmony_ci           rast.depth_clip_near = 1;
191bf215546Sopenharmony_ci           rast.depth_clip_far = 1;
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci           c->rast = c->pipe->create_rasterizer_state(c->pipe, &rast);
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci           memset(&dsa, 0, sizeof dsa);
196bf215546Sopenharmony_ci           dsa.depth_enabled = 0;
197bf215546Sopenharmony_ci           dsa.depth_writemask = 0;
198bf215546Sopenharmony_ci           dsa.depth_func = PIPE_FUNC_ALWAYS;
199bf215546Sopenharmony_ci           for (i = 0; i < 2; ++i) {
200bf215546Sopenharmony_ci                   dsa.stencil[i].enabled = 0;
201bf215546Sopenharmony_ci                   dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
202bf215546Sopenharmony_ci                   dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
203bf215546Sopenharmony_ci                   dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
204bf215546Sopenharmony_ci                   dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
205bf215546Sopenharmony_ci                   dsa.stencil[i].valuemask = 0;
206bf215546Sopenharmony_ci                   dsa.stencil[i].writemask = 0;
207bf215546Sopenharmony_ci           }
208bf215546Sopenharmony_ci           dsa.alpha_enabled = 0;
209bf215546Sopenharmony_ci           dsa.alpha_func = PIPE_FUNC_ALWAYS;
210bf215546Sopenharmony_ci           dsa.alpha_ref_value = 0;
211bf215546Sopenharmony_ci           c->dsa = c->pipe->create_depth_stencil_alpha_state(c->pipe, &dsa);
212bf215546Sopenharmony_ci           c->pipe->bind_depth_stencil_alpha_state(c->pipe, c->dsa);
213bf215546Sopenharmony_ci   }
214bf215546Sopenharmony_ci
215bf215546Sopenharmony_ci   return true;
216bf215546Sopenharmony_ci}
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_cistatic void cleanup_pipe_state(struct vl_compositor *c)
219bf215546Sopenharmony_ci{
220bf215546Sopenharmony_ci   assert(c);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   if (c->pipe_gfx_supported) {
223bf215546Sopenharmony_ci           /* Asserted in softpipe_delete_fs_state() for some reason */
224bf215546Sopenharmony_ci           c->pipe->bind_vs_state(c->pipe, NULL);
225bf215546Sopenharmony_ci           c->pipe->bind_fs_state(c->pipe, NULL);
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_ci           c->pipe->delete_depth_stencil_alpha_state(c->pipe, c->dsa);
228bf215546Sopenharmony_ci           c->pipe->delete_blend_state(c->pipe, c->blend_clear);
229bf215546Sopenharmony_ci           c->pipe->delete_blend_state(c->pipe, c->blend_add);
230bf215546Sopenharmony_ci           c->pipe->delete_rasterizer_state(c->pipe, c->rast);
231bf215546Sopenharmony_ci   }
232bf215546Sopenharmony_ci   c->pipe->delete_sampler_state(c->pipe, c->sampler_linear);
233bf215546Sopenharmony_ci   c->pipe->delete_sampler_state(c->pipe, c->sampler_nearest);
234bf215546Sopenharmony_ci}
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_cistatic bool
237bf215546Sopenharmony_ciinit_buffers(struct vl_compositor *c)
238bf215546Sopenharmony_ci{
239bf215546Sopenharmony_ci   struct pipe_vertex_element vertex_elems[3];
240bf215546Sopenharmony_ci   memset(vertex_elems, 0, sizeof(vertex_elems));
241bf215546Sopenharmony_ci
242bf215546Sopenharmony_ci   assert(c);
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci   /*
245bf215546Sopenharmony_ci    * Create our vertex buffer and vertex buffer elements
246bf215546Sopenharmony_ci    */
247bf215546Sopenharmony_ci   c->vertex_buf.stride = sizeof(struct vertex2f) + sizeof(struct vertex4f) * 2;
248bf215546Sopenharmony_ci   c->vertex_buf.buffer_offset = 0;
249bf215546Sopenharmony_ci   c->vertex_buf.buffer.resource = NULL;
250bf215546Sopenharmony_ci   c->vertex_buf.is_user_buffer = false;
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci   if (c->pipe_gfx_supported) {
253bf215546Sopenharmony_ci           vertex_elems[0].src_offset = 0;
254bf215546Sopenharmony_ci           vertex_elems[0].instance_divisor = 0;
255bf215546Sopenharmony_ci           vertex_elems[0].vertex_buffer_index = 0;
256bf215546Sopenharmony_ci           vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
257bf215546Sopenharmony_ci           vertex_elems[1].src_offset = sizeof(struct vertex2f);
258bf215546Sopenharmony_ci           vertex_elems[1].instance_divisor = 0;
259bf215546Sopenharmony_ci           vertex_elems[1].vertex_buffer_index = 0;
260bf215546Sopenharmony_ci           vertex_elems[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
261bf215546Sopenharmony_ci           vertex_elems[2].src_offset = sizeof(struct vertex2f) + sizeof(struct vertex4f);
262bf215546Sopenharmony_ci           vertex_elems[2].instance_divisor = 0;
263bf215546Sopenharmony_ci           vertex_elems[2].vertex_buffer_index = 0;
264bf215546Sopenharmony_ci           vertex_elems[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
265bf215546Sopenharmony_ci           c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 3, vertex_elems);
266bf215546Sopenharmony_ci   }
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   return true;
269bf215546Sopenharmony_ci}
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_cistatic void
272bf215546Sopenharmony_cicleanup_buffers(struct vl_compositor *c)
273bf215546Sopenharmony_ci{
274bf215546Sopenharmony_ci   assert(c);
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_ci   if (c->pipe_gfx_supported) {
277bf215546Sopenharmony_ci           c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems_state);
278bf215546Sopenharmony_ci   }
279bf215546Sopenharmony_ci   pipe_resource_reference(&c->vertex_buf.buffer.resource, NULL);
280bf215546Sopenharmony_ci}
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_cistatic inline struct u_rect
283bf215546Sopenharmony_cidefault_rect(struct vl_compositor_layer *layer)
284bf215546Sopenharmony_ci{
285bf215546Sopenharmony_ci   struct pipe_resource *res = layer->sampler_views[0]->texture;
286bf215546Sopenharmony_ci   struct u_rect rect = { 0, res->width0, 0, res->height0 * res->array_size };
287bf215546Sopenharmony_ci   return rect;
288bf215546Sopenharmony_ci}
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_cistatic inline struct vertex2f
291bf215546Sopenharmony_cicalc_topleft(struct vertex2f size, struct u_rect rect)
292bf215546Sopenharmony_ci{
293bf215546Sopenharmony_ci   struct vertex2f res = { rect.x0 / size.x, rect.y0 / size.y };
294bf215546Sopenharmony_ci   return res;
295bf215546Sopenharmony_ci}
296bf215546Sopenharmony_ci
297bf215546Sopenharmony_cistatic inline struct vertex2f
298bf215546Sopenharmony_cicalc_bottomright(struct vertex2f size, struct u_rect rect)
299bf215546Sopenharmony_ci{
300bf215546Sopenharmony_ci   struct vertex2f res = { rect.x1 / size.x, rect.y1 / size.y };
301bf215546Sopenharmony_ci   return res;
302bf215546Sopenharmony_ci}
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_cistatic inline void
305bf215546Sopenharmony_cicalc_src_and_dst(struct vl_compositor_layer *layer, unsigned width, unsigned height,
306bf215546Sopenharmony_ci                 struct u_rect src, struct u_rect dst)
307bf215546Sopenharmony_ci{
308bf215546Sopenharmony_ci   struct vertex2f size =  { width, height };
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci   layer->src.tl = calc_topleft(size, src);
311bf215546Sopenharmony_ci   layer->src.br = calc_bottomright(size, src);
312bf215546Sopenharmony_ci   layer->dst.tl = calc_topleft(size, dst);
313bf215546Sopenharmony_ci   layer->dst.br = calc_bottomright(size, dst);
314bf215546Sopenharmony_ci   layer->zw.x = 0.0f;
315bf215546Sopenharmony_ci   layer->zw.y = size.y;
316bf215546Sopenharmony_ci}
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_cistatic void
319bf215546Sopenharmony_ciset_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
320bf215546Sopenharmony_ci              unsigned layer, struct pipe_video_buffer *buffer,
321bf215546Sopenharmony_ci              struct u_rect *src_rect, struct u_rect *dst_rect,
322bf215546Sopenharmony_ci              bool y, enum vl_compositor_deinterlace deinterlace)
323bf215546Sopenharmony_ci{
324bf215546Sopenharmony_ci   struct pipe_sampler_view **sampler_views;
325bf215546Sopenharmony_ci   float half_a_line;
326bf215546Sopenharmony_ci   unsigned i;
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   assert(s && c && buffer);
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci   s->interlaced = buffer->interlaced;
333bf215546Sopenharmony_ci   s->used_layers |= 1 << layer;
334bf215546Sopenharmony_ci   sampler_views = buffer->get_sampler_view_components(buffer);
335bf215546Sopenharmony_ci   for (i = 0; i < 3; ++i) {
336bf215546Sopenharmony_ci      s->layers[layer].samplers[i] = c->sampler_linear;
337bf215546Sopenharmony_ci      pipe_sampler_view_reference(&s->layers[layer].sampler_views[i], sampler_views[i]);
338bf215546Sopenharmony_ci   }
339bf215546Sopenharmony_ci
340bf215546Sopenharmony_ci   calc_src_and_dst(&s->layers[layer], buffer->width, buffer->height,
341bf215546Sopenharmony_ci                    src_rect ? *src_rect : default_rect(&s->layers[layer]),
342bf215546Sopenharmony_ci                    dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci   half_a_line = 0.5f / s->layers[layer].zw.y;
345bf215546Sopenharmony_ci
346bf215546Sopenharmony_ci   switch(deinterlace) {
347bf215546Sopenharmony_ci   case VL_COMPOSITOR_BOB_TOP:
348bf215546Sopenharmony_ci      s->layers[layer].zw.x = 0.0f;
349bf215546Sopenharmony_ci      s->layers[layer].src.tl.y += half_a_line;
350bf215546Sopenharmony_ci      s->layers[layer].src.br.y += half_a_line;
351bf215546Sopenharmony_ci      if (c->pipe_gfx_supported)
352bf215546Sopenharmony_ci          s->layers[layer].fs = (y) ? c->fs_yuv.bob.y : c->fs_yuv.bob.uv;
353bf215546Sopenharmony_ci      if (c->pipe_cs_composit_supported)
354bf215546Sopenharmony_ci          s->layers[layer].cs = (y) ? c->cs_yuv.bob.y : c->cs_yuv.bob.uv;
355bf215546Sopenharmony_ci      break;
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   case VL_COMPOSITOR_BOB_BOTTOM:
358bf215546Sopenharmony_ci      s->layers[layer].zw.x = 1.0f;
359bf215546Sopenharmony_ci      s->layers[layer].src.tl.y -= half_a_line;
360bf215546Sopenharmony_ci      s->layers[layer].src.br.y -= half_a_line;
361bf215546Sopenharmony_ci      if (c->pipe_gfx_supported)
362bf215546Sopenharmony_ci          s->layers[layer].fs = (y) ? c->fs_yuv.bob.y : c->fs_yuv.bob.uv;
363bf215546Sopenharmony_ci      if (c->pipe_cs_composit_supported)
364bf215546Sopenharmony_ci          s->layers[layer].cs = (y) ? c->cs_yuv.bob.y : c->cs_yuv.bob.uv;
365bf215546Sopenharmony_ci      break;
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci   default:
368bf215546Sopenharmony_ci      if (c->pipe_gfx_supported)
369bf215546Sopenharmony_ci          s->layers[layer].fs = (y) ? c->fs_yuv.weave.y : c->fs_yuv.weave.uv;
370bf215546Sopenharmony_ci      if (c->pipe_cs_composit_supported)
371bf215546Sopenharmony_ci          s->layers[layer].cs = (y) ? c->cs_yuv.weave.y : c->cs_yuv.weave.uv;
372bf215546Sopenharmony_ci      break;
373bf215546Sopenharmony_ci   }
374bf215546Sopenharmony_ci}
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_cistatic void
377bf215546Sopenharmony_ciset_rgb_to_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
378bf215546Sopenharmony_ci                     unsigned layer, struct pipe_sampler_view *v,
379bf215546Sopenharmony_ci                     struct u_rect *src_rect, struct u_rect *dst_rect, bool y)
380bf215546Sopenharmony_ci{
381bf215546Sopenharmony_ci   vl_csc_matrix csc_matrix;
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci   assert(s && c && v);
384bf215546Sopenharmony_ci
385bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
386bf215546Sopenharmony_ci
387bf215546Sopenharmony_ci   s->used_layers |= 1 << layer;
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ci   s->layers[layer].fs = y? c->fs_rgb_yuv.y : c->fs_rgb_yuv.uv;
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_709_REV, NULL, false, &csc_matrix);
392bf215546Sopenharmony_ci   vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix, 1.0f, 0.0f);
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci   s->layers[layer].samplers[0] = c->sampler_linear;
395bf215546Sopenharmony_ci   s->layers[layer].samplers[1] = NULL;
396bf215546Sopenharmony_ci   s->layers[layer].samplers[2] = NULL;
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[0], v);
399bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[1], NULL);
400bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[2], NULL);
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci   calc_src_and_dst(&s->layers[layer], v->texture->width0, v->texture->height0,
403bf215546Sopenharmony_ci                    src_rect ? *src_rect : default_rect(&s->layers[layer]),
404bf215546Sopenharmony_ci                    dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
405bf215546Sopenharmony_ci}
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_civoid
408bf215546Sopenharmony_civl_compositor_reset_dirty_area(struct u_rect *dirty)
409bf215546Sopenharmony_ci{
410bf215546Sopenharmony_ci   assert(dirty);
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci   dirty->x0 = dirty->y0 = VL_COMPOSITOR_MIN_DIRTY;
413bf215546Sopenharmony_ci   dirty->x1 = dirty->y1 = VL_COMPOSITOR_MAX_DIRTY;
414bf215546Sopenharmony_ci}
415bf215546Sopenharmony_ci
416bf215546Sopenharmony_civoid
417bf215546Sopenharmony_civl_compositor_set_clear_color(struct vl_compositor_state *s, union pipe_color_union *color)
418bf215546Sopenharmony_ci{
419bf215546Sopenharmony_ci   assert(s);
420bf215546Sopenharmony_ci   assert(color);
421bf215546Sopenharmony_ci
422bf215546Sopenharmony_ci   s->clear_color = *color;
423bf215546Sopenharmony_ci}
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_civoid
426bf215546Sopenharmony_civl_compositor_get_clear_color(struct vl_compositor_state *s, union pipe_color_union *color)
427bf215546Sopenharmony_ci{
428bf215546Sopenharmony_ci   assert(s);
429bf215546Sopenharmony_ci   assert(color);
430bf215546Sopenharmony_ci
431bf215546Sopenharmony_ci   *color = s->clear_color;
432bf215546Sopenharmony_ci}
433bf215546Sopenharmony_ci
434bf215546Sopenharmony_civoid
435bf215546Sopenharmony_civl_compositor_clear_layers(struct vl_compositor_state *s)
436bf215546Sopenharmony_ci{
437bf215546Sopenharmony_ci   unsigned i, j;
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci   assert(s);
440bf215546Sopenharmony_ci   s->interlaced = false;
441bf215546Sopenharmony_ci   s->used_layers = 0;
442bf215546Sopenharmony_ci   for ( i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
443bf215546Sopenharmony_ci      struct vertex4f v_one = { 1.0f, 1.0f, 1.0f, 1.0f };
444bf215546Sopenharmony_ci      s->layers[i].clearing = i ? false : true;
445bf215546Sopenharmony_ci      s->layers[i].blend = NULL;
446bf215546Sopenharmony_ci      s->layers[i].fs = NULL;
447bf215546Sopenharmony_ci      s->layers[i].cs = NULL;
448bf215546Sopenharmony_ci      s->layers[i].viewport.scale[2] = 1;
449bf215546Sopenharmony_ci      s->layers[i].viewport.translate[2] = 0;
450bf215546Sopenharmony_ci      s->layers[i].viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
451bf215546Sopenharmony_ci      s->layers[i].viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
452bf215546Sopenharmony_ci      s->layers[i].viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
453bf215546Sopenharmony_ci      s->layers[i].viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
454bf215546Sopenharmony_ci      s->layers[i].rotate = VL_COMPOSITOR_ROTATE_0;
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_ci      for ( j = 0; j < 3; j++)
457bf215546Sopenharmony_ci         pipe_sampler_view_reference(&s->layers[i].sampler_views[j], NULL);
458bf215546Sopenharmony_ci      for ( j = 0; j < 4; ++j)
459bf215546Sopenharmony_ci         s->layers[i].colors[j] = v_one;
460bf215546Sopenharmony_ci   }
461bf215546Sopenharmony_ci}
462bf215546Sopenharmony_ci
463bf215546Sopenharmony_civoid
464bf215546Sopenharmony_civl_compositor_cleanup(struct vl_compositor *c)
465bf215546Sopenharmony_ci{
466bf215546Sopenharmony_ci   assert(c);
467bf215546Sopenharmony_ci
468bf215546Sopenharmony_ci   cleanup_buffers(c);
469bf215546Sopenharmony_ci   cleanup_shaders(c);
470bf215546Sopenharmony_ci   cleanup_pipe_state(c);
471bf215546Sopenharmony_ci}
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_cibool
474bf215546Sopenharmony_civl_compositor_set_csc_matrix(struct vl_compositor_state *s,
475bf215546Sopenharmony_ci                             vl_csc_matrix const *matrix,
476bf215546Sopenharmony_ci                             float luma_min, float luma_max)
477bf215546Sopenharmony_ci{
478bf215546Sopenharmony_ci   struct pipe_transfer *buf_transfer;
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_ci   assert(s);
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_ci   float *ptr = pipe_buffer_map(s->pipe, s->shader_params,
483bf215546Sopenharmony_ci                               PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE,
484bf215546Sopenharmony_ci                               &buf_transfer);
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ci   if (!ptr)
487bf215546Sopenharmony_ci      return false;
488bf215546Sopenharmony_ci
489bf215546Sopenharmony_ci   memcpy(ptr, matrix, sizeof(vl_csc_matrix));
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_ci   ptr += sizeof(vl_csc_matrix)/sizeof(float);
492bf215546Sopenharmony_ci   ptr[0] = luma_min;
493bf215546Sopenharmony_ci   ptr[1] = luma_max;
494bf215546Sopenharmony_ci
495bf215546Sopenharmony_ci   pipe_buffer_unmap(s->pipe, buf_transfer);
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci   return true;
498bf215546Sopenharmony_ci}
499bf215546Sopenharmony_ci
500bf215546Sopenharmony_civoid
501bf215546Sopenharmony_civl_compositor_set_dst_clip(struct vl_compositor_state *s, struct u_rect *dst_clip)
502bf215546Sopenharmony_ci{
503bf215546Sopenharmony_ci   assert(s);
504bf215546Sopenharmony_ci
505bf215546Sopenharmony_ci   s->scissor_valid = dst_clip != NULL;
506bf215546Sopenharmony_ci   if (dst_clip) {
507bf215546Sopenharmony_ci      s->scissor.minx = dst_clip->x0;
508bf215546Sopenharmony_ci      s->scissor.miny = dst_clip->y0;
509bf215546Sopenharmony_ci      s->scissor.maxx = dst_clip->x1;
510bf215546Sopenharmony_ci      s->scissor.maxy = dst_clip->y1;
511bf215546Sopenharmony_ci   }
512bf215546Sopenharmony_ci}
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_civoid
515bf215546Sopenharmony_civl_compositor_set_layer_blend(struct vl_compositor_state *s,
516bf215546Sopenharmony_ci                              unsigned layer, void *blend,
517bf215546Sopenharmony_ci                              bool is_clearing)
518bf215546Sopenharmony_ci{
519bf215546Sopenharmony_ci   assert(s && blend);
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
522bf215546Sopenharmony_ci
523bf215546Sopenharmony_ci   s->layers[layer].clearing = is_clearing;
524bf215546Sopenharmony_ci   s->layers[layer].blend = blend;
525bf215546Sopenharmony_ci}
526bf215546Sopenharmony_ci
527bf215546Sopenharmony_civoid
528bf215546Sopenharmony_civl_compositor_set_layer_dst_area(struct vl_compositor_state *s,
529bf215546Sopenharmony_ci                                 unsigned layer, struct u_rect *dst_area)
530bf215546Sopenharmony_ci{
531bf215546Sopenharmony_ci   assert(s);
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
534bf215546Sopenharmony_ci
535bf215546Sopenharmony_ci   s->layers[layer].viewport_valid = dst_area != NULL;
536bf215546Sopenharmony_ci   if (dst_area) {
537bf215546Sopenharmony_ci      s->layers[layer].viewport.scale[0] = dst_area->x1 - dst_area->x0;
538bf215546Sopenharmony_ci      s->layers[layer].viewport.scale[1] = dst_area->y1 - dst_area->y0;
539bf215546Sopenharmony_ci      s->layers[layer].viewport.translate[0] = dst_area->x0;
540bf215546Sopenharmony_ci      s->layers[layer].viewport.translate[1] = dst_area->y0;
541bf215546Sopenharmony_ci   }
542bf215546Sopenharmony_ci}
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_civoid
545bf215546Sopenharmony_civl_compositor_set_buffer_layer(struct vl_compositor_state *s,
546bf215546Sopenharmony_ci                               struct vl_compositor *c,
547bf215546Sopenharmony_ci                               unsigned layer,
548bf215546Sopenharmony_ci                               struct pipe_video_buffer *buffer,
549bf215546Sopenharmony_ci                               struct u_rect *src_rect,
550bf215546Sopenharmony_ci                               struct u_rect *dst_rect,
551bf215546Sopenharmony_ci                               enum vl_compositor_deinterlace deinterlace)
552bf215546Sopenharmony_ci{
553bf215546Sopenharmony_ci   struct pipe_sampler_view **sampler_views;
554bf215546Sopenharmony_ci   unsigned i;
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   assert(s && c && buffer);
557bf215546Sopenharmony_ci
558bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_ci   s->interlaced = buffer->interlaced;
561bf215546Sopenharmony_ci   s->used_layers |= 1 << layer;
562bf215546Sopenharmony_ci   sampler_views = buffer->get_sampler_view_components(buffer);
563bf215546Sopenharmony_ci   for (i = 0; i < 3; ++i) {
564bf215546Sopenharmony_ci      s->layers[layer].samplers[i] = c->sampler_linear;
565bf215546Sopenharmony_ci      pipe_sampler_view_reference(&s->layers[layer].sampler_views[i], sampler_views[i]);
566bf215546Sopenharmony_ci   }
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_ci   calc_src_and_dst(&s->layers[layer], buffer->width, buffer->height,
569bf215546Sopenharmony_ci                    src_rect ? *src_rect : default_rect(&s->layers[layer]),
570bf215546Sopenharmony_ci                    dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
571bf215546Sopenharmony_ci
572bf215546Sopenharmony_ci   if (buffer->interlaced) {
573bf215546Sopenharmony_ci      float half_a_line = 0.5f / s->layers[layer].zw.y;
574bf215546Sopenharmony_ci      switch(deinterlace) {
575bf215546Sopenharmony_ci      case VL_COMPOSITOR_NONE:
576bf215546Sopenharmony_ci      case VL_COMPOSITOR_MOTION_ADAPTIVE:
577bf215546Sopenharmony_ci      case VL_COMPOSITOR_WEAVE:
578bf215546Sopenharmony_ci         if (c->pipe_cs_composit_supported)
579bf215546Sopenharmony_ci            s->layers[layer].cs = c->cs_weave_rgb;
580bf215546Sopenharmony_ci         else if (c->pipe_gfx_supported)
581bf215546Sopenharmony_ci            s->layers[layer].fs = c->fs_weave_rgb;
582bf215546Sopenharmony_ci         break;
583bf215546Sopenharmony_ci
584bf215546Sopenharmony_ci      case VL_COMPOSITOR_BOB_TOP:
585bf215546Sopenharmony_ci         s->layers[layer].zw.x = 0.0f;
586bf215546Sopenharmony_ci         s->layers[layer].src.tl.y += half_a_line;
587bf215546Sopenharmony_ci         s->layers[layer].src.br.y += half_a_line;
588bf215546Sopenharmony_ci         if (c->pipe_cs_composit_supported)
589bf215546Sopenharmony_ci            s->layers[layer].cs = c->cs_video_buffer;
590bf215546Sopenharmony_ci         else if (c->pipe_gfx_supported)
591bf215546Sopenharmony_ci            s->layers[layer].fs = c->fs_video_buffer;
592bf215546Sopenharmony_ci         break;
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_ci      case VL_COMPOSITOR_BOB_BOTTOM:
595bf215546Sopenharmony_ci         s->layers[layer].zw.x = 1.0f;
596bf215546Sopenharmony_ci         s->layers[layer].src.tl.y -= half_a_line;
597bf215546Sopenharmony_ci         s->layers[layer].src.br.y -= half_a_line;
598bf215546Sopenharmony_ci         if (c->pipe_cs_composit_supported)
599bf215546Sopenharmony_ci            s->layers[layer].cs = c->cs_video_buffer;
600bf215546Sopenharmony_ci         else if (c->pipe_gfx_supported)
601bf215546Sopenharmony_ci            s->layers[layer].fs = c->fs_video_buffer;
602bf215546Sopenharmony_ci         break;
603bf215546Sopenharmony_ci      }
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_ci   } else {
606bf215546Sopenharmony_ci      if (c->pipe_cs_composit_supported)
607bf215546Sopenharmony_ci         s->layers[layer].cs = c->cs_video_buffer;
608bf215546Sopenharmony_ci      else if (c->pipe_gfx_supported)
609bf215546Sopenharmony_ci         s->layers[layer].fs = c->fs_video_buffer;
610bf215546Sopenharmony_ci   }
611bf215546Sopenharmony_ci}
612bf215546Sopenharmony_ci
613bf215546Sopenharmony_civoid
614bf215546Sopenharmony_civl_compositor_set_palette_layer(struct vl_compositor_state *s,
615bf215546Sopenharmony_ci                                struct vl_compositor *c,
616bf215546Sopenharmony_ci                                unsigned layer,
617bf215546Sopenharmony_ci                                struct pipe_sampler_view *indexes,
618bf215546Sopenharmony_ci                                struct pipe_sampler_view *palette,
619bf215546Sopenharmony_ci                                struct u_rect *src_rect,
620bf215546Sopenharmony_ci                                struct u_rect *dst_rect,
621bf215546Sopenharmony_ci                                bool include_color_conversion)
622bf215546Sopenharmony_ci{
623bf215546Sopenharmony_ci   assert(s && c && indexes && palette);
624bf215546Sopenharmony_ci
625bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
626bf215546Sopenharmony_ci
627bf215546Sopenharmony_ci   s->used_layers |= 1 << layer;
628bf215546Sopenharmony_ci
629bf215546Sopenharmony_ci   s->layers[layer].fs = include_color_conversion ?
630bf215546Sopenharmony_ci      c->fs_palette.yuv : c->fs_palette.rgb;
631bf215546Sopenharmony_ci
632bf215546Sopenharmony_ci   s->layers[layer].samplers[0] = c->sampler_linear;
633bf215546Sopenharmony_ci   s->layers[layer].samplers[1] = c->sampler_nearest;
634bf215546Sopenharmony_ci   s->layers[layer].samplers[2] = NULL;
635bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[0], indexes);
636bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[1], palette);
637bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[2], NULL);
638bf215546Sopenharmony_ci   calc_src_and_dst(&s->layers[layer], indexes->texture->width0, indexes->texture->height0,
639bf215546Sopenharmony_ci                    src_rect ? *src_rect : default_rect(&s->layers[layer]),
640bf215546Sopenharmony_ci                    dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
641bf215546Sopenharmony_ci}
642bf215546Sopenharmony_ci
643bf215546Sopenharmony_civoid
644bf215546Sopenharmony_civl_compositor_set_rgba_layer(struct vl_compositor_state *s,
645bf215546Sopenharmony_ci                             struct vl_compositor *c,
646bf215546Sopenharmony_ci                             unsigned layer,
647bf215546Sopenharmony_ci                             struct pipe_sampler_view *rgba,
648bf215546Sopenharmony_ci                             struct u_rect *src_rect,
649bf215546Sopenharmony_ci                             struct u_rect *dst_rect,
650bf215546Sopenharmony_ci                             struct vertex4f *colors)
651bf215546Sopenharmony_ci{
652bf215546Sopenharmony_ci   unsigned i;
653bf215546Sopenharmony_ci
654bf215546Sopenharmony_ci   assert(s && c && rgba);
655bf215546Sopenharmony_ci
656bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
657bf215546Sopenharmony_ci
658bf215546Sopenharmony_ci   s->used_layers |= 1 << layer;
659bf215546Sopenharmony_ci   s->layers[layer].fs = c->fs_rgba;
660bf215546Sopenharmony_ci   s->layers[layer].samplers[0] = c->sampler_linear;
661bf215546Sopenharmony_ci   s->layers[layer].samplers[1] = NULL;
662bf215546Sopenharmony_ci   s->layers[layer].samplers[2] = NULL;
663bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[0], rgba);
664bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[1], NULL);
665bf215546Sopenharmony_ci   pipe_sampler_view_reference(&s->layers[layer].sampler_views[2], NULL);
666bf215546Sopenharmony_ci   calc_src_and_dst(&s->layers[layer], rgba->texture->width0, rgba->texture->height0,
667bf215546Sopenharmony_ci                    src_rect ? *src_rect : default_rect(&s->layers[layer]),
668bf215546Sopenharmony_ci                    dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
669bf215546Sopenharmony_ci
670bf215546Sopenharmony_ci   if (colors)
671bf215546Sopenharmony_ci      for (i = 0; i < 4; ++i)
672bf215546Sopenharmony_ci         s->layers[layer].colors[i] = colors[i];
673bf215546Sopenharmony_ci}
674bf215546Sopenharmony_ci
675bf215546Sopenharmony_civoid
676bf215546Sopenharmony_civl_compositor_set_layer_rotation(struct vl_compositor_state *s,
677bf215546Sopenharmony_ci                                 unsigned layer,
678bf215546Sopenharmony_ci                                 enum vl_compositor_rotation rotate)
679bf215546Sopenharmony_ci{
680bf215546Sopenharmony_ci   assert(s);
681bf215546Sopenharmony_ci   assert(layer < VL_COMPOSITOR_MAX_LAYERS);
682bf215546Sopenharmony_ci   s->layers[layer].rotate = rotate;
683bf215546Sopenharmony_ci}
684bf215546Sopenharmony_ci
685bf215546Sopenharmony_civoid
686bf215546Sopenharmony_civl_compositor_yuv_deint_full(struct vl_compositor_state *s,
687bf215546Sopenharmony_ci                             struct vl_compositor *c,
688bf215546Sopenharmony_ci                             struct pipe_video_buffer *src,
689bf215546Sopenharmony_ci                             struct pipe_video_buffer *dst,
690bf215546Sopenharmony_ci                             struct u_rect *src_rect,
691bf215546Sopenharmony_ci                             struct u_rect *dst_rect,
692bf215546Sopenharmony_ci                             enum vl_compositor_deinterlace deinterlace)
693bf215546Sopenharmony_ci{
694bf215546Sopenharmony_ci   struct pipe_surface **dst_surfaces;
695bf215546Sopenharmony_ci
696bf215546Sopenharmony_ci   dst_surfaces = dst->get_surfaces(dst);
697bf215546Sopenharmony_ci   vl_compositor_clear_layers(s);
698bf215546Sopenharmony_ci
699bf215546Sopenharmony_ci   set_yuv_layer(s, c, 0, src, src_rect, NULL, true, deinterlace);
700bf215546Sopenharmony_ci   vl_compositor_set_layer_dst_area(s, 0, dst_rect);
701bf215546Sopenharmony_ci   vl_compositor_render(s, c, dst_surfaces[0], NULL, false);
702bf215546Sopenharmony_ci
703bf215546Sopenharmony_ci   if (dst_rect) {
704bf215546Sopenharmony_ci      dst_rect->x1 /= 2;
705bf215546Sopenharmony_ci      dst_rect->y1 /= 2;
706bf215546Sopenharmony_ci   }
707bf215546Sopenharmony_ci
708bf215546Sopenharmony_ci   set_yuv_layer(s, c, 0, src, src_rect, NULL, false, deinterlace);
709bf215546Sopenharmony_ci   vl_compositor_set_layer_dst_area(s, 0, dst_rect);
710bf215546Sopenharmony_ci   vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
711bf215546Sopenharmony_ci
712bf215546Sopenharmony_ci   s->pipe->flush(s->pipe, NULL, 0);
713bf215546Sopenharmony_ci}
714bf215546Sopenharmony_ci
715bf215546Sopenharmony_civoid
716bf215546Sopenharmony_civl_compositor_convert_rgb_to_yuv(struct vl_compositor_state *s,
717bf215546Sopenharmony_ci                                 struct vl_compositor *c,
718bf215546Sopenharmony_ci                                 unsigned layer,
719bf215546Sopenharmony_ci                                 struct pipe_resource *src_res,
720bf215546Sopenharmony_ci                                 struct pipe_video_buffer *dst,
721bf215546Sopenharmony_ci                                 struct u_rect *src_rect,
722bf215546Sopenharmony_ci                                 struct u_rect *dst_rect)
723bf215546Sopenharmony_ci{
724bf215546Sopenharmony_ci   struct pipe_sampler_view *sv, sv_templ;
725bf215546Sopenharmony_ci   struct pipe_surface **dst_surfaces;
726bf215546Sopenharmony_ci
727bf215546Sopenharmony_ci   dst_surfaces = dst->get_surfaces(dst);
728bf215546Sopenharmony_ci
729bf215546Sopenharmony_ci   memset(&sv_templ, 0, sizeof(sv_templ));
730bf215546Sopenharmony_ci   u_sampler_view_default_template(&sv_templ, src_res, src_res->format);
731bf215546Sopenharmony_ci   sv = s->pipe->create_sampler_view(s->pipe, src_res, &sv_templ);
732bf215546Sopenharmony_ci
733bf215546Sopenharmony_ci   vl_compositor_clear_layers(s);
734bf215546Sopenharmony_ci
735bf215546Sopenharmony_ci   set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, true);
736bf215546Sopenharmony_ci   vl_compositor_set_layer_dst_area(s, 0, dst_rect);
737bf215546Sopenharmony_ci   vl_compositor_render(s, c, dst_surfaces[0], NULL, false);
738bf215546Sopenharmony_ci
739bf215546Sopenharmony_ci   if (dst_rect) {
740bf215546Sopenharmony_ci      dst_rect->x1 /= 2;
741bf215546Sopenharmony_ci      dst_rect->y1 /= 2;
742bf215546Sopenharmony_ci   }
743bf215546Sopenharmony_ci
744bf215546Sopenharmony_ci   set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, false);
745bf215546Sopenharmony_ci   vl_compositor_set_layer_dst_area(s, 0, dst_rect);
746bf215546Sopenharmony_ci   vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
747bf215546Sopenharmony_ci   pipe_sampler_view_reference(&sv, NULL);
748bf215546Sopenharmony_ci
749bf215546Sopenharmony_ci   s->pipe->flush(s->pipe, NULL, 0);
750bf215546Sopenharmony_ci}
751bf215546Sopenharmony_ci
752bf215546Sopenharmony_civoid
753bf215546Sopenharmony_civl_compositor_render(struct vl_compositor_state *s,
754bf215546Sopenharmony_ci                     struct vl_compositor       *c,
755bf215546Sopenharmony_ci                     struct pipe_surface        *dst_surface,
756bf215546Sopenharmony_ci                     struct u_rect              *dirty_area,
757bf215546Sopenharmony_ci                     bool                        clear_dirty)
758bf215546Sopenharmony_ci{
759bf215546Sopenharmony_ci   assert(s);
760bf215546Sopenharmony_ci
761bf215546Sopenharmony_ci   if (s->layers->cs)
762bf215546Sopenharmony_ci      vl_compositor_cs_render(s, c, dst_surface, dirty_area, clear_dirty);
763bf215546Sopenharmony_ci   else if (s->layers->fs)
764bf215546Sopenharmony_ci      vl_compositor_gfx_render(s, c, dst_surface, dirty_area, clear_dirty);
765bf215546Sopenharmony_ci   else
766bf215546Sopenharmony_ci      debug_warning("Hardware don't support.\n");;
767bf215546Sopenharmony_ci}
768bf215546Sopenharmony_ci
769bf215546Sopenharmony_cibool
770bf215546Sopenharmony_civl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe)
771bf215546Sopenharmony_ci{
772bf215546Sopenharmony_ci   assert(c);
773bf215546Sopenharmony_ci
774bf215546Sopenharmony_ci   memset(c, 0, sizeof(*c));
775bf215546Sopenharmony_ci
776bf215546Sopenharmony_ci   c->pipe_cs_composit_supported = pipe->screen->get_param(pipe->screen, PIPE_CAP_PREFER_COMPUTE_FOR_MULTIMEDIA) &&
777bf215546Sopenharmony_ci            pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_TEX_TXF_LZ) &&
778bf215546Sopenharmony_ci            pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_DIV);
779bf215546Sopenharmony_ci
780bf215546Sopenharmony_ci   c->pipe_gfx_supported = pipe->screen->get_param(pipe->screen, PIPE_CAP_GRAPHICS);
781bf215546Sopenharmony_ci   c->pipe = pipe;
782bf215546Sopenharmony_ci
783bf215546Sopenharmony_ci   c->deinterlace = VL_COMPOSITOR_NONE;
784bf215546Sopenharmony_ci
785bf215546Sopenharmony_ci   if (!init_pipe_state(c)) {
786bf215546Sopenharmony_ci      return false;
787bf215546Sopenharmony_ci   }
788bf215546Sopenharmony_ci
789bf215546Sopenharmony_ci   if (!init_shaders(c)) {
790bf215546Sopenharmony_ci      cleanup_pipe_state(c);
791bf215546Sopenharmony_ci      return false;
792bf215546Sopenharmony_ci   }
793bf215546Sopenharmony_ci
794bf215546Sopenharmony_ci   if (!init_buffers(c)) {
795bf215546Sopenharmony_ci      cleanup_shaders(c);
796bf215546Sopenharmony_ci      cleanup_pipe_state(c);
797bf215546Sopenharmony_ci      return false;
798bf215546Sopenharmony_ci   }
799bf215546Sopenharmony_ci
800bf215546Sopenharmony_ci   return true;
801bf215546Sopenharmony_ci}
802bf215546Sopenharmony_ci
803bf215546Sopenharmony_cibool
804bf215546Sopenharmony_civl_compositor_init_state(struct vl_compositor_state *s, struct pipe_context *pipe)
805bf215546Sopenharmony_ci{
806bf215546Sopenharmony_ci   vl_csc_matrix csc_matrix;
807bf215546Sopenharmony_ci
808bf215546Sopenharmony_ci   assert(s);
809bf215546Sopenharmony_ci
810bf215546Sopenharmony_ci   memset(s, 0, sizeof(*s));
811bf215546Sopenharmony_ci
812bf215546Sopenharmony_ci   s->pipe = pipe;
813bf215546Sopenharmony_ci
814bf215546Sopenharmony_ci   s->clear_color.f[0] = s->clear_color.f[1] = 0.0f;
815bf215546Sopenharmony_ci   s->clear_color.f[2] = s->clear_color.f[3] = 0.0f;
816bf215546Sopenharmony_ci
817bf215546Sopenharmony_ci   /*
818bf215546Sopenharmony_ci    * Create our fragment shader's constant buffer
819bf215546Sopenharmony_ci    * Const buffer contains the color conversion matrix and bias vectors
820bf215546Sopenharmony_ci    */
821bf215546Sopenharmony_ci   /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
822bf215546Sopenharmony_ci   s->shader_params = pipe_buffer_create_const0
823bf215546Sopenharmony_ci   (
824bf215546Sopenharmony_ci      pipe->screen,
825bf215546Sopenharmony_ci      PIPE_BIND_CONSTANT_BUFFER,
826bf215546Sopenharmony_ci      PIPE_USAGE_DEFAULT,
827bf215546Sopenharmony_ci      sizeof(csc_matrix) + 6*sizeof(float) + 10*sizeof(int)
828bf215546Sopenharmony_ci   );
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_ci   if (!s->shader_params)
831bf215546Sopenharmony_ci      return false;
832bf215546Sopenharmony_ci
833bf215546Sopenharmony_ci   vl_compositor_clear_layers(s);
834bf215546Sopenharmony_ci
835bf215546Sopenharmony_ci   vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, &csc_matrix);
836bf215546Sopenharmony_ci   if (!vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix, 1.0f, 0.0f))
837bf215546Sopenharmony_ci      return false;
838bf215546Sopenharmony_ci
839bf215546Sopenharmony_ci   return true;
840bf215546Sopenharmony_ci}
841bf215546Sopenharmony_ci
842bf215546Sopenharmony_civoid
843bf215546Sopenharmony_civl_compositor_cleanup_state(struct vl_compositor_state *s)
844bf215546Sopenharmony_ci{
845bf215546Sopenharmony_ci   assert(s);
846bf215546Sopenharmony_ci
847bf215546Sopenharmony_ci   vl_compositor_clear_layers(s);
848bf215546Sopenharmony_ci   pipe_resource_reference(&s->shader_params, NULL);
849bf215546Sopenharmony_ci}
850