1 /*
2 * Copyright (c) 2009-2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file      media_libva_putsurface_linux.cpp
24 //! \brief     libva(and its extension) putsurface linux implementaion
25 //!
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 
32 #include <fcntl.h>     //open
33 #include <sys/stat.h>  //fstat
34 #include <unistd.h>    //read, lseek
35 #include <dlfcn.h>     //dlopen,dlsym,dlclose
36 #include <time.h>      //get_clocktime
37 #include <errno.h>     //errno
38 #include <assert.h>    //assert
39 
40 #include <sys/mman.h>
41 #include <dlfcn.h>
42 #include <sys/ioctl.h>
43 #include <X11/Xlib.h>
44 #include <X11/Xutil.h>
45 
46 #include "media_libva_putsurface_linux.h"
47 #include "media_libva_util.h"
48 #include "media_libva_common.h"
49 #include "media_libva_vp.h"
50 
51 extern MOS_FORMAT     VpGetFormatFromMediaFormat(DDI_MEDIA_FORMAT mf);
52 extern VPHAL_CSPACE   DdiVp_GetColorSpaceFromMediaFormat(DDI_MEDIA_FORMAT mf);
53 extern MOS_TILE_TYPE  VpGetTileTypeFromMediaTileType(uint32_t mediaTileType);
54 
55 /* Closes and disposed any allocated data */
dso_close(struct dso_handle * h)56 void dso_close(struct dso_handle *h)
57 {
58     if (!h){
59         return;
60     }
61 
62     if (h->handle) {
63         if (h->handle != RTLD_DEFAULT)
64             dlclose(h->handle);
65         h->handle = nullptr;
66     }
67     free(h);
68 }
69 
70 /* Opens the named shared library */
dso_open(const char * path)71 struct dso_handle * dso_open(const char *path)
72 {
73     struct dso_handle *h = nullptr;
74 
75     h = (dso_handle *)calloc(1, sizeof(*h));
76     if (!h){
77         return nullptr;
78     }
79 
80     if (path) {
81         h->handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL);
82         if (!h->handle)
83             goto error;
84     }
85     else{
86         h->handle = RTLD_DEFAULT;
87     }
88     return h;
89 
90 error:
91     dso_close(h);
92     return nullptr;
93 }
94 
95 /* Load function name from one dynamic lib */
get_symbol(struct dso_handle * h,void * func_vptr,const char * name)96 static bool get_symbol(struct dso_handle *h, void *func_vptr, const char *name)
97 {
98     DDI_CHK_NULL(h, "nullptr h", false);
99     DDI_CHK_NULL(func_vptr, "nullptr func_vptr", false);
100 
101     dso_generic_func func;
102     dso_generic_func * const func_ptr = (dso_generic_func*) func_vptr;
103     const char *error = nullptr;
104 
105     dlerror();
106     func = (dso_generic_func)dlsym(h->handle, name);
107     error = dlerror();
108     if (error) {
109         fprintf(stderr, "error: failed to resolve %s(): %s\n", name, error);
110         return false;
111     }
112     *func_ptr = func;
113     return true;
114 }
115 
116 //!
117 //! \brief  Loads function name from vtable
118 //!
119 //! \param  [in] h
120 //!     Dso handle
121 //! \param  [in] vtable
122 //!     VA api table
123 //! \param  [in] vtable_length
124 //!     Length of VA api table
125 //! \param  [in] symbols
126 //!     Dso symbol
127 //!
128 //! \return     bool
129 //!     true if call success, else false
130 //!
131 bool
dso_get_symbols(struct dso_handle * h,void * vtable,uint32_t vtable_length,const struct dso_symbol * symbols)132 dso_get_symbols(
133     struct dso_handle          *h,
134     void                       *vtable,
135     uint32_t                    vtable_length,
136     const struct dso_symbol    *symbols
137 )
138 {
139     DDI_CHK_NULL(h, "nullptr h", false);
140 
141     const struct dso_symbol *s = nullptr;
142     if (nullptr == symbols)
143     {
144         return VA_STATUS_ERROR_INVALID_PARAMETER;
145     }
146     for (s = symbols; s->name != nullptr; s++) {
147         if (s->offset + sizeof(dso_generic_func) > vtable_length)
148             return false;
149         if (!get_symbol(h, ((char *)vtable) + s->offset, s->name))
150             return false;
151     }
152     return true;
153 }
154 
output_dri_init(VADriverContextP ctx)155 bool output_dri_init(VADriverContextP ctx)
156 {
157     DDI_CHK_NULL(ctx, "nullptr ctx", false);
158 
159     PDDI_MEDIA_CONTEXT mediaDrvCtx = nullptr;
160     mediaDrvCtx = DdiMedia_GetMediaContext(ctx);
161     DDI_CHK_NULL(mediaDrvCtx, "nullptr ctx", false);
162 
163     struct dso_handle *dso_handle = nullptr;
164     struct dri_vtable *dri_vtable = nullptr;
165 
166     mediaDrvCtx->dri_output = nullptr;
167 
168     static const struct dso_symbol symbols[] = {
169         { "va_dri_get_drawable",
170           offsetof(struct dri_vtable, get_drawable) },
171         { "va_dri_get_rendering_buffer",
172           offsetof(struct dri_vtable, get_rendering_buffer) },
173         { "va_dri_swap_buffer",
174           offsetof(struct dri_vtable, swap_buffer) },
175         { nullptr, }
176     };
177 
178     mediaDrvCtx->dri_output = (va_dri_output*) calloc(1, sizeof(struct va_dri_output));
179     if (!mediaDrvCtx->dri_output){
180         goto error;
181     }
182 
183     mediaDrvCtx->dri_output->handle = dso_open(LIBVA_X11_NAME);
184     if (!mediaDrvCtx->dri_output->handle){
185         free(mediaDrvCtx->dri_output);
186         mediaDrvCtx->dri_output = nullptr;
187         goto error;
188     }
189 
190     dso_handle = mediaDrvCtx->dri_output->handle;
191     dri_vtable = &mediaDrvCtx->dri_output->vtable;
192     if (!dso_get_symbols(dso_handle, dri_vtable, sizeof(*dri_vtable), symbols)){
193         dso_close(mediaDrvCtx->dri_output->handle);
194         free(mediaDrvCtx->dri_output);
195         mediaDrvCtx->dri_output = nullptr;
196         goto error;
197     }
198     return true;
199 
200 error:
201     return false;
202 }
203 
204 void
Rect_init(RECT * rect,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth)205 inline Rect_init(
206     RECT            *rect,
207     int16_t          destx,
208     int16_t          desty,
209     uint16_t         destw,
210     uint16_t         desth
211 )
212 {
213     if (nullptr == rect)
214     {
215         return;
216     }
217     rect->left                    = destx;
218     rect->top                     = desty;
219     rect->right                   = destx + destw;
220     rect->bottom                  = desty + desth;
221 }
222 
DdiCodec_PutSurfaceLinuxVphalExt(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)223 VAStatus DdiCodec_PutSurfaceLinuxVphalExt(
224     VADriverContextP ctx,
225     VASurfaceID      surface,
226     void            *draw,             /* Drawable of window system */
227     int16_t          srcx,
228     int16_t          srcy,
229     uint16_t         srcw,
230     uint16_t         srch,
231     int16_t          destx,
232     int16_t          desty,
233     uint16_t         destw,
234     uint16_t         desth,
235     VARectangle     *cliprects,       /* client supplied clip list */
236     uint32_t         number_cliprects, /* number of clip rects in the clip list */
237     uint32_t         flags             /* de-interlacing flags */
238 )
239 {
240     GC                        gc;
241     int32_t                   depth;
242     Visual*                   visual;
243     XImage*                   ximg;
244     int32_t                   surf_width;
245     int32_t                   surf_height;
246     PDDI_MEDIA_CONTEXT        mediaDrvCtx;
247     PDDI_MEDIA_SURFACE        dstSurfBuffObj;
248 
249     TypeXCreateGC             pfn_XCreateGC = nullptr;
250     TypeXFreeGC               pfn_XFreeGC = nullptr;
251     TypeXCreateImage          pfn_XCreateImage = nullptr;
252     TypeXDestroyImage         pfn_XDestroyImage = nullptr;
253     TypeXPutImage             pfn_XPutImage = nullptr;
254 
255     if (nullptr == draw)
256     {
257         return VA_STATUS_ERROR_UNKNOWN;
258     }
259 
260     visual                    = nullptr;
261     ximg                     = nullptr;
262     mediaDrvCtx              = DdiMedia_GetMediaContext(ctx);
263     dstSurfBuffObj           = DdiMedia_GetSurfaceFromVASurfaceID(mediaDrvCtx, surface);
264 
265     if (nullptr == dstSurfBuffObj)
266     {
267         return VA_STATUS_ERROR_UNKNOWN;
268     }
269 
270     if (nullptr == mediaDrvCtx->X11FuncTable                   ||
271         nullptr == mediaDrvCtx->X11FuncTable->pfnXCreateGC     ||
272         nullptr == mediaDrvCtx->X11FuncTable->pfnXFreeGC       ||
273         nullptr == mediaDrvCtx->X11FuncTable->pfnXCreateImage  ||
274         nullptr == mediaDrvCtx->X11FuncTable->pfnXDestroyImage ||
275         nullptr == mediaDrvCtx->X11FuncTable->pfnXPutImage)
276     {
277         return VA_STATUS_ERROR_UNKNOWN;
278     }
279 
280     pfn_XCreateGC     = (TypeXCreateGC)(mediaDrvCtx->X11FuncTable->pfnXCreateGC);
281     pfn_XFreeGC       = (TypeXFreeGC)(mediaDrvCtx->X11FuncTable->pfnXFreeGC);
282     pfn_XCreateImage  = (TypeXCreateImage)(mediaDrvCtx->X11FuncTable->pfnXCreateImage);
283     pfn_XDestroyImage = (TypeXDestroyImage)(mediaDrvCtx->X11FuncTable->pfnXDestroyImage);
284     pfn_XPutImage     = (TypeXPutImage)(mediaDrvCtx->X11FuncTable->pfnXPutImage);
285 
286     surf_width  = dstSurfBuffObj->iWidth;
287     surf_height = dstSurfBuffObj->iHeight;
288 
289     visual = DefaultVisual(ctx->native_dpy, ctx->x11_screen);
290     gc     = (*pfn_XCreateGC)((Display*)ctx->native_dpy, (Drawable)draw, 0, nullptr);
291     depth  = DefaultDepth(ctx->native_dpy, ctx->x11_screen);
292 
293     if (TrueColor != visual->c_class)
294     {
295         DDI_ASSERTMESSAGE("Default visual of X display must be TrueColor.");
296         (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
297         return VA_STATUS_ERROR_UNKNOWN;
298     }
299 
300     ximg = (*pfn_XCreateImage)((Display*)ctx->native_dpy, visual, depth, ZPixmap, 0, nullptr,surf_width, surf_height, 32, 0 );
301 
302     if (nullptr == ximg)
303     {
304         return VA_STATUS_ERROR_ALLOCATION_FAILED;
305     }
306 
307     if (ximg->bits_per_pixel != 32)
308     {
309         DDI_ASSERTMESSAGE("Display uses %d bits/pixel this not supported.",ximg->bits_per_pixel);
310         (*pfn_XDestroyImage)(ximg);
311         (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
312         return VA_STATUS_ERROR_UNKNOWN;
313     }
314 
315     ximg->data = (char *)DdiMediaUtil_LockSurface(dstSurfBuffObj, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY));
316 
317     if (nullptr == ximg->data)
318     {
319         DdiMediaUtil_UnlockSurface(dstSurfBuffObj);
320         (*pfn_XDestroyImage)(ximg);
321         (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
322         return VA_STATUS_ERROR_ALLOCATION_FAILED;
323     }
324 
325     (*pfn_XPutImage)((Display*)ctx->native_dpy, (Drawable)draw, gc, ximg, 0, 0, destx, desty, surf_width, surf_height);
326 
327     DdiMediaUtil_UnlockSurface(dstSurfBuffObj);
328     ximg->data = nullptr;
329 
330     if (nullptr != ximg)
331     {
332         (*pfn_XDestroyImage)(ximg);
333     }
334 
335     (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
336 
337     return VA_STATUS_SUCCESS;
338 }
339 
DdiCodec_PutSurfaceLinuxHW(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)340 VAStatus DdiCodec_PutSurfaceLinuxHW(
341     VADriverContextP ctx,
342     VASurfaceID      surface,
343     void*            draw,             /* Drawable of window system */
344     int16_t          srcx,
345     int16_t          srcy,
346     uint16_t         srcw,
347     uint16_t         srch,
348     int16_t          destx,
349     int16_t          desty,
350     uint16_t         destw,
351     uint16_t         desth,
352     VARectangle     *cliprects,        /* client supplied clip list */
353     uint32_t         number_cliprects, /* number of clip rects in the clip list */
354     uint32_t         flags             /* de-interlacing flags */
355 )
356 {
357     VpBase                  *vpHal = nullptr;
358     int32_t                 ovRenderIndex = 0;
359     VPHAL_SURFACE           Surf;
360     VPHAL_SURFACE           target;
361     VPHAL_RENDER_PARAMS     renderParams;
362     VPHAL_COLORFILL_PARAMS  colorFill;
363 
364     MOS_STATUS              eStatus    = MOS_STATUS_INVALID_PARAMETER;
365     RECT                    srcRect    = { 0, 0, 0, 0 };
366     RECT                    dstRect    = { 0, 0, 0, 0 };
367     PDDI_MEDIA_CONTEXT      mediaCtx;
368     PDDI_MEDIA_SURFACE      bufferObject;
369     uint32_t                width,height,pitch;
370     uint32_t                drawable_tiling_mode;
371     uint32_t                drawable_swizzle_mode;
372     MOS_ALLOC_GFXRES_PARAMS allocParams;
373     MOS_TILE_TYPE           tileType;
374 
375     uint32_t                ctxType;
376     PDDI_VP_CONTEXT         vpCtx;
377     struct dri_drawable*    dri_drawable = nullptr;
378     union dri_buffer*       buffer = nullptr;
379 
380     GMM_RESCREATE_PARAMS    gmmParams;
381 
382     mediaCtx     = DdiMedia_GetMediaContext(ctx);
383     DDI_CHK_NULL(mediaCtx, "Null mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
384     DDI_CHK_NULL(mediaCtx->dri_output, "Null mediaDrvCtx->dri_output", VA_STATUS_ERROR_INVALID_PARAMETER);
385     DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "Null mediaDrvCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_PARAMETER);
386     DDI_CHK_NULL(mediaCtx->pGmmClientContext, "Null mediaCtx->pGmmClientContext", VA_STATUS_ERROR_INVALID_PARAMETER);
387     DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaceId", VA_STATUS_ERROR_INVALID_SURFACE);
388 
389     struct dri_vtable * const dri_vtable = &mediaCtx->dri_output->vtable;
390     DDI_CHK_NULL(dri_vtable, "Null dri_vtable", VA_STATUS_ERROR_INVALID_PARAMETER);
391 
392     dri_drawable = dri_vtable->get_drawable(ctx, (Drawable)draw);
393     DDI_CHK_NULL(dri_drawable, "Null dri_drawable", VA_STATUS_ERROR_INVALID_PARAMETER);
394     buffer = dri_vtable->get_rendering_buffer(ctx, dri_drawable);
395     DDI_CHK_NULL(buffer, "Null buffer", VA_STATUS_ERROR_INVALID_PARAMETER);
396 
397     bufferObject = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
398     DDI_CHK_NULL(bufferObject, "Null bufferObject", VA_STATUS_ERROR_INVALID_SURFACE);
399     DdiMediaUtil_MediaPrintFps();
400     pitch = bufferObject->iPitch;
401 
402     vpCtx         = nullptr;
403     if (nullptr != mediaCtx->pVpCtxHeap->pHeapBase)
404     {
405         vpCtx = (PDDI_VP_CONTEXT)DdiMedia_GetContextFromContextID(ctx, (VAContextID)(0 + DDI_MEDIA_VACONTEXTID_OFFSET_VP), &ctxType);
406         DDI_CHK_NULL(vpCtx, "Null vpCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
407         vpHal = vpCtx->pVpHal;
408         DDI_CHK_NULL(vpHal, "Null vpHal", VA_STATUS_ERROR_INVALID_PARAMETER);
409     }
410     else
411     {
412         return VA_STATUS_ERROR_INVALID_CONTEXT;
413     }
414 
415     // Zero memory
416     MOS_ZeroMemory(&Surf,    sizeof(Surf));
417     MOS_ZeroMemory(&target, sizeof(target));
418     MOS_ZeroMemory(&renderParams, sizeof(renderParams));
419     MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
420 
421     renderParams.Component = COMPONENT_LibVA;
422 
423     //Init source rectangle
424     Rect_init(&srcRect, srcx, srcy, srcw, srch);
425     Rect_init(&dstRect, destx, desty, destw, desth);
426 
427     if( destx + destw > dri_drawable->x + dri_drawable->width )
428     {
429         //return VA_STATUS_ERROR_INVALID_PARAMETER;
430         dstRect.right = dri_drawable->x + dri_drawable->width - destx;
431         if(dstRect.right <= 0)
432         {
433             return VA_STATUS_SUCCESS;
434         }
435     }
436     if(desty + desth > dri_drawable->y + dri_drawable->height)
437     {
438         dstRect.bottom = dri_drawable->y + dri_drawable->height - desty;
439         if(dstRect.bottom <= 0)
440         {
441             return VA_STATUS_SUCCESS;
442         }
443     }
444     // Source Surface Information
445     Surf.Format                 = VpGetFormatFromMediaFormat(bufferObject->format);           // Surface format
446     Surf.SurfType               = SURF_IN_PRIMARY;       // Surface type (context)
447     Surf.SampleType             = SAMPLE_PROGRESSIVE;
448     Surf.ScalingMode            = VPHAL_SCALING_AVS;
449 
450     Surf.OsResource.Format      = VpGetFormatFromMediaFormat(bufferObject->format);
451     Surf.OsResource.iWidth      = bufferObject->iWidth;
452     Surf.OsResource.iHeight     = bufferObject->iHeight;
453     Surf.OsResource.iPitch      = bufferObject->iPitch;
454     Surf.OsResource.iCount      = 0;
455     Surf.OsResource.TileType    = VpGetTileTypeFromMediaTileType(bufferObject->TileType);
456     Surf.OsResource.bMapped     = bufferObject->bMapped;
457     Surf.OsResource.bo          = bufferObject->bo;
458     Surf.OsResource.pGmmResInfo = bufferObject->pGmmResourceInfo;
459 
460     Surf.dwWidth                = bufferObject->iWidth;
461     Surf.dwHeight               = bufferObject->iHeight;
462     Surf.dwPitch                = bufferObject->iPitch;
463     Surf.TileType               = VpGetTileTypeFromMediaTileType(bufferObject->TileType);
464     Surf.ColorSpace             = DdiVp_GetColorSpaceFromMediaFormat(bufferObject->format);
465     Surf.ExtendedGamut          = false;
466     Surf.rcSrc                  = srcRect;
467     Surf.rcDst                  = dstRect;
468 
469     MOS_LINUX_BO* drawable_bo = mos_bo_create_from_name(mediaCtx->pDrmBufMgr, "rendering buffer", buffer->dri2.name);
470 
471 
472     if  (nullptr == drawable_bo)
473     {
474         return VA_STATUS_ERROR_ALLOCATION_FAILED;
475     }
476 
477     if (!mos_bo_get_tiling(drawable_bo, &drawable_tiling_mode, &drawable_swizzle_mode))
478     {
479         switch (drawable_tiling_mode)
480         {
481         case TILING_Y:
482            tileType = MOS_TILE_Y;
483            break;
484         case TILING_X:
485            tileType = MOS_TILE_X;
486            gmmParams.Flags.Info.TiledX    = true;
487            break;
488         case TILING_NONE:
489            tileType = MOS_TILE_LINEAR;
490            gmmParams.Flags.Info.Linear    = true;
491            break;
492         default:
493            drawable_tiling_mode = TILING_NONE;
494            tileType = MOS_TILE_LINEAR;
495            gmmParams.Flags.Info.Linear    = true;
496            break;
497         }
498     }
499     else
500     {
501         target.OsResource.TileType = (MOS_TILE_TYPE)TILING_NONE;
502         tileType = MOS_TILE_LINEAR;
503         gmmParams.Flags.Info.Linear    = true;
504     }
505     gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory);
506 
507     target.Format                = Format_A8R8G8B8;
508     target.SurfType              = SURF_OUT_RENDERTARGET;
509 
510     //init target retangle
511     Rect_init(&srcRect, dri_drawable->x, dri_drawable->y, dri_drawable->width, dri_drawable->height);
512     Rect_init(&dstRect, dri_drawable->x, dri_drawable->y, dri_drawable->width, dri_drawable->height);
513 
514     // Create GmmResourceInfo
515     gmmParams.Flags.Gpu.Video       = true;
516     gmmParams.BaseWidth             = dri_drawable->width;
517     gmmParams.BaseHeight            = dri_drawable->height;
518     gmmParams.ArraySize             = 1;
519     gmmParams.Type                  = RESOURCE_2D;
520     gmmParams.Format                = GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
521     //gmmParams.Format                = GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
522     target.OsResource.pGmmResInfo = mediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
523     if (nullptr == target.OsResource.pGmmResInfo)
524     {
525         mos_bo_unreference(drawable_bo);
526         return VA_STATUS_ERROR_ALLOCATION_FAILED;
527     }
528 
529     target.OsResource.iWidth     = dri_drawable->width;
530     target.OsResource.iHeight    = dri_drawable->height;
531     target.OsResource.iPitch     = buffer->dri2.pitch;
532     target.OsResource.Format     = Format_A8R8G8B8;
533     target.OsResource.iCount     = 0;
534     target.OsResource.bo         = drawable_bo;
535     target.OsResource.pData      = (uint8_t *)drawable_bo->virt;
536     target.OsResource.TileType   = tileType;
537     target.TileType              = tileType;
538     target.dwWidth               = dri_drawable->width;
539     target.dwHeight              = dri_drawable->height;
540     target.dwPitch               = target.OsResource.iPitch;
541     target.ColorSpace            = CSpace_sRGB;
542     target.ExtendedGamut         = false;
543     target.rcSrc                 = srcRect;
544     target.rcDst                 = dstRect;
545 
546     renderParams.uSrcCount                  = 1;
547     renderParams.uDstCount                  = 1;
548     renderParams.pSrc[0]                    = &Surf;
549     renderParams.pTarget[0]                 = &target;
550     renderParams.pColorFillParams           = &colorFill;
551     renderParams.pColorFillParams->Color    = 0xFF000000;
552     renderParams.pColorFillParams->bYCbCr   = false;
553     renderParams.pColorFillParams->CSpace   = CSpace_sRGB;
554 
555     DdiMediaUtil_LockMutex(&mediaCtx->PutSurfaceRenderMutex);
556     eStatus = vpHal->Render(&renderParams);
557     if (MOS_FAILED(eStatus))
558     {
559         DdiMediaUtil_UnLockMutex(&mediaCtx->PutSurfaceRenderMutex);
560         mos_bo_unreference(drawable_bo);
561         return VA_STATUS_ERROR_OPERATION_FAILED;
562     }
563 
564     DdiMediaUtil_UnLockMutex(&mediaCtx->PutSurfaceRenderMutex);
565     mos_bo_unreference(drawable_bo);
566     target.OsResource.bo         = nullptr;
567     DdiMediaUtil_LockMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
568     dri_vtable->swap_buffer(ctx, dri_drawable);
569     DdiMediaUtil_UnLockMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
570 
571     mediaCtx->pGmmClientContext->DestroyResInfoObject(target.OsResource.pGmmResInfo);
572     target.OsResource.pGmmResInfo = nullptr;
573 
574     return VA_STATUS_SUCCESS;
575 }
576 
577 #ifndef ANDROID
578 // move from media_libva_putsurface_linux.c
DdiMedia_mask2shift(unsigned long mask)579 static unsigned long DdiMedia_mask2shift(unsigned long mask)
580 {
581     unsigned long shift = 0;
582     while((mask & 0x1) == 0)
583     {
584         mask = mask >> 1;
585         shift++;
586     }
587     return shift;
588 }
DdiMedia_yuv2pixel(uint32_t * pixel,int32_t y,int32_t u,int32_t v,unsigned long rshift,unsigned long rmask,unsigned long gshift,unsigned long gmask,unsigned long bshift,unsigned long bmask)589 static void DdiMedia_yuv2pixel(uint32_t *pixel, int32_t y, int32_t u, int32_t v,
590                                unsigned long rshift, unsigned long rmask,
591                                unsigned long gshift, unsigned long gmask,
592                                unsigned long bshift, unsigned long bmask)
593 {
594     DDI_CHK_NULL(pixel, "nullptr pixel", );
595     /* Warning, magic values ahead */
596     int32_t r = y + ((351 * (v-128)) >> 8);
597     int32_t g = y - (((179 * (v-128)) + (86 * (u-128))) >> 8);
598     int32_t b = y + ((444 * (u-128)) >> 8);
599 
600     if (r > 255) r = 255;
601     if (g > 255) g = 255;
602     if (b > 255) b = 255;
603     if (r < 0)   r = 0;
604     if (g < 0)   g = 0;
605     if (b < 0)   b = 0;
606 
607     *pixel = (uint32_t)(((r << rshift) & rmask) | ((g << gshift) & gmask) |((b << bshift) & bmask));
608 }
609 
610 #define YUV_444P_TO_ARGB() \
611     srcY = umdContextY + pitch * srcy;\
612     srcU = srcY + pitch * ((mediaSurface->iHeight));\
613     srcV = srcU + pitch * ((mediaSurface->iHeight));\
614      \
615     for(y = srcy; y < (srcy + height); y += 1) \
616     {\
617         for(x = srcx; x < (srcx + width); x += 1) \
618         {\
619             y1 = *(srcY + x); \
620             u1 = *(srcU + x);\
621             v1 = *(srcV + x);\
622             \
623             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
624             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
625            \
626         }\
627         srcY += pitch;\
628         srcU += pitch;\
629         srcV += pitch;\
630     }
631 
632 #define YUV_422H_TO_ARGB()\
633     srcY = umdContextY + pitch * srcy;\
634     srcU = srcY + pitch * mediaSurface->iHeight;\
635     srcV = srcU + pitch * mediaSurface->iHeight;\
636     \
637     for(y = srcy; y < (srcy + height); y += 1)\
638     {\
639         for(x = srcx; x < (srcx + width); x += 2)\
640         {\
641             y1 = *(srcY + x);\
642             y2 = *(srcY + x + 1);\
643             u1 = *(srcU + x / 2);\
644             v1 = *(srcV + x / 2);\
645             \
646             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
647             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
648             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
649             DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
650         }\
651         srcY += pitch;\
652         srcU += pitch;\
653         srcV += pitch;\
654     }
655 
656 #define YUV_422V_TO_ARGB() \
657     srcY = umdContextY + pitch * srcy;\
658     srcU = srcY + pitch * mediaSurface->iHeight;\
659     srcV = srcU + pitch * mediaSurface->iHeight / 2;\
660     \
661     for(y = srcy; y < (srcy + width); y += 1)\
662     {\
663         for(x = srcx; x < (srcx + height); x += 2)\
664         {\
665             y1 = *(srcY + x * pitch);\
666             y2 = *(srcY + (x + 1) * pitch);\
667             u1 = *(srcU + (x / 2) * pitch);\
668             v1 = *(srcV + (x / 2) * pitch);\
669             \
670             pixel = (uint32_t *)(ximg->data + (x * ximg->bytes_per_line) + (y * (ximg->bits_per_pixel >> 3)));\
671             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
672             pixel = (uint32_t *)(ximg->data + (x* ximg->bytes_per_line) + ((y + 1) * (ximg->bits_per_pixel >> 3)));\
673             DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
674             \
675         }\
676         \
677         srcY += 1;\
678         srcU += 1;\
679         srcV += 1;\
680     }
681 
682 #define YUV_IMC3_TO_ARGB() \
683     srcY = umdContextY + pitch * srcy;\
684     srcU = srcY + pitch * mediaSurface->iHeight;\
685     srcV = srcU + pitch * mediaSurface->iHeight / 2;\
686     \
687     for(y = srcy; y < (srcy + height); y += 2) \
688     {\
689         for(x = srcx; x < (srcx + width); x += 2) \
690         {\
691             y1 = *(srcY + x);\
692             y2 = *(srcY + x + 1);\
693             y3 = *(srcY + x + pitch);\
694             y4 = *(srcY + x + pitch + 1);\
695             \
696             u1 = *(srcU + x / 2);\
697             v1 = *(srcV + x / 2);\
698             \
699             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
700             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
701             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
702             DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
703             pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
704             DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
705             pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
706             DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask); \
707         }\
708         srcY += pitch * 2;\
709         srcU += pitch;\
710         srcV += pitch;\
711     }
712 
713 #define YUV_411P_TO_ARGB() \
714     srcY = umdContextY + pitch * srcy;\
715     srcU = srcY + pitch * mediaSurface->iHeight;\
716     srcV = srcU + pitch * mediaSurface->iHeight;\
717     \
718     for(y = srcy; y < (srcy + height); y += 1)\
719     {\
720         for(x = srcx; x < (srcx + width); x += 4)\
721         {\
722             y1 = *(srcY + x);\
723             y2 = *(srcY + x + 1);\
724             y3 = *(srcY + x + 2);\
725             y4 = *(srcY + x + 3);\
726             \
727             u1 = *(srcU + x / 4);\
728             v1 = *(srcV + x / 4);\
729             \
730             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
731             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
732             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
733             DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
734             pixel = (uint32_t *)(ximg->data + ((y ) * ximg->bytes_per_line) + ((x+2) * (ximg->bits_per_pixel >> 3)));\
735             DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
736             pixel = (uint32_t *)(ximg->data + ((y) * ximg->bytes_per_line) + ((x + 3) * (ximg->bits_per_pixel >> 3)));\
737             DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
738         }\
739         srcY  += pitch;\
740         srcU  += pitch;\
741         srcV  += pitch;\
742     }
743 
744 #define YUV_400P_TO_ARGB()\
745     srcY = umdContextY + pitch * srcy;\
746     srcU = srcY;\
747     srcV = srcY;\
748     \
749     for(y = srcy; y < (srcy + height); y += 2)\
750     {\
751         for(x = srcx; x < (srcx + width); x += 2)\
752         {\
753             y1 = *(srcY + x);\
754             y2 = *(srcY + x + 1);\
755             y3 = *(srcY + x + pitch);\
756             y4 = *(srcY + x + pitch + 1);\
757             \
758             u1 = 128;\
759             v1 = 128;\
760             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
761             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
762             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
763             DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
764             pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
765             DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
766             pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
767             DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
768         }\
769         srcY += pitch * 2;\
770         srcU += pitch;\
771         srcV += pitch;\
772     }
773 
774 #define YUV_NV12_TO_ARGB()\
775     srcY = umdContextY + pitch * srcy;\
776     srcU = srcY + pitch * mediaSurface->iHeight;\
777     srcV = srcU + 1;\
778     \
779     for(y = srcy; y < (srcy + height); y += 2)\
780     {\
781         for(x = srcx; x < (srcx + width); x += 2)\
782         {\
783             y1 = *(srcY + x);\
784             y2 = *(srcY + x + 1);\
785             y3 = *(srcY + x + pitch);\
786             y4 = *(srcY + x + pitch + 1);\
787             \
788             u1 = *(srcU + x);\
789             v1 = *(srcU + x +1);\
790             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
791             DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
792             pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
793             DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
794             pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
795             DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
796             pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
797             DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
798         }\
799         srcY += pitch * 2;\
800         srcU += pitch;\
801     }
802 
DdiMedia_PutSurfaceLinuxSW(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)803 VAStatus DdiMedia_PutSurfaceLinuxSW(
804     VADriverContextP ctx,
805     VASurfaceID      surface,
806     void*            draw,             /* Drawable of window system */
807     int16_t          srcx,
808     int16_t          srcy,
809     uint16_t         srcw,
810     uint16_t         srch,
811     int16_t          destx,
812     int16_t          desty,
813     uint16_t         destw,
814     uint16_t         desth,
815     VARectangle     *cliprects,        /* client supplied clip list */
816     uint32_t         number_cliprects, /* number of clip rects in the clip list */
817     uint32_t         flags             /* de-interlacing flags */
818 )
819 {
820     PDDI_MEDIA_CONTEXT mediaCtx         = DdiMedia_GetMediaContext(ctx);
821     DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
822 
823     DDI_CHK_NULL(mediaCtx->X11FuncTable, "nullptr X11FuncTable", VA_STATUS_ERROR_INVALID_CONTEXT);
824     DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXCreateGC, "nullptr pfnXCreateGC", VA_STATUS_ERROR_INVALID_CONTEXT);
825     DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXFreeGC, "nullptr pfnXFreeGC", VA_STATUS_ERROR_INVALID_CONTEXT);
826     DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXCreateImage, "nullptr pfnXCreateImage", VA_STATUS_ERROR_INVALID_CONTEXT);
827     DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXDestroyImage, "nullptr pfnXDestroyImage", VA_STATUS_ERROR_INVALID_CONTEXT);
828     DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXPutImage, "nullptr pfnXPutImage", VA_STATUS_ERROR_INVALID_CONTEXT);
829 
830     TypeXCreateGC     pfn_XCreateGC     = (TypeXCreateGC)(mediaCtx->X11FuncTable->pfnXCreateGC);
831     TypeXFreeGC       pfn_XFreeGC       = (TypeXFreeGC)(mediaCtx->X11FuncTable->pfnXFreeGC);
832     TypeXCreateImage  pfn_XCreateImage  = (TypeXCreateImage)(mediaCtx->X11FuncTable->pfnXCreateImage);
833     TypeXDestroyImage pfn_XDestroyImage = (TypeXDestroyImage)(mediaCtx->X11FuncTable->pfnXDestroyImage);
834     TypeXPutImage     pfn_XPutImage     = (TypeXPutImage)(mediaCtx->X11FuncTable->pfnXPutImage);
835 
836     DDI_MEDIA_SURFACE *mediaSurface     = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
837     DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE);
838 
839     uint16_t width  = 0;
840     if (srcw <= destw)
841         width = srcw;
842     else
843         width = destw;
844 
845     uint16_t height = 0;
846     if (srch <= desth)
847         height = srch;
848     else
849         height = desth;
850 
851     int32_t  pitch   = mediaSurface->iPitch;
852     uint32_t adjustU = 1;
853     uint32_t adjustD = 1;
854     switch(mediaSurface->format)
855     {
856         case Media_Format_422H:
857         case Media_Format_444P:
858         case Media_Format_411P:
859             adjustU = 3;
860             adjustD = 1;
861             break;
862         case Media_Format_400P:
863             adjustU = 1;
864             adjustD = 1;
865             break;
866         case Media_Format_422V:
867         case Media_Format_IMC3:
868             adjustU = 2;
869             adjustD = 1;
870             break;
871         case Media_Format_NV12:
872             adjustU = 3;
873             adjustD = 2;
874             break;
875         default:
876             DDI_ASSERTMESSAGE("Color Format is not supported: %d",mediaSurface->format);
877             return VA_STATUS_ERROR_INVALID_VALUE;
878     }
879 
880     uint32_t surfaceSize          = pitch * mediaSurface->iHeight * adjustU / adjustD;
881     uint8_t  *dispTempBuffer      = (uint8_t *)malloc(surfaceSize);
882     if (dispTempBuffer == nullptr)
883     {
884         DdiMediaUtil_UnlockSurface(mediaSurface);
885         return VA_STATUS_ERROR_ALLOCATION_FAILED;
886     }
887 
888     uint8_t *umdContextY = dispTempBuffer;
889     uint8_t *ptr         = (uint8_t*)DdiMediaUtil_LockSurface(mediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY));
890     MOS_STATUS eStatus   = MOS_SecureMemcpy(umdContextY, surfaceSize, ptr, surfaceSize);
891 
892     if (eStatus != MOS_STATUS_SUCCESS)
893     {
894         MOS_FreeMemory(dispTempBuffer);
895         DDI_ASSERTMESSAGE("DDI:Failed to copy surface buffer data!");
896         return VA_STATUS_ERROR_OPERATION_FAILED;
897     }
898 
899     Visual *visual       = DefaultVisual(ctx->native_dpy, ctx->x11_screen);
900     GC     gc            = (*pfn_XCreateGC)((Display*)ctx->native_dpy, (Drawable)draw, 0, nullptr);
901 
902     if (TrueColor != visual->c_class)
903     {
904         (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
905         MOS_FreeMemory(dispTempBuffer);
906         return VA_STATUS_ERROR_UNKNOWN;
907     }
908 
909     unsigned long rmask  = visual->red_mask;
910     unsigned long gmask  = visual->green_mask;
911     unsigned long bmask  = visual->blue_mask;
912 
913     unsigned long rshift = DdiMedia_mask2shift(rmask);
914     unsigned long gshift = DdiMedia_mask2shift(gmask);
915     unsigned long bshift = DdiMedia_mask2shift(bmask);
916 
917     int32_t depth        = DefaultDepth(ctx->native_dpy, ctx->x11_screen);
918     XImage   *ximg  = (*pfn_XCreateImage)((Display*)ctx->native_dpy, visual, depth, ZPixmap, 0, nullptr,width, height, 32, 0 );
919     if (ximg == nullptr)
920     {
921         MOS_FreeMemory(dispTempBuffer);
922         return VA_STATUS_ERROR_ALLOCATION_FAILED;
923     }
924 
925     if (ximg->bits_per_pixel != 32)
926     {
927          (*pfn_XDestroyImage)(ximg);
928          (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
929          MOS_FreeMemory(dispTempBuffer);
930          return VA_STATUS_ERROR_UNKNOWN;
931     }
932 
933     ximg->data = (char *) malloc(ximg->bytes_per_line * MOS_ALIGN_CEIL(height, 2)); // If height is odd, need to add it by one for we process two lines per iteration
934     if (nullptr == ximg->data)
935     {
936         (*pfn_XDestroyImage)(ximg);
937         (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
938         MOS_FreeMemory(dispTempBuffer);
939         return VA_STATUS_ERROR_ALLOCATION_FAILED;
940     }
941 
942     int32_t  x = 0;
943     int32_t  y = 0;
944     uint8_t  *srcY = nullptr;
945     uint8_t  *srcU = nullptr;
946     uint8_t  *srcV = nullptr;
947     uint32_t *pixel = nullptr;
948     int32_t  y1 = 0, y2 = 0, y3 = 0, y4 = 0, u1 = 0, v1 = 0;
949      switch(mediaSurface->format)
950     {
951         case Media_Format_444P:
952             YUV_444P_TO_ARGB();
953             break;
954         case Media_Format_422H:
955             YUV_422H_TO_ARGB();
956             break;
957         case Media_Format_422V:
958             YUV_422V_TO_ARGB();
959             break;
960         case Media_Format_IMC3:
961             YUV_IMC3_TO_ARGB();
962             break;
963         case Media_Format_411P:
964             YUV_411P_TO_ARGB();
965             break;
966         case Media_Format_400P:
967             YUV_400P_TO_ARGB();
968             break;
969         case Media_Format_NV12:
970             YUV_NV12_TO_ARGB();
971             break;
972         default:
973             DDI_ASSERTMESSAGE("Color Format is not supported: %d", mediaSurface->format);
974     }
975 
976     DdiMediaUtil_UnlockSurface(mediaSurface);
977 
978     (*pfn_XPutImage)((Display*)ctx->native_dpy,(Drawable)draw, gc, ximg, 0, 0, destx, desty, destw, desth);
979 
980     if (ximg != nullptr)
981     {
982         (*pfn_XDestroyImage)(ximg);
983     }
984     (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
985     MOS_FreeMemory(dispTempBuffer);
986     return VA_STATUS_SUCCESS;
987 }
988 
DdiMedia_PutSurfaceDummy(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)989 VAStatus DdiMedia_PutSurfaceDummy(
990     VADriverContextP ctx,
991     VASurfaceID      surface,
992     void            *draw,             /* Drawable of window system */
993     int16_t          srcx,
994     int16_t          srcy,
995     uint16_t         srcw,
996     uint16_t         srch,
997     int16_t          destx,
998     int16_t          desty,
999     uint16_t         destw,
1000     uint16_t         desth,
1001     VARectangle     *cliprects,        /* client supplied clip list */
1002     uint32_t         number_cliprects, /* number of clip rects in the clip list */
1003     uint32_t         flags             /* de-interlacing flags */
1004 )
1005 {
1006     return VA_STATUS_ERROR_UNIMPLEMENTED;
1007 }
1008 
1009 #endif
1010