psb_ctexture.c revision 2f768e2db3e4074a6e9a3d5f0f6e321233d96e4c
1/* 2 * INTEL CONFIDENTIAL 3 * Copyright 2007 Intel Corporation. All Rights Reserved. 4 * Copyright 2005-2007 Imagination Technologies Limited. All Rights Reserved. 5 * 6 * The source code contained or described herein and all documents related to 7 * the source code ("Material") are owned by Intel Corporation or its suppliers 8 * or licensors. Title to the Material remains with Intel Corporation or its 9 * suppliers and licensors. The Material may contain trade secrets and 10 * proprietary and confidential information of Intel Corporation and its 11 * suppliers and licensors, and is protected by worldwide copyright and trade 12 * secret laws and treaty provisions. No part of the Material may be used, 13 * copied, reproduced, modified, published, uploaded, posted, transmitted, 14 * distributed, or disclosed in any way without Intel's prior express written 15 * permission. 16 * 17 * No license under any patent, copyright, trade secret or other intellectual 18 * property right is granted to or conferred upon you by disclosure or delivery 19 * of the Materials, either expressly, by implication, inducement, estoppel or 20 * otherwise. Any license under such intellectual property rights must be 21 * express and approved by Intel in writing. 22 */ 23 24#include <stdio.h> 25#include <math.h> 26 27#include <psb_drm.h> 28#include <va/va_backend.h> 29#include <va/va_dricommon.h> 30 31#include <wsbm/wsbm_manager.h> 32#include <X11/Xlib.h> 33#include <X11/X.h> 34 35#include "psb_drv_video.h" 36#include "psb_x11.h" 37#include "psb_output.h" 38#include "psb_xrandr.h" 39#include "psb_surface_ext.h" 40 41#include "psb_texture.h" 42 43#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 44#define INIT_OUTPUT_PRIV psb_x11_output_p output = (psb_x11_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv) 45 46#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 47#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 48#define IMAGE(id) ((object_image_p) object_heap_lookup( &driver_data->image_heap, id )) 49#define SUBPIC(id) ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id )) 50#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 51 52static VAStatus psb_dri_init(VADriverContextP ctx, VASurfaceID surface, Drawable draw) 53{ 54 INIT_DRIVER_DATA; 55 INIT_OUTPUT_PRIV; 56 int i, ret; 57 58 union dri_buffer *dri_buffer; 59 union dri_buffer *extend_dri_buffer; 60 61 PPVR2DMEMINFO dri2_bb_export_meminfo; 62 63 struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; 64 65 if (psb_xrandr_extvideo_mode()) { 66 67 output->extend_drawable = (Window)psb_xrandr_create_full_screen_window(); 68 69 texture_priv->extend_dri_drawable = dri_get_drawable(ctx, output->extend_drawable); 70 if (!texture_priv->extend_dri_drawable) { 71 psb__error_message("%s(): Failed to get extend_dri_drawable\n", __func__); 72 return VA_STATUS_ERROR_UNKNOWN; 73 } 74 75 extend_dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->extend_dri_drawable); 76 if (!extend_dri_buffer) { 77 psb__error_message("%s(): Failed to get extend_dri_buffer\n", __func__); 78 return VA_STATUS_ERROR_UNKNOWN; 79 } 80 81 ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)extend_dri_buffer->dri2.name, &dri2_bb_export_meminfo); 82 if (ret != PVR2D_OK) { 83 psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret); 84 return VA_STATUS_ERROR_UNKNOWN; 85 } 86 87 memcpy(&texture_priv->extend_dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport)); 88 89 //must be Flip-Chain mode 90 for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { 91 ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->extend_dri2_bb_export.hBuffers[i], &texture_priv->extend_blt_meminfo[i]); 92 if (ret != PVR2D_OK) { 93 psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret); 94 return VA_STATUS_ERROR_UNKNOWN; 95 } 96 } 97 } 98 99 texture_priv->dri_drawable = dri_get_drawable(ctx, output->output_drawable); 100 if (!texture_priv->dri_drawable) { 101 psb__error_message("%s(): Failed to get dri_drawable\n", __func__); 102 return VA_STATUS_ERROR_UNKNOWN; 103 } 104 105 dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->dri_drawable); 106 if (!dri_buffer) { 107 psb__error_message("%s(): Failed to get dri_buffer\n", __func__); 108 return VA_STATUS_ERROR_UNKNOWN; 109 } 110 111 ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)dri_buffer->dri2.name, &dri2_bb_export_meminfo); 112 if (ret != PVR2D_OK) { 113 psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret); 114 return VA_STATUS_ERROR_UNKNOWN; 115 } 116 117 memcpy(&texture_priv->dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport)); 118 119 if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) { 120 psb__information_message("psb_dri_init: Now map buffer, DRI2 back buffer export type: DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS\n"); 121 122 for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { 123 ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->dri2_bb_export.hBuffers[i], &texture_priv->blt_meminfo[i]); 124 if (ret != PVR2D_OK) { 125 psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret); 126 return VA_STATUS_ERROR_UNKNOWN; 127 } 128 } 129 } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) { 130 psb__information_message("psb_dri_init: Now map buffer, DRI2 back buffer export type: DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN\n"); 131 132 for(i = 0; i < DRI2_FLIP_BUFFERS_NUM; i++) { 133 ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->dri2_bb_export.hBuffers[i], &texture_priv->flip_meminfo[i]); 134 if (ret != PVR2D_OK) { 135 psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret); 136 return VA_STATUS_ERROR_UNKNOWN; 137 } 138 } 139 } 140 141 texture_priv->dri_init_flag = 1; 142 143 PVR2DMemFree(texture_priv->hPVR2DContext, dri2_bb_export_meminfo); 144 return VA_STATUS_SUCCESS; 145} 146 147VAStatus psb_putsurface_ctexture( 148 VADriverContextP ctx, 149 VASurfaceID surface, 150 Drawable draw, 151 short srcx, 152 short srcy, 153 unsigned short srcw, 154 unsigned short srch, 155 short destx, 156 short desty, 157 unsigned short destw, 158 unsigned short desth, 159 unsigned int flags /* de-interlacing flags */ 160) 161{ 162 INIT_DRIVER_DATA; 163 INIT_OUTPUT_PRIV; 164 int ret; 165 int primary_crtc_x, primary_crtc_y, extend_crtc_x, extend_crtc_y; 166 int display_width, display_height, extend_display_width, extend_display_height; 167 psb_xrandr_location extend_location; 168 object_surface_p obj_surface = SURFACE(surface); 169 psb_surface_p psb_surface; 170 171 struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; 172 173 obj_surface = SURFACE(surface); 174 psb_surface = obj_surface->psb_surface; 175 176 if (output->output_drawable != draw) { 177 output->output_drawable = draw; 178 ret = psb_xrandr_init(ctx); 179 if ( ret != 0) { 180 psb__error_message("%s: Failed to initialize psb xrandr error # %d\n", __func__, ret); 181 return VA_STATUS_ERROR_UNKNOWN; 182 } 183 } 184 185 if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) { 186 ret = psb_xrandr_thread_create(ctx); 187 if ( ret != 0) { 188 psb__error_message("%s: Failed to create psb xrandr thread error # %d\n", __func__, ret); 189 return VA_STATUS_ERROR_UNKNOWN; 190 } 191 } 192 193 if (!texture_priv->dri_init_flag) { 194 ret = psb_dri_init(ctx, surface, draw); 195 if (ret != VA_STATUS_SUCCESS) 196 return VA_STATUS_ERROR_UNKNOWN; 197 } 198 199 if (psb_xrandr_clone_mode()) { 200 psb__information_message("psb_putsurface_ctexture: current mode is Clone\n"); 201 } else if (psb_xrandr_extend_mode()) { 202 ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height); 203 if (ret != 0) { 204 psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret); 205 return VA_STATUS_ERROR_UNKNOWN; 206 } 207 display_width += 1; 208 display_height += 1; 209 210 ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location); 211 if (ret != 0) { 212 psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret); 213 return VA_STATUS_ERROR_UNKNOWN; 214 } 215 extend_display_width += 1; 216 extend_display_height += 1; 217 218 switch (extend_location) { 219 case LEFT_OF: 220 display_height = display_height > extend_display_height ? display_height : extend_display_height; 221 if (destw > display_width + extend_display_width) 222 destw = display_width + extend_display_width; 223 if (desth > display_height) 224 desth = display_height; 225 break; 226 case RIGHT_OF: 227 display_height = display_height > extend_display_height ? display_height : extend_display_height; 228 if (destw > display_width + extend_display_width) 229 destw = display_width + extend_display_width; 230 if (desth > display_height) 231 desth = display_height; 232 break; 233 case BELOW: 234 display_width = display_width > extend_display_width ? display_width : extend_display_width; 235 if (destw > display_width) 236 destw = display_width; 237 if (desth > display_height + extend_display_height) 238 desth = display_height + extend_display_height; 239 break; 240 case ABOVE: 241 display_width = display_width > extend_display_width ? display_width : extend_display_width; 242 if (destw > display_width) 243 destw = display_width; 244 if (desth > display_height + extend_display_height) 245 desth = display_height + extend_display_height; 246 break; 247 case NORMAL: 248 default: 249 break; 250 } 251 psb__information_message("psb_putsurface_ctexture: current mode is Extend, Location: %08x\n", extend_location); 252 } else if (psb_xrandr_extvideo_mode()) { 253 254 psb__information_message("psb_putsurface_ctexture: current mode is ExtVideo, Location: %08x\n", extend_location); 255 ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height); 256 if (ret != 0) { 257 psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret); 258 return VA_STATUS_ERROR_UNKNOWN; 259 } 260 display_width += 1; 261 display_height += 1; 262 263 ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location); 264 if (ret != 0) { 265 psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret); 266 return VA_STATUS_ERROR_UNKNOWN; 267 } 268 extend_display_width += 1; 269 extend_display_height += 1; 270 271 psb__information_message("psb_putsurface_ctexture: ExtVideo coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", 272 srcx, srcy, srcw, srch, destx, desty, extend_display_width, extend_display_height, texture_priv->current_blt_buffer); 273 274 psb_putsurface_textureblit(ctx, texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, extend_crtc_x, extend_crtc_y, 275 extend_display_width, extend_display_height, 276 obj_surface->width, obj_surface->height, 277 psb_surface->stride, psb_surface->buf.drm_buf, 278 psb_surface->buf.pl_flags); 279 280 dri_swap_buffer(ctx, texture_priv->extend_dri_drawable); 281 texture_priv->extend_current_blt_buffer = (texture_priv->extend_current_blt_buffer + 1) & 0x01; 282 } 283 284 if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) { 285 psb__information_message("psb_putsurface_ctexture: SWAP BUFFER, Video coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", 286 srcx, srcy, srcw, srch, destx, desty, destw, desth, texture_priv->current_blt_buffer); 287 //FIXME: Currently using Extend Mode to simulate ExtVideo mode. 288 //When resolution >= 864x480, Extend video has a white line on top. 289 //When resolution >= 864x480, testsuite should create a window with maximum resolution of 864x480, but now it creates window based on the virtual frame buffer resolution. 290 //When ExtVideo driver is ready, double check the above 2 issue. 291 psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 292 obj_surface->width, obj_surface->height, 293 psb_surface->stride, psb_surface->buf.drm_buf, 294 psb_surface->buf.pl_flags); 295 296 dri_swap_buffer(ctx, texture_priv->dri_drawable); 297 texture_priv->current_blt_buffer = (texture_priv->current_blt_buffer + 1) & 0x01; 298 299 } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) { 300 psb__information_message("psb_putsurface_ctexture: FLIP CHAIN, Video coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", 301 srcx, srcy, srcw, srch, destx, desty, texture_priv->rootwin_width, texture_priv->rootwin_height, texture_priv->current_blt_buffer); 302 303 psb_putsurface_textureblit(ctx, texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, texture_priv->rootwin_width, texture_priv->rootwin_height, 304 obj_surface->width, obj_surface->height, 305 psb_surface->stride, psb_surface->buf.drm_buf, 306 psb_surface->buf.pl_flags); 307 308 dri_swap_buffer(ctx, texture_priv->dri_drawable); 309 texture_priv->current_blt_buffer++; 310 if(texture_priv->current_blt_buffer == DRI2_FLIP_BUFFERS_NUM) 311 texture_priv->current_blt_buffer = 0; 312 } 313 314 return VA_STATUS_SUCCESS; 315} 316