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