1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker *
3*bbecb9d1SAndroid Build Coastguard Worker * Copyright (C) 2022 Kylin Software Co., Ltd.
4*bbecb9d1SAndroid Build Coastguard Worker *
5*bbecb9d1SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker *
12*bbecb9d1SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker *
15*bbecb9d1SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker *
23*bbecb9d1SAndroid Build Coastguard Worker **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker
25*bbecb9d1SAndroid Build Coastguard Worker /**
26*bbecb9d1SAndroid Build Coastguard Worker * @file
27*bbecb9d1SAndroid Build Coastguard Worker * The video implementation of the vrend renderer.
28*bbecb9d1SAndroid Build Coastguard Worker *
29*bbecb9d1SAndroid Build Coastguard Worker * It is based on the general virgl video submodule and handles data transfer
30*bbecb9d1SAndroid Build Coastguard Worker * and synchronization between host and guest.
31*bbecb9d1SAndroid Build Coastguard Worker *
32*bbecb9d1SAndroid Build Coastguard Worker * The relationship between vaSurface and video buffer objects:
33*bbecb9d1SAndroid Build Coastguard Worker *
34*bbecb9d1SAndroid Build Coastguard Worker * GUEST (Mesa) | HOST (Virglrenderer)
35*bbecb9d1SAndroid Build Coastguard Worker * |
36*bbecb9d1SAndroid Build Coastguard Worker * +------------+ | +------------+
37*bbecb9d1SAndroid Build Coastguard Worker * | vaSurface | | | vaSurface | <------+
38*bbecb9d1SAndroid Build Coastguard Worker * +------------+ | +------------+ |
39*bbecb9d1SAndroid Build Coastguard Worker * | | |
40*bbecb9d1SAndroid Build Coastguard Worker * +---------------------------+ | +-------------------------+ |
41*bbecb9d1SAndroid Build Coastguard Worker * | virgl_video_buffer | | | vrend_video_buffer | |
42*bbecb9d1SAndroid Build Coastguard Worker * | +-----------------------+ | | | +-------------------+ | |
43*bbecb9d1SAndroid Build Coastguard Worker * | | vl_video_buffer | | | | | vrend_resource(s) | | |
44*bbecb9d1SAndroid Build Coastguard Worker * | | +-------------------+ | |<--+-->| +-------------------+ | |
45*bbecb9d1SAndroid Build Coastguard Worker * | | | virgl_resource(s) | | | | | +--------------------+ | |
46*bbecb9d1SAndroid Build Coastguard Worker * | | +-------------------+ | | | | | virgl_video_buffer |-+--+
47*bbecb9d1SAndroid Build Coastguard Worker * | +-----------------------+ | | | +--------------------+ |
48*bbecb9d1SAndroid Build Coastguard Worker * +---------------------------+ | +-------------------------+
49*bbecb9d1SAndroid Build Coastguard Worker *
50*bbecb9d1SAndroid Build Coastguard Worker * The relationship between vaContext and video codec objects:
51*bbecb9d1SAndroid Build Coastguard Worker *
52*bbecb9d1SAndroid Build Coastguard Worker * GUEST (Mesa) | HOST (Virglrenderer)
53*bbecb9d1SAndroid Build Coastguard Worker * |
54*bbecb9d1SAndroid Build Coastguard Worker * +------------+ | +------------+
55*bbecb9d1SAndroid Build Coastguard Worker * | vaContext | | | vaContext | <-------+
56*bbecb9d1SAndroid Build Coastguard Worker * +------------+ | +------------+ |
57*bbecb9d1SAndroid Build Coastguard Worker * | | |
58*bbecb9d1SAndroid Build Coastguard Worker * +------------------------+ | +--------------------------+ |
59*bbecb9d1SAndroid Build Coastguard Worker * | virgl_video_codec | <--+--> | vrend_video_codec | |
60*bbecb9d1SAndroid Build Coastguard Worker * +------------------------+ | | +--------------------+ | |
61*bbecb9d1SAndroid Build Coastguard Worker * | | | virgl_video_codec | -+--+
62*bbecb9d1SAndroid Build Coastguard Worker * | | +--------------------+ |
63*bbecb9d1SAndroid Build Coastguard Worker * | +--------------------------+
64*bbecb9d1SAndroid Build Coastguard Worker *
65*bbecb9d1SAndroid Build Coastguard Worker * @author Feng Jiang <[email protected]>
66*bbecb9d1SAndroid Build Coastguard Worker */
67*bbecb9d1SAndroid Build Coastguard Worker
68*bbecb9d1SAndroid Build Coastguard Worker
69*bbecb9d1SAndroid Build Coastguard Worker #include <sys/param.h>
70*bbecb9d1SAndroid Build Coastguard Worker
71*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_video.h"
72*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_video_hw.h"
73*bbecb9d1SAndroid Build Coastguard Worker
74*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_debug.h"
75*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys.h"
76*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_renderer.h"
77*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_video.h"
78*bbecb9d1SAndroid Build Coastguard Worker
79*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context;
80*bbecb9d1SAndroid Build Coastguard Worker
81*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context {
82*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *ctx;
83*bbecb9d1SAndroid Build Coastguard Worker struct list_head codecs;
84*bbecb9d1SAndroid Build Coastguard Worker struct list_head buffers;
85*bbecb9d1SAndroid Build Coastguard Worker };
86*bbecb9d1SAndroid Build Coastguard Worker
87*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec {
88*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_codec *codec;
89*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle;
90*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *feed_res; /* encoding feedback */
91*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dest_res; /* encoding coded buffer */
92*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *ctx;
93*bbecb9d1SAndroid Build Coastguard Worker struct list_head head;
94*bbecb9d1SAndroid Build Coastguard Worker };
95*bbecb9d1SAndroid Build Coastguard Worker
96*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_plane {
97*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle;
98*bbecb9d1SAndroid Build Coastguard Worker GLuint texture; /* texture for temporary use */
99*bbecb9d1SAndroid Build Coastguard Worker GLuint framebuffer; /* framebuffer for temporary use */
100*bbecb9d1SAndroid Build Coastguard Worker EGLImageKHR egl_image; /* egl image for temporary use */
101*bbecb9d1SAndroid Build Coastguard Worker };
102*bbecb9d1SAndroid Build Coastguard Worker
103*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer {
104*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_buffer *buffer;
105*bbecb9d1SAndroid Build Coastguard Worker
106*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle;
107*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *ctx;
108*bbecb9d1SAndroid Build Coastguard Worker struct list_head head;
109*bbecb9d1SAndroid Build Coastguard Worker
110*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_planes;
111*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_plane planes[3];
112*bbecb9d1SAndroid Build Coastguard Worker };
113*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_codec(struct virgl_video_codec * codec)114*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_video_codec *vrend_video_codec(
115*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_codec *codec)
116*bbecb9d1SAndroid Build Coastguard Worker {
117*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_codec_opaque_data(codec);
118*bbecb9d1SAndroid Build Coastguard Worker }
119*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_buffer(struct virgl_video_buffer * buffer)120*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_video_buffer *vrend_video_buffer(
121*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_buffer *buffer)
122*bbecb9d1SAndroid Build Coastguard Worker {
123*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_buffer_opaque_data(buffer);
124*bbecb9d1SAndroid Build Coastguard Worker }
125*bbecb9d1SAndroid Build Coastguard Worker
get_video_codec(struct vrend_video_context * ctx,uint32_t cdc_handle)126*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_video_codec *get_video_codec(
127*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *ctx,
128*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle)
129*bbecb9d1SAndroid Build Coastguard Worker {
130*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc;
131*bbecb9d1SAndroid Build Coastguard Worker
132*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(cdc, &ctx->codecs, head) {
133*bbecb9d1SAndroid Build Coastguard Worker if (cdc->handle == cdc_handle)
134*bbecb9d1SAndroid Build Coastguard Worker return cdc;
135*bbecb9d1SAndroid Build Coastguard Worker }
136*bbecb9d1SAndroid Build Coastguard Worker
137*bbecb9d1SAndroid Build Coastguard Worker return NULL;
138*bbecb9d1SAndroid Build Coastguard Worker }
139*bbecb9d1SAndroid Build Coastguard Worker
get_video_buffer(struct vrend_video_context * ctx,uint32_t buf_handle)140*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_video_buffer *get_video_buffer(
141*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *ctx,
142*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_handle)
143*bbecb9d1SAndroid Build Coastguard Worker {
144*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *buf;
145*bbecb9d1SAndroid Build Coastguard Worker
146*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(buf, &ctx->buffers, head) {
147*bbecb9d1SAndroid Build Coastguard Worker if (buf->handle == buf_handle)
148*bbecb9d1SAndroid Build Coastguard Worker return buf;
149*bbecb9d1SAndroid Build Coastguard Worker }
150*bbecb9d1SAndroid Build Coastguard Worker
151*bbecb9d1SAndroid Build Coastguard Worker return NULL;
152*bbecb9d1SAndroid Build Coastguard Worker }
153*bbecb9d1SAndroid Build Coastguard Worker
154*bbecb9d1SAndroid Build Coastguard Worker
sync_dmabuf_to_video_buffer(struct vrend_video_buffer * buf,const struct virgl_video_dma_buf * dmabuf)155*bbecb9d1SAndroid Build Coastguard Worker static int sync_dmabuf_to_video_buffer(struct vrend_video_buffer *buf,
156*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_video_dma_buf *dmabuf)
157*bbecb9d1SAndroid Build Coastguard Worker {
158*bbecb9d1SAndroid Build Coastguard Worker if (!(dmabuf->flags & VIRGL_VIDEO_DMABUF_READ_ONLY)) {
159*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: dmabuf is not readable\n", __func__);
160*bbecb9d1SAndroid Build Coastguard Worker return -1;
161*bbecb9d1SAndroid Build Coastguard Worker }
162*bbecb9d1SAndroid Build Coastguard Worker
163*bbecb9d1SAndroid Build Coastguard Worker for (unsigned i = 0; i < dmabuf->num_planes && i < buf->num_planes; i++) {
164*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_plane *plane = &buf->planes[i];
165*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
166*bbecb9d1SAndroid Build Coastguard Worker
167*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(buf->ctx->ctx, plane->res_handle);
168*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
169*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: res %d not found\n", __func__, plane->res_handle);
170*bbecb9d1SAndroid Build Coastguard Worker continue;
171*bbecb9d1SAndroid Build Coastguard Worker }
172*bbecb9d1SAndroid Build Coastguard Worker
173*bbecb9d1SAndroid Build Coastguard Worker /* dmabuf -> eglimage */
174*bbecb9d1SAndroid Build Coastguard Worker if (EGL_NO_IMAGE_KHR == plane->egl_image) {
175*bbecb9d1SAndroid Build Coastguard Worker EGLint img_attrs[16] = {
176*bbecb9d1SAndroid Build Coastguard Worker EGL_LINUX_DRM_FOURCC_EXT, dmabuf->planes[i].drm_format,
177*bbecb9d1SAndroid Build Coastguard Worker EGL_WIDTH, dmabuf->width / (i + 1),
178*bbecb9d1SAndroid Build Coastguard Worker EGL_HEIGHT, dmabuf->height / (i + 1),
179*bbecb9d1SAndroid Build Coastguard Worker EGL_DMA_BUF_PLANE0_FD_EXT, dmabuf->planes[i].fd,
180*bbecb9d1SAndroid Build Coastguard Worker EGL_DMA_BUF_PLANE0_OFFSET_EXT, dmabuf->planes[i].offset,
181*bbecb9d1SAndroid Build Coastguard Worker EGL_DMA_BUF_PLANE0_PITCH_EXT, dmabuf->planes[i].pitch,
182*bbecb9d1SAndroid Build Coastguard Worker EGL_NONE
183*bbecb9d1SAndroid Build Coastguard Worker };
184*bbecb9d1SAndroid Build Coastguard Worker
185*bbecb9d1SAndroid Build Coastguard Worker plane->egl_image = eglCreateImageKHR(eglGetCurrentDisplay(),
186*bbecb9d1SAndroid Build Coastguard Worker EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, img_attrs);
187*bbecb9d1SAndroid Build Coastguard Worker }
188*bbecb9d1SAndroid Build Coastguard Worker
189*bbecb9d1SAndroid Build Coastguard Worker if (EGL_NO_IMAGE_KHR == plane->egl_image) {
190*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: create egl image failed\n", __func__);
191*bbecb9d1SAndroid Build Coastguard Worker continue;
192*bbecb9d1SAndroid Build Coastguard Worker }
193*bbecb9d1SAndroid Build Coastguard Worker
194*bbecb9d1SAndroid Build Coastguard Worker /* eglimage -> texture */
195*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, plane->texture);
196*bbecb9d1SAndroid Build Coastguard Worker glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
197*bbecb9d1SAndroid Build Coastguard Worker (GLeglImageOES)(plane->egl_image));
198*bbecb9d1SAndroid Build Coastguard Worker
199*bbecb9d1SAndroid Build Coastguard Worker /* texture -> framebuffer */
200*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, plane->framebuffer);
201*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
202*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, plane->texture, 0);
203*bbecb9d1SAndroid Build Coastguard Worker
204*bbecb9d1SAndroid Build Coastguard Worker /* framebuffer -> vrend_video_buffer.planes[i] */
205*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, res->id);
206*bbecb9d1SAndroid Build Coastguard Worker glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
207*bbecb9d1SAndroid Build Coastguard Worker res->base.width0, res->base.height0);
208*bbecb9d1SAndroid Build Coastguard Worker }
209*bbecb9d1SAndroid Build Coastguard Worker
210*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, 0);
211*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, 0);
212*bbecb9d1SAndroid Build Coastguard Worker
213*bbecb9d1SAndroid Build Coastguard Worker return 0;
214*bbecb9d1SAndroid Build Coastguard Worker }
215*bbecb9d1SAndroid Build Coastguard Worker
sync_video_buffer_to_dmabuf(struct vrend_video_buffer * buf,const struct virgl_video_dma_buf * dmabuf)216*bbecb9d1SAndroid Build Coastguard Worker static int sync_video_buffer_to_dmabuf(struct vrend_video_buffer *buf,
217*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_video_dma_buf *dmabuf)
218*bbecb9d1SAndroid Build Coastguard Worker {
219*bbecb9d1SAndroid Build Coastguard Worker if (!(dmabuf->flags & VIRGL_VIDEO_DMABUF_WRITE_ONLY)) {
220*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: dmabuf is not writable\n", __func__);
221*bbecb9d1SAndroid Build Coastguard Worker return -1;
222*bbecb9d1SAndroid Build Coastguard Worker }
223*bbecb9d1SAndroid Build Coastguard Worker
224*bbecb9d1SAndroid Build Coastguard Worker for (unsigned i = 0; i < dmabuf->num_planes && i < buf->num_planes; i++) {
225*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_plane *plane = &buf->planes[i];
226*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
227*bbecb9d1SAndroid Build Coastguard Worker
228*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(buf->ctx->ctx, plane->res_handle);
229*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
230*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: res %d not found\n", __func__, plane->res_handle);
231*bbecb9d1SAndroid Build Coastguard Worker continue;
232*bbecb9d1SAndroid Build Coastguard Worker }
233*bbecb9d1SAndroid Build Coastguard Worker
234*bbecb9d1SAndroid Build Coastguard Worker /* dmabuf -> eglimage */
235*bbecb9d1SAndroid Build Coastguard Worker if (EGL_NO_IMAGE_KHR == plane->egl_image) {
236*bbecb9d1SAndroid Build Coastguard Worker EGLint img_attrs[16] = {
237*bbecb9d1SAndroid Build Coastguard Worker EGL_LINUX_DRM_FOURCC_EXT, dmabuf->planes[i].drm_format,
238*bbecb9d1SAndroid Build Coastguard Worker EGL_WIDTH, dmabuf->width / (i + 1),
239*bbecb9d1SAndroid Build Coastguard Worker EGL_HEIGHT, dmabuf->height / (i + 1),
240*bbecb9d1SAndroid Build Coastguard Worker EGL_DMA_BUF_PLANE0_FD_EXT, dmabuf->planes[i].fd,
241*bbecb9d1SAndroid Build Coastguard Worker EGL_DMA_BUF_PLANE0_OFFSET_EXT, dmabuf->planes[i].offset,
242*bbecb9d1SAndroid Build Coastguard Worker EGL_DMA_BUF_PLANE0_PITCH_EXT, dmabuf->planes[i].pitch,
243*bbecb9d1SAndroid Build Coastguard Worker EGL_NONE
244*bbecb9d1SAndroid Build Coastguard Worker };
245*bbecb9d1SAndroid Build Coastguard Worker
246*bbecb9d1SAndroid Build Coastguard Worker plane->egl_image = eglCreateImageKHR(eglGetCurrentDisplay(),
247*bbecb9d1SAndroid Build Coastguard Worker EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, img_attrs);
248*bbecb9d1SAndroid Build Coastguard Worker }
249*bbecb9d1SAndroid Build Coastguard Worker
250*bbecb9d1SAndroid Build Coastguard Worker if (EGL_NO_IMAGE_KHR == plane->egl_image) {
251*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: create egl image failed\n", __func__);
252*bbecb9d1SAndroid Build Coastguard Worker continue;
253*bbecb9d1SAndroid Build Coastguard Worker }
254*bbecb9d1SAndroid Build Coastguard Worker
255*bbecb9d1SAndroid Build Coastguard Worker /* eglimage -> texture */
256*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, plane->texture);
257*bbecb9d1SAndroid Build Coastguard Worker glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
258*bbecb9d1SAndroid Build Coastguard Worker (GLeglImageOES)(plane->egl_image));
259*bbecb9d1SAndroid Build Coastguard Worker
260*bbecb9d1SAndroid Build Coastguard Worker /* vrend_video_buffer.planes[i] -> framebuffer */
261*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, plane->framebuffer);
262*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
263*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, res->id, 0);
264*bbecb9d1SAndroid Build Coastguard Worker
265*bbecb9d1SAndroid Build Coastguard Worker /* framebuffer -> texture */
266*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, plane->texture);
267*bbecb9d1SAndroid Build Coastguard Worker glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
268*bbecb9d1SAndroid Build Coastguard Worker res->base.width0, res->base.height0);
269*bbecb9d1SAndroid Build Coastguard Worker
270*bbecb9d1SAndroid Build Coastguard Worker }
271*bbecb9d1SAndroid Build Coastguard Worker
272*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, 0);
273*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, 0);
274*bbecb9d1SAndroid Build Coastguard Worker
275*bbecb9d1SAndroid Build Coastguard Worker return 0;
276*bbecb9d1SAndroid Build Coastguard Worker }
277*bbecb9d1SAndroid Build Coastguard Worker
278*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_decode_completed(struct virgl_video_codec * codec,const struct virgl_video_dma_buf * dmabuf)279*bbecb9d1SAndroid Build Coastguard Worker static void vrend_video_decode_completed(
280*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_codec *codec,
281*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_video_dma_buf *dmabuf)
282*bbecb9d1SAndroid Build Coastguard Worker {
283*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *buf = vrend_video_buffer(dmabuf->buf);
284*bbecb9d1SAndroid Build Coastguard Worker
285*bbecb9d1SAndroid Build Coastguard Worker (void)codec;
286*bbecb9d1SAndroid Build Coastguard Worker
287*bbecb9d1SAndroid Build Coastguard Worker sync_dmabuf_to_video_buffer(buf, dmabuf);
288*bbecb9d1SAndroid Build Coastguard Worker }
289*bbecb9d1SAndroid Build Coastguard Worker
290*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_enocde_upload_picture(struct virgl_video_codec * codec,const struct virgl_video_dma_buf * dmabuf)291*bbecb9d1SAndroid Build Coastguard Worker static void vrend_video_enocde_upload_picture(
292*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_codec *codec,
293*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_video_dma_buf *dmabuf)
294*bbecb9d1SAndroid Build Coastguard Worker {
295*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *buf = vrend_video_buffer(dmabuf->buf);
296*bbecb9d1SAndroid Build Coastguard Worker
297*bbecb9d1SAndroid Build Coastguard Worker (void)codec;
298*bbecb9d1SAndroid Build Coastguard Worker
299*bbecb9d1SAndroid Build Coastguard Worker sync_video_buffer_to_dmabuf(buf, dmabuf);
300*bbecb9d1SAndroid Build Coastguard Worker }
301*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_encode_completed(struct virgl_video_codec * codec,const struct virgl_video_dma_buf * src_buf,const struct virgl_video_dma_buf * ref_buf,unsigned num_coded_bufs,const void * const * coded_bufs,const unsigned * coded_sizes)302*bbecb9d1SAndroid Build Coastguard Worker static void vrend_video_encode_completed(
303*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_codec *codec,
304*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_video_dma_buf *src_buf,
305*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_video_dma_buf *ref_buf,
306*bbecb9d1SAndroid Build Coastguard Worker unsigned num_coded_bufs,
307*bbecb9d1SAndroid Build Coastguard Worker const void * const *coded_bufs,
308*bbecb9d1SAndroid Build Coastguard Worker const unsigned *coded_sizes)
309*bbecb9d1SAndroid Build Coastguard Worker {
310*bbecb9d1SAndroid Build Coastguard Worker void *buf;
311*bbecb9d1SAndroid Build Coastguard Worker unsigned i, size, data_size;
312*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_encode_feedback feedback;
313*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = vrend_video_codec(codec);
314*bbecb9d1SAndroid Build Coastguard Worker
315*bbecb9d1SAndroid Build Coastguard Worker (void)src_buf;
316*bbecb9d1SAndroid Build Coastguard Worker (void)ref_buf;
317*bbecb9d1SAndroid Build Coastguard Worker
318*bbecb9d1SAndroid Build Coastguard Worker if (!cdc->dest_res || !cdc->feed_res)
319*bbecb9d1SAndroid Build Coastguard Worker return;
320*bbecb9d1SAndroid Build Coastguard Worker
321*bbecb9d1SAndroid Build Coastguard Worker memset(&feedback, 0, sizeof(feedback));
322*bbecb9d1SAndroid Build Coastguard Worker
323*bbecb9d1SAndroid Build Coastguard Worker /* sync coded data to guest */
324*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(cdc->dest_res->storage_bits, VREND_STORAGE_GL_BUFFER)) {
325*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(cdc->dest_res->target, cdc->dest_res->id);
326*bbecb9d1SAndroid Build Coastguard Worker buf = glMapBufferRange(cdc->dest_res->target, 0,
327*bbecb9d1SAndroid Build Coastguard Worker cdc->dest_res->base.width0, GL_MAP_WRITE_BIT);
328*bbecb9d1SAndroid Build Coastguard Worker for (i = 0, data_size = 0; i < num_coded_bufs &&
329*bbecb9d1SAndroid Build Coastguard Worker data_size < cdc->dest_res->base.width0; i++) {
330*bbecb9d1SAndroid Build Coastguard Worker size = MIN(cdc->dest_res->base.width0 - data_size, coded_sizes[i]);
331*bbecb9d1SAndroid Build Coastguard Worker memcpy((uint8_t *)buf + data_size, coded_bufs[i], size);
332*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(cdc->dest_res->iov, cdc->dest_res->num_iovs,
333*bbecb9d1SAndroid Build Coastguard Worker data_size, coded_bufs[i], size);
334*bbecb9d1SAndroid Build Coastguard Worker data_size += size;
335*bbecb9d1SAndroid Build Coastguard Worker }
336*bbecb9d1SAndroid Build Coastguard Worker glUnmapBuffer(cdc->dest_res->target);
337*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(cdc->dest_res->target, 0);
338*bbecb9d1SAndroid Build Coastguard Worker feedback.stat = VIRGL_VIDEO_ENCODE_STAT_SUCCESS;
339*bbecb9d1SAndroid Build Coastguard Worker feedback.coded_size = data_size;
340*bbecb9d1SAndroid Build Coastguard Worker } else {
341*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("unexcepted coded res type\n");
342*bbecb9d1SAndroid Build Coastguard Worker feedback.stat = VIRGL_VIDEO_ENCODE_STAT_FAILURE;
343*bbecb9d1SAndroid Build Coastguard Worker feedback.coded_size = 0;
344*bbecb9d1SAndroid Build Coastguard Worker }
345*bbecb9d1SAndroid Build Coastguard Worker
346*bbecb9d1SAndroid Build Coastguard Worker /* send feedback */
347*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(cdc->feed_res->iov, cdc->feed_res->num_iovs,
348*bbecb9d1SAndroid Build Coastguard Worker 0, (char *)(&feedback),
349*bbecb9d1SAndroid Build Coastguard Worker MIN(cdc->feed_res->base.width0, sizeof(feedback)));
350*bbecb9d1SAndroid Build Coastguard Worker
351*bbecb9d1SAndroid Build Coastguard Worker cdc->dest_res = NULL;
352*bbecb9d1SAndroid Build Coastguard Worker cdc->feed_res = NULL;
353*bbecb9d1SAndroid Build Coastguard Worker }
354*bbecb9d1SAndroid Build Coastguard Worker
355*bbecb9d1SAndroid Build Coastguard Worker static struct virgl_video_callbacks video_callbacks = {
356*bbecb9d1SAndroid Build Coastguard Worker .decode_completed = vrend_video_decode_completed,
357*bbecb9d1SAndroid Build Coastguard Worker .encode_upload_picture = vrend_video_enocde_upload_picture,
358*bbecb9d1SAndroid Build Coastguard Worker .encode_completed = vrend_video_encode_completed,
359*bbecb9d1SAndroid Build Coastguard Worker };
360*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_init(int drm_fd)361*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_init(int drm_fd)
362*bbecb9d1SAndroid Build Coastguard Worker {
363*bbecb9d1SAndroid Build Coastguard Worker if (drm_fd < 0)
364*bbecb9d1SAndroid Build Coastguard Worker return -1;
365*bbecb9d1SAndroid Build Coastguard Worker
366*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_init(drm_fd, &video_callbacks, 0);
367*bbecb9d1SAndroid Build Coastguard Worker }
368*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_fini(void)369*bbecb9d1SAndroid Build Coastguard Worker void vrend_video_fini(void)
370*bbecb9d1SAndroid Build Coastguard Worker {
371*bbecb9d1SAndroid Build Coastguard Worker virgl_video_destroy();
372*bbecb9d1SAndroid Build Coastguard Worker }
373*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_fill_caps(union virgl_caps * caps)374*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_fill_caps(union virgl_caps *caps)
375*bbecb9d1SAndroid Build Coastguard Worker {
376*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_fill_caps(caps);
377*bbecb9d1SAndroid Build Coastguard Worker }
378*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_create_codec(struct vrend_video_context * ctx,uint32_t handle,uint32_t profile,uint32_t entrypoint,uint32_t chroma_format,uint32_t level,uint32_t width,uint32_t height,uint32_t max_ref,uint32_t flags)379*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_create_codec(struct vrend_video_context *ctx,
380*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
381*bbecb9d1SAndroid Build Coastguard Worker uint32_t profile,
382*bbecb9d1SAndroid Build Coastguard Worker uint32_t entrypoint,
383*bbecb9d1SAndroid Build Coastguard Worker uint32_t chroma_format,
384*bbecb9d1SAndroid Build Coastguard Worker uint32_t level,
385*bbecb9d1SAndroid Build Coastguard Worker uint32_t width,
386*bbecb9d1SAndroid Build Coastguard Worker uint32_t height,
387*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_ref,
388*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags)
389*bbecb9d1SAndroid Build Coastguard Worker {
390*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = get_video_codec(ctx, handle);
391*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_create_codec_args args;
392*bbecb9d1SAndroid Build Coastguard Worker
393*bbecb9d1SAndroid Build Coastguard Worker if (cdc)
394*bbecb9d1SAndroid Build Coastguard Worker return 0;
395*bbecb9d1SAndroid Build Coastguard Worker
396*bbecb9d1SAndroid Build Coastguard Worker if (profile <= PIPE_VIDEO_PROFILE_UNKNOWN ||
397*bbecb9d1SAndroid Build Coastguard Worker profile >= PIPE_VIDEO_PROFILE_MAX)
398*bbecb9d1SAndroid Build Coastguard Worker return -1;
399*bbecb9d1SAndroid Build Coastguard Worker
400*bbecb9d1SAndroid Build Coastguard Worker if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_UNKNOWN ||
401*bbecb9d1SAndroid Build Coastguard Worker entrypoint > PIPE_VIDEO_ENTRYPOINT_ENCODE)
402*bbecb9d1SAndroid Build Coastguard Worker return -1;
403*bbecb9d1SAndroid Build Coastguard Worker
404*bbecb9d1SAndroid Build Coastguard Worker if (chroma_format >= PIPE_VIDEO_CHROMA_FORMAT_NONE)
405*bbecb9d1SAndroid Build Coastguard Worker return -1;
406*bbecb9d1SAndroid Build Coastguard Worker
407*bbecb9d1SAndroid Build Coastguard Worker if (!width || !height)
408*bbecb9d1SAndroid Build Coastguard Worker return -1;
409*bbecb9d1SAndroid Build Coastguard Worker
410*bbecb9d1SAndroid Build Coastguard Worker cdc = (struct vrend_video_codec *)calloc(1, sizeof(*cdc));
411*bbecb9d1SAndroid Build Coastguard Worker if (!cdc)
412*bbecb9d1SAndroid Build Coastguard Worker return -1;
413*bbecb9d1SAndroid Build Coastguard Worker
414*bbecb9d1SAndroid Build Coastguard Worker args.profile = profile;
415*bbecb9d1SAndroid Build Coastguard Worker args.entrypoint = entrypoint;
416*bbecb9d1SAndroid Build Coastguard Worker args.chroma_format = chroma_format;
417*bbecb9d1SAndroid Build Coastguard Worker args.level = level;
418*bbecb9d1SAndroid Build Coastguard Worker args.width = width;
419*bbecb9d1SAndroid Build Coastguard Worker args.height = height;
420*bbecb9d1SAndroid Build Coastguard Worker args.max_references = max_ref;
421*bbecb9d1SAndroid Build Coastguard Worker args.flags = flags;
422*bbecb9d1SAndroid Build Coastguard Worker args.opaque = cdc;
423*bbecb9d1SAndroid Build Coastguard Worker cdc->codec = virgl_video_create_codec(&args);
424*bbecb9d1SAndroid Build Coastguard Worker if (!cdc->codec) {
425*bbecb9d1SAndroid Build Coastguard Worker free(cdc);
426*bbecb9d1SAndroid Build Coastguard Worker return -1;
427*bbecb9d1SAndroid Build Coastguard Worker }
428*bbecb9d1SAndroid Build Coastguard Worker
429*bbecb9d1SAndroid Build Coastguard Worker cdc->handle = handle;
430*bbecb9d1SAndroid Build Coastguard Worker cdc->ctx = ctx;
431*bbecb9d1SAndroid Build Coastguard Worker list_add(&cdc->head, &ctx->codecs);
432*bbecb9d1SAndroid Build Coastguard Worker
433*bbecb9d1SAndroid Build Coastguard Worker return 0;
434*bbecb9d1SAndroid Build Coastguard Worker }
435*bbecb9d1SAndroid Build Coastguard Worker
destroy_video_codec(struct vrend_video_codec * cdc)436*bbecb9d1SAndroid Build Coastguard Worker static void destroy_video_codec(struct vrend_video_codec *cdc)
437*bbecb9d1SAndroid Build Coastguard Worker {
438*bbecb9d1SAndroid Build Coastguard Worker if (cdc) {
439*bbecb9d1SAndroid Build Coastguard Worker list_del(&cdc->head);
440*bbecb9d1SAndroid Build Coastguard Worker virgl_video_destroy_codec(cdc->codec);
441*bbecb9d1SAndroid Build Coastguard Worker free(cdc);
442*bbecb9d1SAndroid Build Coastguard Worker }
443*bbecb9d1SAndroid Build Coastguard Worker }
444*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_destroy_codec(struct vrend_video_context * ctx,uint32_t handle)445*bbecb9d1SAndroid Build Coastguard Worker void vrend_video_destroy_codec(struct vrend_video_context *ctx,
446*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
447*bbecb9d1SAndroid Build Coastguard Worker {
448*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = get_video_codec(ctx, handle);
449*bbecb9d1SAndroid Build Coastguard Worker
450*bbecb9d1SAndroid Build Coastguard Worker destroy_video_codec(cdc);
451*bbecb9d1SAndroid Build Coastguard Worker }
452*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_create_buffer(struct vrend_video_context * ctx,uint32_t handle,uint32_t format,uint32_t width,uint32_t height,uint32_t * res_handles,unsigned int num_res)453*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_create_buffer(struct vrend_video_context *ctx,
454*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
455*bbecb9d1SAndroid Build Coastguard Worker uint32_t format,
456*bbecb9d1SAndroid Build Coastguard Worker uint32_t width,
457*bbecb9d1SAndroid Build Coastguard Worker uint32_t height,
458*bbecb9d1SAndroid Build Coastguard Worker uint32_t *res_handles,
459*bbecb9d1SAndroid Build Coastguard Worker unsigned int num_res)
460*bbecb9d1SAndroid Build Coastguard Worker {
461*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
462*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_plane *plane;
463*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *buf = get_video_buffer(ctx, handle);
464*bbecb9d1SAndroid Build Coastguard Worker struct virgl_video_create_buffer_args args;
465*bbecb9d1SAndroid Build Coastguard Worker
466*bbecb9d1SAndroid Build Coastguard Worker if (buf)
467*bbecb9d1SAndroid Build Coastguard Worker return 0;
468*bbecb9d1SAndroid Build Coastguard Worker
469*bbecb9d1SAndroid Build Coastguard Worker if (format <= PIPE_FORMAT_NONE || format >= PIPE_FORMAT_COUNT)
470*bbecb9d1SAndroid Build Coastguard Worker return -1;
471*bbecb9d1SAndroid Build Coastguard Worker
472*bbecb9d1SAndroid Build Coastguard Worker if (!width || !height || !res_handles || !num_res)
473*bbecb9d1SAndroid Build Coastguard Worker return -1;
474*bbecb9d1SAndroid Build Coastguard Worker
475*bbecb9d1SAndroid Build Coastguard Worker buf = (struct vrend_video_buffer *)calloc(1, sizeof(*buf));
476*bbecb9d1SAndroid Build Coastguard Worker if (!buf)
477*bbecb9d1SAndroid Build Coastguard Worker return -1;
478*bbecb9d1SAndroid Build Coastguard Worker
479*bbecb9d1SAndroid Build Coastguard Worker args.format = format;
480*bbecb9d1SAndroid Build Coastguard Worker args.width = width;
481*bbecb9d1SAndroid Build Coastguard Worker args.height = height;
482*bbecb9d1SAndroid Build Coastguard Worker args.interlaced = 0;
483*bbecb9d1SAndroid Build Coastguard Worker args.opaque = buf;
484*bbecb9d1SAndroid Build Coastguard Worker buf->buffer = virgl_video_create_buffer(&args);
485*bbecb9d1SAndroid Build Coastguard Worker if (!buf->buffer) {
486*bbecb9d1SAndroid Build Coastguard Worker free(buf);
487*bbecb9d1SAndroid Build Coastguard Worker return -1;
488*bbecb9d1SAndroid Build Coastguard Worker }
489*bbecb9d1SAndroid Build Coastguard Worker
490*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(buf->planes); i++)
491*bbecb9d1SAndroid Build Coastguard Worker buf->planes[i].egl_image = EGL_NO_IMAGE_KHR;
492*bbecb9d1SAndroid Build Coastguard Worker
493*bbecb9d1SAndroid Build Coastguard Worker for (i = 0, buf->num_planes = 0;
494*bbecb9d1SAndroid Build Coastguard Worker i < num_res && buf->num_planes < ARRAY_SIZE(buf->planes); i++) {
495*bbecb9d1SAndroid Build Coastguard Worker
496*bbecb9d1SAndroid Build Coastguard Worker if (!res_handles[i])
497*bbecb9d1SAndroid Build Coastguard Worker continue;
498*bbecb9d1SAndroid Build Coastguard Worker
499*bbecb9d1SAndroid Build Coastguard Worker plane = &buf->planes[buf->num_planes++];
500*bbecb9d1SAndroid Build Coastguard Worker plane->res_handle = res_handles[i];
501*bbecb9d1SAndroid Build Coastguard Worker glGenFramebuffers(1, &plane->framebuffer);
502*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &plane->texture);
503*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, plane->texture);
504*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
505*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
506*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
507*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
508*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, 0);
509*bbecb9d1SAndroid Build Coastguard Worker }
510*bbecb9d1SAndroid Build Coastguard Worker
511*bbecb9d1SAndroid Build Coastguard Worker buf->handle = handle;
512*bbecb9d1SAndroid Build Coastguard Worker buf->ctx = ctx;
513*bbecb9d1SAndroid Build Coastguard Worker list_add(&buf->head, &ctx->buffers);
514*bbecb9d1SAndroid Build Coastguard Worker
515*bbecb9d1SAndroid Build Coastguard Worker return 0;
516*bbecb9d1SAndroid Build Coastguard Worker }
517*bbecb9d1SAndroid Build Coastguard Worker
destroy_video_buffer(struct vrend_video_buffer * buf)518*bbecb9d1SAndroid Build Coastguard Worker static void destroy_video_buffer(struct vrend_video_buffer *buf)
519*bbecb9d1SAndroid Build Coastguard Worker {
520*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
521*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_plane *plane;
522*bbecb9d1SAndroid Build Coastguard Worker
523*bbecb9d1SAndroid Build Coastguard Worker if (!buf)
524*bbecb9d1SAndroid Build Coastguard Worker return;
525*bbecb9d1SAndroid Build Coastguard Worker
526*bbecb9d1SAndroid Build Coastguard Worker list_del(&buf->head);
527*bbecb9d1SAndroid Build Coastguard Worker
528*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < buf->num_planes; i++) {
529*bbecb9d1SAndroid Build Coastguard Worker plane = &buf->planes[i];
530*bbecb9d1SAndroid Build Coastguard Worker
531*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &plane->texture);
532*bbecb9d1SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &plane->framebuffer);
533*bbecb9d1SAndroid Build Coastguard Worker if (plane->egl_image == EGL_NO_IMAGE_KHR)
534*bbecb9d1SAndroid Build Coastguard Worker eglDestroyImageKHR(eglGetCurrentDisplay(), plane->egl_image);
535*bbecb9d1SAndroid Build Coastguard Worker }
536*bbecb9d1SAndroid Build Coastguard Worker
537*bbecb9d1SAndroid Build Coastguard Worker virgl_video_destroy_buffer(buf->buffer);
538*bbecb9d1SAndroid Build Coastguard Worker
539*bbecb9d1SAndroid Build Coastguard Worker free(buf);
540*bbecb9d1SAndroid Build Coastguard Worker }
541*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_destroy_buffer(struct vrend_video_context * ctx,uint32_t handle)542*bbecb9d1SAndroid Build Coastguard Worker void vrend_video_destroy_buffer(struct vrend_video_context *ctx,
543*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
544*bbecb9d1SAndroid Build Coastguard Worker {
545*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *buf = get_video_buffer(ctx, handle);
546*bbecb9d1SAndroid Build Coastguard Worker
547*bbecb9d1SAndroid Build Coastguard Worker destroy_video_buffer(buf);
548*bbecb9d1SAndroid Build Coastguard Worker }
549*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_create_context(struct vrend_context * ctx)550*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vrend_video_create_context(struct vrend_context *ctx)
551*bbecb9d1SAndroid Build Coastguard Worker {
552*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vctx;
553*bbecb9d1SAndroid Build Coastguard Worker
554*bbecb9d1SAndroid Build Coastguard Worker vctx = (struct vrend_video_context *)calloc(1, sizeof(*vctx));
555*bbecb9d1SAndroid Build Coastguard Worker if (vctx) {
556*bbecb9d1SAndroid Build Coastguard Worker vctx->ctx = ctx;
557*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&vctx->codecs);
558*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&vctx->buffers);
559*bbecb9d1SAndroid Build Coastguard Worker }
560*bbecb9d1SAndroid Build Coastguard Worker
561*bbecb9d1SAndroid Build Coastguard Worker return vctx;
562*bbecb9d1SAndroid Build Coastguard Worker }
563*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_destroy_context(struct vrend_video_context * ctx)564*bbecb9d1SAndroid Build Coastguard Worker void vrend_video_destroy_context(struct vrend_video_context *ctx)
565*bbecb9d1SAndroid Build Coastguard Worker {
566*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *vcdc, *vcdc_tmp;
567*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *vbuf, *vbuf_tmp;
568*bbecb9d1SAndroid Build Coastguard Worker
569*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(vcdc, vcdc_tmp, &ctx->codecs, head)
570*bbecb9d1SAndroid Build Coastguard Worker destroy_video_codec(vcdc);
571*bbecb9d1SAndroid Build Coastguard Worker
572*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(vbuf, vbuf_tmp, &ctx->buffers, head)
573*bbecb9d1SAndroid Build Coastguard Worker destroy_video_buffer(vbuf);
574*bbecb9d1SAndroid Build Coastguard Worker
575*bbecb9d1SAndroid Build Coastguard Worker free(ctx);
576*bbecb9d1SAndroid Build Coastguard Worker }
577*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_begin_frame(struct vrend_video_context * ctx,uint32_t cdc_handle,uint32_t tgt_handle)578*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_begin_frame(struct vrend_video_context *ctx,
579*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle,
580*bbecb9d1SAndroid Build Coastguard Worker uint32_t tgt_handle)
581*bbecb9d1SAndroid Build Coastguard Worker {
582*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = get_video_codec(ctx, cdc_handle);
583*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *tgt = get_video_buffer(ctx, tgt_handle);
584*bbecb9d1SAndroid Build Coastguard Worker
585*bbecb9d1SAndroid Build Coastguard Worker if (!cdc || !tgt)
586*bbecb9d1SAndroid Build Coastguard Worker return -1;
587*bbecb9d1SAndroid Build Coastguard Worker
588*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_begin_frame(cdc->codec, tgt->buffer);
589*bbecb9d1SAndroid Build Coastguard Worker }
590*bbecb9d1SAndroid Build Coastguard Worker
modify_h264_picture_desc(struct vrend_video_codec * cdc,struct vrend_video_buffer * tgt,struct virgl_h264_picture_desc * desc)591*bbecb9d1SAndroid Build Coastguard Worker static void modify_h264_picture_desc(struct vrend_video_codec *cdc,
592*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *tgt,
593*bbecb9d1SAndroid Build Coastguard Worker struct virgl_h264_picture_desc *desc)
594*bbecb9d1SAndroid Build Coastguard Worker {
595*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
596*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *vbuf;
597*bbecb9d1SAndroid Build Coastguard Worker
598*bbecb9d1SAndroid Build Coastguard Worker (void)tgt;
599*bbecb9d1SAndroid Build Coastguard Worker
600*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(desc->buffer_id); i++) {
601*bbecb9d1SAndroid Build Coastguard Worker vbuf = get_video_buffer(cdc->ctx, desc->buffer_id[i]);
602*bbecb9d1SAndroid Build Coastguard Worker desc->buffer_id[i] = virgl_video_buffer_id(vbuf ? vbuf->buffer : NULL);
603*bbecb9d1SAndroid Build Coastguard Worker }
604*bbecb9d1SAndroid Build Coastguard Worker }
605*bbecb9d1SAndroid Build Coastguard Worker
modify_h265_picture_desc(struct vrend_video_codec * cdc,struct vrend_video_buffer * tgt,struct virgl_h265_picture_desc * desc)606*bbecb9d1SAndroid Build Coastguard Worker static void modify_h265_picture_desc(struct vrend_video_codec *cdc,
607*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *tgt,
608*bbecb9d1SAndroid Build Coastguard Worker struct virgl_h265_picture_desc *desc)
609*bbecb9d1SAndroid Build Coastguard Worker {
610*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
611*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *vbuf;
612*bbecb9d1SAndroid Build Coastguard Worker
613*bbecb9d1SAndroid Build Coastguard Worker (void)tgt;
614*bbecb9d1SAndroid Build Coastguard Worker
615*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(desc->ref); i++) {
616*bbecb9d1SAndroid Build Coastguard Worker vbuf = get_video_buffer(cdc->ctx, desc->ref[i]);
617*bbecb9d1SAndroid Build Coastguard Worker desc->ref[i] = virgl_video_buffer_id(vbuf ? vbuf->buffer : NULL);
618*bbecb9d1SAndroid Build Coastguard Worker }
619*bbecb9d1SAndroid Build Coastguard Worker }
620*bbecb9d1SAndroid Build Coastguard Worker
modify_picture_desc(struct vrend_video_codec * cdc,struct vrend_video_buffer * tgt,union virgl_picture_desc * desc)621*bbecb9d1SAndroid Build Coastguard Worker static void modify_picture_desc(struct vrend_video_codec *cdc,
622*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *tgt,
623*bbecb9d1SAndroid Build Coastguard Worker union virgl_picture_desc *desc)
624*bbecb9d1SAndroid Build Coastguard Worker {
625*bbecb9d1SAndroid Build Coastguard Worker switch(virgl_video_codec_profile(cdc->codec)) {
626*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
627*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
628*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
629*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
630*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
631*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
632*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
633*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
634*bbecb9d1SAndroid Build Coastguard Worker modify_h264_picture_desc(cdc, tgt, &desc->h264);
635*bbecb9d1SAndroid Build Coastguard Worker break;
636*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_HEVC_MAIN:
637*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
638*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL:
639*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_HEVC_MAIN_12:
640*bbecb9d1SAndroid Build Coastguard Worker case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
641*bbecb9d1SAndroid Build Coastguard Worker modify_h265_picture_desc(cdc, tgt, &desc->h265);
642*bbecb9d1SAndroid Build Coastguard Worker break;
643*bbecb9d1SAndroid Build Coastguard Worker default:
644*bbecb9d1SAndroid Build Coastguard Worker break;
645*bbecb9d1SAndroid Build Coastguard Worker }
646*bbecb9d1SAndroid Build Coastguard Worker }
647*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_decode_bitstream(struct vrend_video_context * ctx,uint32_t cdc_handle,uint32_t tgt_handle,uint32_t desc_handle,unsigned num_buffers,const uint32_t * buffer_handles,const uint32_t * buffer_sizes)648*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_decode_bitstream(struct vrend_video_context *ctx,
649*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle,
650*bbecb9d1SAndroid Build Coastguard Worker uint32_t tgt_handle,
651*bbecb9d1SAndroid Build Coastguard Worker uint32_t desc_handle,
652*bbecb9d1SAndroid Build Coastguard Worker unsigned num_buffers,
653*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buffer_handles,
654*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *buffer_sizes)
655*bbecb9d1SAndroid Build Coastguard Worker {
656*bbecb9d1SAndroid Build Coastguard Worker int err = -1;
657*bbecb9d1SAndroid Build Coastguard Worker unsigned i, num_bs, *bs_sizes = NULL;
658*bbecb9d1SAndroid Build Coastguard Worker void **bs_buffers = NULL;
659*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
660*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = get_video_codec(ctx, cdc_handle);
661*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *tgt = get_video_buffer(ctx, tgt_handle);
662*bbecb9d1SAndroid Build Coastguard Worker union virgl_picture_desc desc;
663*bbecb9d1SAndroid Build Coastguard Worker
664*bbecb9d1SAndroid Build Coastguard Worker if (!cdc || !tgt)
665*bbecb9d1SAndroid Build Coastguard Worker return -1;
666*bbecb9d1SAndroid Build Coastguard Worker
667*bbecb9d1SAndroid Build Coastguard Worker bs_buffers = calloc(num_buffers, sizeof(void *));
668*bbecb9d1SAndroid Build Coastguard Worker if (!bs_buffers) {
669*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: alloc bs_buffers failed\n", __func__);
670*bbecb9d1SAndroid Build Coastguard Worker return -1;
671*bbecb9d1SAndroid Build Coastguard Worker }
672*bbecb9d1SAndroid Build Coastguard Worker
673*bbecb9d1SAndroid Build Coastguard Worker bs_sizes = calloc(num_buffers, sizeof(unsigned));
674*bbecb9d1SAndroid Build Coastguard Worker if (!bs_sizes) {
675*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: alloc bs_sizes failed\n", __func__);
676*bbecb9d1SAndroid Build Coastguard Worker goto err;
677*bbecb9d1SAndroid Build Coastguard Worker }
678*bbecb9d1SAndroid Build Coastguard Worker
679*bbecb9d1SAndroid Build Coastguard Worker for (i = 0, num_bs = 0; i < num_buffers; i++) {
680*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx->ctx, buffer_handles[i]);
681*bbecb9d1SAndroid Build Coastguard Worker if (!res || !res->ptr) {
682*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: bs res %d invalid or not found",
683*bbecb9d1SAndroid Build Coastguard Worker __func__, buffer_handles[i]);
684*bbecb9d1SAndroid Build Coastguard Worker continue;
685*bbecb9d1SAndroid Build Coastguard Worker }
686*bbecb9d1SAndroid Build Coastguard Worker
687*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(res->iov, res->num_iovs, 0,
688*bbecb9d1SAndroid Build Coastguard Worker res->ptr, buffer_sizes[i]);
689*bbecb9d1SAndroid Build Coastguard Worker bs_buffers[num_bs] = res->ptr;
690*bbecb9d1SAndroid Build Coastguard Worker bs_sizes[num_bs] = buffer_sizes[i];
691*bbecb9d1SAndroid Build Coastguard Worker num_bs++;
692*bbecb9d1SAndroid Build Coastguard Worker }
693*bbecb9d1SAndroid Build Coastguard Worker
694*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx->ctx, desc_handle);
695*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
696*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: desc res %d not found\n", __func__, desc_handle);
697*bbecb9d1SAndroid Build Coastguard Worker goto err;
698*bbecb9d1SAndroid Build Coastguard Worker }
699*bbecb9d1SAndroid Build Coastguard Worker memset(&desc, 0, sizeof(desc));
700*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(res->iov, res->num_iovs, 0, (char *)(&desc),
701*bbecb9d1SAndroid Build Coastguard Worker MIN(res->base.width0, sizeof(desc)));
702*bbecb9d1SAndroid Build Coastguard Worker modify_picture_desc(cdc, tgt, &desc);
703*bbecb9d1SAndroid Build Coastguard Worker
704*bbecb9d1SAndroid Build Coastguard Worker err = virgl_video_decode_bitstream(cdc->codec, tgt->buffer, &desc,
705*bbecb9d1SAndroid Build Coastguard Worker num_bs, (const void * const *)bs_buffers, bs_sizes);
706*bbecb9d1SAndroid Build Coastguard Worker
707*bbecb9d1SAndroid Build Coastguard Worker err:
708*bbecb9d1SAndroid Build Coastguard Worker free(bs_buffers);
709*bbecb9d1SAndroid Build Coastguard Worker free(bs_sizes);
710*bbecb9d1SAndroid Build Coastguard Worker
711*bbecb9d1SAndroid Build Coastguard Worker return err;
712*bbecb9d1SAndroid Build Coastguard Worker }
713*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_encode_bitstream(struct vrend_video_context * ctx,uint32_t cdc_handle,uint32_t src_handle,uint32_t dest_handle,uint32_t desc_handle,uint32_t feed_handle)714*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_encode_bitstream(struct vrend_video_context *ctx,
715*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle,
716*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_handle,
717*bbecb9d1SAndroid Build Coastguard Worker uint32_t dest_handle,
718*bbecb9d1SAndroid Build Coastguard Worker uint32_t desc_handle,
719*bbecb9d1SAndroid Build Coastguard Worker uint32_t feed_handle)
720*bbecb9d1SAndroid Build Coastguard Worker {
721*bbecb9d1SAndroid Build Coastguard Worker union virgl_picture_desc desc;
722*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dest_res, *desc_res, *feed_res;
723*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = get_video_codec(ctx, cdc_handle);
724*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *src = get_video_buffer(ctx, src_handle);
725*bbecb9d1SAndroid Build Coastguard Worker
726*bbecb9d1SAndroid Build Coastguard Worker if (!cdc || !src)
727*bbecb9d1SAndroid Build Coastguard Worker return -1;
728*bbecb9d1SAndroid Build Coastguard Worker
729*bbecb9d1SAndroid Build Coastguard Worker /* Feedback resource */
730*bbecb9d1SAndroid Build Coastguard Worker feed_res = vrend_renderer_ctx_res_lookup(ctx->ctx, feed_handle);
731*bbecb9d1SAndroid Build Coastguard Worker if (!feed_res) {
732*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: feedback res %d not found\n", __func__, feed_handle);
733*bbecb9d1SAndroid Build Coastguard Worker return -1;
734*bbecb9d1SAndroid Build Coastguard Worker }
735*bbecb9d1SAndroid Build Coastguard Worker
736*bbecb9d1SAndroid Build Coastguard Worker /* Picture descriptor resource */
737*bbecb9d1SAndroid Build Coastguard Worker desc_res = vrend_renderer_ctx_res_lookup(ctx->ctx, desc_handle);
738*bbecb9d1SAndroid Build Coastguard Worker if (!desc_res) {
739*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: desc res %d not found\n", __func__, desc_handle);
740*bbecb9d1SAndroid Build Coastguard Worker return -1;
741*bbecb9d1SAndroid Build Coastguard Worker }
742*bbecb9d1SAndroid Build Coastguard Worker memset(&desc, 0, sizeof(desc));
743*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(desc_res->iov, desc_res->num_iovs, 0, (char *)(&desc),
744*bbecb9d1SAndroid Build Coastguard Worker MIN(desc_res->base.width0, sizeof(desc)));
745*bbecb9d1SAndroid Build Coastguard Worker
746*bbecb9d1SAndroid Build Coastguard Worker /* Destination buffer resource. */
747*bbecb9d1SAndroid Build Coastguard Worker dest_res = vrend_renderer_ctx_res_lookup(ctx->ctx, dest_handle);
748*bbecb9d1SAndroid Build Coastguard Worker if (!dest_res) {
749*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: dest res %d not found\n", __func__, dest_handle);
750*bbecb9d1SAndroid Build Coastguard Worker return -1;
751*bbecb9d1SAndroid Build Coastguard Worker }
752*bbecb9d1SAndroid Build Coastguard Worker
753*bbecb9d1SAndroid Build Coastguard Worker cdc->feed_res = feed_res;
754*bbecb9d1SAndroid Build Coastguard Worker cdc->dest_res = dest_res;
755*bbecb9d1SAndroid Build Coastguard Worker
756*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_encode_bitstream(cdc->codec, src->buffer, &desc);
757*bbecb9d1SAndroid Build Coastguard Worker }
758*bbecb9d1SAndroid Build Coastguard Worker
vrend_video_end_frame(struct vrend_video_context * ctx,uint32_t cdc_handle,uint32_t tgt_handle)759*bbecb9d1SAndroid Build Coastguard Worker int vrend_video_end_frame(struct vrend_video_context *ctx,
760*bbecb9d1SAndroid Build Coastguard Worker uint32_t cdc_handle,
761*bbecb9d1SAndroid Build Coastguard Worker uint32_t tgt_handle)
762*bbecb9d1SAndroid Build Coastguard Worker {
763*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_codec *cdc = get_video_codec(ctx, cdc_handle);
764*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_buffer *tgt = get_video_buffer(ctx, tgt_handle);
765*bbecb9d1SAndroid Build Coastguard Worker
766*bbecb9d1SAndroid Build Coastguard Worker if (!cdc || !tgt)
767*bbecb9d1SAndroid Build Coastguard Worker return -1;
768*bbecb9d1SAndroid Build Coastguard Worker
769*bbecb9d1SAndroid Build Coastguard Worker return virgl_video_end_frame(cdc->codec, tgt->buffer);
770*bbecb9d1SAndroid Build Coastguard Worker }
771*bbecb9d1SAndroid Build Coastguard Worker
772