• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3  * Copyright (c) Imagination Technologies Limited, UK
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Zhaohan Ren  <zhaohan.ren@intel.com>
27  *    Shengquan Yuan  <shengquan.yuan@intel.com>
28  *
29  */
30 
31 #include <stdio.h>
32 #include <math.h>
33 
34 #include <psb_drm.h>
35 #include <va/va_backend.h>
36 #include <va/va_dricommon.h>
37 
38 #include <wsbm/wsbm_manager.h>
39 #include <X11/Xlib.h>
40 #include <X11/X.h>
41 
42 #include "psb_drv_video.h"
43 #include "psb_x11.h"
44 #include "psb_output.h"
45 #include "psb_xrandr.h"
46 #include "psb_surface_ext.h"
47 
48 #include "psb_texture.h"
49 #include "psb_drv_debug.h"
50 
51 #define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
52 #define INIT_OUTPUT_PRIV    psb_x11_output_p output = (psb_x11_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv)
53 
54 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
55 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
56 #define IMAGE(id)  ((object_image_p) object_heap_lookup( &driver_data->image_heap, id ))
57 #define SUBPIC(id)  ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id ))
58 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
59 
psb_extend_dri_init(VADriverContextP ctx,unsigned int destx,unsigned desty,unsigned destw,unsigned desth)60 static VAStatus psb_extend_dri_init(VADriverContextP ctx, unsigned int destx, unsigned desty, unsigned destw, unsigned desth)
61 {
62     INIT_DRIVER_DATA;
63     INIT_OUTPUT_PRIV;
64 
65     int i, ret;
66     union dri_buffer *extend_dri_buffer;
67     PPVR2DMEMINFO dri2_bb_export_meminfo;
68 
69     struct psb_texture_s *texture_priv = &driver_data->ctexture_priv;
70 
71     output->extend_drawable = (Window)psb_xrandr_create_full_screen_window(destx, desty, destw, desth);
72     if (!output->extend_drawable) {
73         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to create drawable for extend display # %d\n", __func__, output->extend_drawable);
74     }
75 
76     if (texture_priv->extend_dri_drawable) {
77         free_drawable(ctx, texture_priv->extend_dri_drawable);
78         texture_priv->extend_dri_drawable = NULL;
79     }
80 
81     texture_priv->extend_dri_drawable = dri_get_drawable(ctx, output->extend_drawable);
82     if (!texture_priv->extend_dri_drawable) {
83         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): Failed to get extend_dri_drawable\n", __func__);
84         return VA_STATUS_ERROR_UNKNOWN;
85     }
86 
87     extend_dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->extend_dri_drawable);
88     if (!extend_dri_buffer) {
89         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): Failed to get extend_dri_buffer\n", __func__);
90         return VA_STATUS_ERROR_UNKNOWN;
91     }
92 
93     ret = PVR2DMemMap(driver_data->hPVR2DContext, 0, (PVR2D_HANDLE)extend_dri_buffer->dri2.name, &dri2_bb_export_meminfo);
94     if (ret != PVR2D_OK) {
95         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
96         return VA_STATUS_ERROR_UNKNOWN;
97     }
98 
99     memcpy(&texture_priv->extend_dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport));
100 
101     for (i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) {
102         ret = PVR2DMemMap(driver_data->hPVR2DContext, 0, texture_priv->extend_dri2_bb_export.hBuffers[i], &texture_priv->extend_blt_meminfo[i]);
103         if (ret != PVR2D_OK) {
104             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
105             return VA_STATUS_ERROR_UNKNOWN;
106         }
107     }
108 
109     texture_priv->extend_dri_init_flag = 1;
110 
111     return VA_STATUS_SUCCESS;
112 }
113 
114 /* reset buffer to prevent non-video area distorting when rendering into part of a drawable */
psb_dri_reset_mem(VADriverContextP ctx)115 static void psb_dri_reset_mem(VADriverContextP ctx)
116 {
117     INIT_DRIVER_DATA;
118     unsigned int i, size;
119     struct dri_drawable *tmp_drawable;
120     struct psb_texture_s *texture_priv = &driver_data->ctexture_priv;
121 
122     tmp_drawable = (struct dri_drawable *)texture_priv->dri_drawable;
123     size = tmp_drawable->width * tmp_drawable->height * 4;
124 
125     if (!tmp_drawable->is_window) {
126         memset(texture_priv->blt_meminfo_pixmap->pBase, 0x0, size);
127         return;
128     } else {
129         if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS)
130             for (i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++)
131                 memset(texture_priv->blt_meminfo[i]->pBase, 0x0, size);
132         if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN)
133             for (i = 0; i < DRI2_FLIP_BUFFERS_NUM; i++)
134                 memset(texture_priv->blt_meminfo[i]->pBase, 0x0, size);
135     }
136 
137     return;
138 }
139 
psb_dri_init(VADriverContextP ctx,Drawable draw)140 static VAStatus psb_dri_init(VADriverContextP ctx, Drawable draw)
141 {
142     INIT_DRIVER_DATA;
143     union dri_buffer *dri_buffer;
144     PPVR2DMEMINFO dri2_bb_export_meminfo;
145     struct psb_texture_s *texture_priv = &driver_data->ctexture_priv;
146     struct dri_drawable *tmp_drawable;
147     int i, ret;
148 
149     /* free the previous drawable buffer */
150     if (texture_priv->dri_drawable) {
151         free_drawable(ctx, texture_priv->dri_drawable);
152         texture_priv->dri_drawable = NULL;
153     }
154 
155     texture_priv->dri_drawable = dri_get_drawable(ctx, draw);
156     if (!texture_priv->dri_drawable) {
157         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): Failed to get dri_drawable\n", __func__);
158         return VA_STATUS_ERROR_UNKNOWN;
159     }
160     tmp_drawable = (struct dri_drawable *)texture_priv->dri_drawable;
161 
162     dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->dri_drawable);
163     if (!dri_buffer) {
164         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): Failed to get dri_buffer\n", __func__);
165         return VA_STATUS_ERROR_UNKNOWN;
166     }
167 
168     /* pixmap */
169     if (!tmp_drawable->is_window) {
170         if (texture_priv->blt_meminfo_pixmap)
171             PVR2DMemFree(driver_data->hPVR2DContext, texture_priv->blt_meminfo_pixmap);
172 
173         ret = PVR2DMemMap(driver_data->hPVR2DContext, 0, (PVR2D_HANDLE)(dri_buffer->dri2.name & 0x00FFFFFF), &texture_priv->blt_meminfo_pixmap);
174         if (ret != PVR2D_OK) {
175             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
176             return VA_STATUS_ERROR_UNKNOWN;
177         }
178         /* window */
179     } else {
180         ret = PVR2DMemMap(driver_data->hPVR2DContext, 0, (PVR2D_HANDLE)(dri_buffer->dri2.name & 0x00FFFFFF), &dri2_bb_export_meminfo);
181         if (ret != PVR2D_OK) {
182             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
183             return VA_STATUS_ERROR_UNKNOWN;
184         }
185 
186         memcpy(&texture_priv->dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport));
187 
188         if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) {
189             drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_dri_init: Now map buffer, DRI2 back buffer export type: DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS\n");
190 
191             for (i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) {
192                 ret = PVR2DMemMap(driver_data->hPVR2DContext, 0, texture_priv->dri2_bb_export.hBuffers[i], &texture_priv->blt_meminfo[i]);
193                 if (ret != PVR2D_OK) {
194                     drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
195                     return VA_STATUS_ERROR_UNKNOWN;
196                 }
197             }
198         } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) {
199             drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_dri_init: Now map buffer, DRI2 back buffer export type: DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN\n");
200 
201             for (i = 0; i < DRI2_FLIP_BUFFERS_NUM; i++) {
202                 ret = PVR2DMemMap(driver_data->hPVR2DContext, 0, texture_priv->dri2_bb_export.hBuffers[i], &texture_priv->flip_meminfo[i]);
203                 if (ret != PVR2D_OK) {
204                     drv_debug_msg(VIDEO_DEBUG_ERROR, "%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret);
205                     return VA_STATUS_ERROR_UNKNOWN;
206                 }
207             }
208         }
209 
210         PVR2DMemFree(driver_data->hPVR2DContext, dri2_bb_export_meminfo);
211     }
212 
213     texture_priv->dri_init_flag = 1;
214 
215     psb_dri_reset_mem(ctx);
216     return VA_STATUS_SUCCESS;
217 }
218 
psb_putsurface_ctexture(VADriverContextP ctx,VASurfaceID surface,Drawable draw,short srcx,short srcy,unsigned short srcw,unsigned short srch,short destx,short desty,unsigned short destw,unsigned short desth,unsigned int flags)219 VAStatus psb_putsurface_ctexture(
220     VADriverContextP ctx,
221     VASurfaceID surface,
222     Drawable draw,
223     short srcx,
224     short srcy,
225     unsigned short srcw,
226     unsigned short srch,
227     short destx,
228     short desty,
229     unsigned short destw,
230     unsigned short desth,
231     unsigned int flags /* de-interlacing flags */
232 )
233 {
234     INIT_DRIVER_DATA;
235     INIT_OUTPUT_PRIV;
236     int ret;
237     int local_crtc_x, local_crtc_y, extend_crtc_x, extend_crtc_y;
238     int display_width = 0, display_height = 0, extend_display_width = 0, extend_display_height = 0;
239     int surface_width, surface_height;
240     psb_xrandr_location extend_location = NORMAL;
241     psb_extvideo_subtitle subtitle = NOSUBTITLE;
242     object_surface_p obj_surface = SURFACE(surface);
243     psb_surface_p psb_surface;
244     Rotation local_rotation, extend_rotation;
245     psb_output_device local_device, extend_device;
246     unsigned short tmp;
247     struct psb_texture_s *texture_priv = &driver_data->ctexture_priv;
248     struct dri_drawable *tmp_drawable;
249 
250 
251     obj_surface = SURFACE(surface);
252     if (NULL == obj_surface) {
253         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Invalid surface ID 0x%08x.\n", __func__, surface);
254         return VA_STATUS_ERROR_INVALID_SURFACE;
255     }
256 
257     if (driver_data->va_rotate == VA_ROTATION_NONE) {
258         psb_surface = obj_surface->psb_surface;
259         surface_width = obj_surface->width;
260         surface_height = obj_surface->height;
261     } else {
262         psb_surface = obj_surface->out_loop_surface;
263         if (driver_data->va_rotate != VA_ROTATION_180) {
264             tmp = srcw;
265             srcw = srch;
266             srch = tmp;
267         }
268         surface_width = obj_surface->width_r;
269         surface_height = obj_surface->height_r;
270     }
271 
272     if (!psb_surface)
273         psb_surface = obj_surface->psb_surface;
274 
275     if (output->output_drawable != draw) {
276         output->output_drawable = draw;
277         if (texture_priv->dri_init_flag)
278             texture_priv->drawable_update_flag = 1;
279     }
280 
281     if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) {
282         ret = psb_xrandr_thread_create(ctx);
283         if (ret != 0) {
284             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to create psb xrandr thread error # %d\n", __func__, ret);
285             return VA_STATUS_ERROR_UNKNOWN;
286         }
287     }
288 
289     if (!texture_priv->dri_init_flag) {
290         texture_priv->destw_save = destw;
291         texture_priv->desth_save = desth;
292     } else {
293         if (texture_priv->destw_save != destw || texture_priv->desth_save != desth) {
294             texture_priv->destw_save = destw;
295             texture_priv->desth_save = desth;
296             texture_priv->drawable_update_flag = 1;
297         }
298     }
299 
300     ret = psb_xrandr_local_crtc_coordinate(&local_device, &local_crtc_x, &local_crtc_y, &display_width, &display_height, &local_rotation);
301     if (ret != VA_STATUS_SUCCESS) {
302         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get local crtc coordinates error # %d\n", __func__, ret);
303         return VA_STATUS_ERROR_UNKNOWN;
304     }
305 
306     if (!psb_xrandr_single_mode() && IS_MFLD(driver_data)) {
307         ret = psb_xrandr_extend_crtc_coordinate(&extend_device, &extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location, &extend_rotation);
308         if (ret != VA_STATUS_SUCCESS) {
309             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret);
310             return VA_STATUS_ERROR_UNKNOWN;
311         }
312     }
313 
314     //Reinit DRI if screen rotates
315     if (texture_priv->local_rotation_save != local_rotation) {
316         texture_priv->local_rotation_save = local_rotation;
317         texture_priv->dri_init_flag = 0;
318     }
319     if (texture_priv->extend_rotation_save != extend_rotation) {
320         texture_priv->extend_rotation_save = extend_rotation;
321         texture_priv->extend_dri_init_flag = 0;
322     }
323 
324     if (!psb_xrandr_extvideo_mode()) {
325         if (!texture_priv->dri_init_flag || texture_priv->drawable_update_flag) {
326             if (texture_priv->drawable_update_flag) {
327                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Drawable update, reinit DRI\n");
328                 texture_priv->drawable_update_flag = 0;
329             }
330 
331             ret = psb_dri_init(ctx, output->output_drawable);
332             if (ret != VA_STATUS_SUCCESS)
333                 return VA_STATUS_ERROR_UNKNOWN;
334         }
335     }
336 
337     /* Extend video */
338     if (psb_xrandr_clone_mode() && local_rotation == extend_rotation) {
339         if (output->extend_drawable) {
340             XDestroyWindow(ctx->native_dpy, output->extend_drawable);
341             output->extend_drawable = 0;
342             texture_priv->extend_dri_init_flag = 0;
343         }
344 
345         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: Clone Mode\n");
346     } else if (psb_xrandr_extend_mode()) {
347         if (output->extend_drawable) {
348             XDestroyWindow(ctx->native_dpy, output->extend_drawable);
349             output->extend_drawable = 0;
350             texture_priv->extend_dri_init_flag = 0;
351         }
352         switch (extend_location) {
353         case LEFT_OF:
354             display_height = display_height > extend_display_height ? display_height : extend_display_height;
355             if (destw > display_width + extend_display_width)
356                 destw = display_width + extend_display_width;
357             if (desth > display_height)
358                 desth = display_height;
359             break;
360         case RIGHT_OF:
361             display_height = display_height > extend_display_height ? display_height : extend_display_height;
362             if (destw > display_width + extend_display_width)
363                 destw = display_width + extend_display_width;
364             if (desth > display_height)
365                 desth = display_height;
366             break;
367         case BELOW:
368             display_width = display_width > extend_display_width ? display_width : extend_display_width;
369             if (destw > display_width)
370                 destw = display_width;
371             if (desth > display_height + extend_display_height)
372                 desth = display_height + extend_display_height;
373             break;
374         case ABOVE:
375             display_width = display_width > extend_display_width ? display_width : extend_display_width;
376             if (destw > display_width)
377                 destw = display_width;
378             if (desth > display_height + extend_display_height)
379                 desth = display_height + extend_display_height;
380             break;
381         case NORMAL:
382         default:
383             break;
384         }
385 
386         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: Extend Mode, Location: %08x\n", extend_location);
387     } else if (psb_xrandr_extvideo_mode()) {
388 
389         unsigned int xres, yres, xoffset, yoffset, overscanmode, pannelfitting;
390         psb_extvideo_center center;
391 
392         psb_xrandr_extvideo_prop(&xres, &yres, &xoffset, &yoffset, &center, &subtitle, &overscanmode, &pannelfitting);
393 
394         xres = extend_display_width - xoffset;
395         yres = extend_display_height - yoffset;
396         //Init DRI for extend display
397         if (!texture_priv->extend_dri_init_flag) {
398             ret = psb_extend_dri_init(ctx, xoffset, yoffset, xres, yres);
399             if (ret != VA_STATUS_SUCCESS)
400                 return VA_STATUS_ERROR_UNKNOWN;
401         }
402 
403         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: ExtendVideo Mode, Location: %08x\n", extend_location);
404         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: ExtVideo coordinate srcx= %d, srcy=%d, \
405 				  srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
406                                  srcx, srcy, srcw, srch, xoffset, yoffset, xres, yres, texture_priv->extend_current_blt_buffer);
407 
408         if (subtitle == BOTH || subtitle == ONLY_HDMI)
409             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, 0, 0,
410                                        xres, yres, 1,
411                                        surface_width, surface_height,
412                                        psb_surface->stride, psb_surface->buf.drm_buf,
413                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
414         else
415             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, 0, 0,
416                                        xres, yres, 0,
417                                        surface_width, surface_height,
418                                        psb_surface->stride, psb_surface->buf.drm_buf,
419                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
420 
421         dri_swap_buffer(ctx, texture_priv->extend_dri_drawable);
422         texture_priv->extend_current_blt_buffer = (texture_priv->extend_current_blt_buffer + 1) & 0x01;
423 
424         /* int this mode, destination retangle may be larger than MIPI resolution, if so setting it to MIPI resolution */
425         if (destw > display_width)
426             destw = display_width;
427         if (desth > display_height)
428             desth = display_height;
429 
430         /* adjust local window on MIPI, make sure it is not covered by HDMI image */
431         if (!texture_priv->adjust_window_flag) {
432             switch (extend_location) {
433             case ABOVE:
434                 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, 0, extend_display_height, destw, desth);
435                 break;
436             case LEFT_OF:
437                 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, extend_display_width, 0, destw, desth);
438                 break;
439             case BELOW:
440             case RIGHT_OF:
441             case NORMAL:
442             default:
443                 break;
444             }
445             XFlush(ctx->native_dpy);
446             texture_priv->adjust_window_flag = 1;
447         }
448 
449         if (!texture_priv->dri_init_flag || texture_priv->drawable_update_flag) {
450             if (texture_priv->drawable_update_flag) {
451                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Drawable update, reinit DRI\n");
452                 texture_priv->drawable_update_flag = 0;
453             }
454 
455             ret = psb_dri_init(ctx, output->output_drawable);
456             if (ret != VA_STATUS_SUCCESS)
457                 return VA_STATUS_ERROR_UNKNOWN;
458 
459         }
460     }
461 
462     /* Main Video for pixmap*/
463     tmp_drawable = (struct dri_drawable *)texture_priv->dri_drawable;
464     if (!tmp_drawable->is_window) {
465         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: Main video Pixmap, coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
466                                  srcx, srcy, srcw, srch, destx, desty, destw, desth, texture_priv->current_blt_buffer);
467         if (subtitle == BOTH || (subtitle == NOSUBTITLE && obj_surface->subpic_count))
468             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->blt_meminfo_pixmap, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1,
469                                        surface_width, surface_height,
470                                        psb_surface->stride, psb_surface->buf.drm_buf,
471                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
472         else
473             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->blt_meminfo_pixmap, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 0,
474                                        surface_width, surface_height,
475                                        psb_surface->stride, psb_surface->buf.drm_buf,
476                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
477 
478         return VA_STATUS_SUCCESS;
479     }
480 
481     /* Main Video for window*/
482     if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) {
483         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: Main video, swap buffer, coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
484                                  srcx, srcy, srcw, srch, destx, desty, destw, desth, texture_priv->current_blt_buffer);
485 
486         if (subtitle == BOTH || (subtitle == NOSUBTITLE && obj_surface->subpic_count))
487             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1,
488                                        surface_width, surface_height,
489                                        psb_surface->stride, psb_surface->buf.drm_buf,
490                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
491         else
492             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 0,
493                                        surface_width, surface_height,
494                                        psb_surface->stride, psb_surface->buf.drm_buf,
495                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
496 
497         dri_swap_buffer(ctx, texture_priv->dri_drawable);
498         texture_priv->current_blt_buffer = (texture_priv->current_blt_buffer + 1) & 0x01;
499 
500     } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) {
501         drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_putsurface_ctexture: Main video, flip chain, coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n",
502                                  srcx, srcy, srcw, srch, destx, desty, display_width, display_height, texture_priv->current_blt_buffer);
503 
504         if (subtitle == BOTH || (subtitle == NOSUBTITLE && obj_surface->subpic_count))
505             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty,
506                                        display_width, display_height, 1, surface_width, surface_height,
507                                        psb_surface->stride, psb_surface->buf.drm_buf,
508                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
509         else
510             psb_putsurface_textureblit(ctx, (unsigned char *)texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty,
511                                        display_width, display_height, 0, surface_width, surface_height,
512                                        psb_surface->stride, psb_surface->buf.drm_buf,
513                                        psb_surface->buf.pl_flags, 0 /* no wrap for dst */);
514 
515         dri_swap_buffer(ctx, texture_priv->dri_drawable);
516         texture_priv->current_blt_buffer++;
517         if (texture_priv->current_blt_buffer == DRI2_FLIP_BUFFERS_NUM)
518             texture_priv->current_blt_buffer = 0;
519     }
520 
521     return VA_STATUS_SUCCESS;
522 }
523