psb_coverlay.c revision c60d5b7bdb5616ca37e0b912c10725bec4320f33
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish, 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the following conditions: 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the Software. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Authors: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Jason Hu <jason.hu@intel.com> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Zhaohan Ren <zhaohan.ren@intel.com> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Shengquan Yuan <shengquan.yuan@intel.com> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/Xutil.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <X11/extensions/Xrandr.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <va/va_backend.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_output.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_surface.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_buffer.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_x11.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_surface_ext.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <wsbm/wsbm_manager.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_drv_video.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "psb_xrandr.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_OUTPUT_PRIV psb_x11_output_p output = (psb_x11_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)psb_x11_getWindowCoordinate(Display * display, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window x11_window_id, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb_x11_win_t * psX11Window, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int * pbIsVisible) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window DummyWindow; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Status status; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XWindowAttributes sXWinAttrib; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((status = XGetWindowAttributes(display, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x11_window_id, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sXWinAttrib)) == 0) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get X11 window coordinates - error %lu\n", __func__, (unsigned long)status); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psX11Window->i32Left = sXWinAttrib.x; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psX11Window->i32Top = sXWinAttrib.y; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psX11Window->ui32Width = sXWinAttrib.width; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psX11Window->ui32Height = sXWinAttrib.height; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pbIsVisible = (sXWinAttrib.map_state == IsViewable); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!*pbIsVisible) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (XTranslateCoordinates(display, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) x11_window_id, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultRootWindow(display), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &psX11Window->i32Left, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &psX11Window->i32Top, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &DummyWindow) == 0) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to tranlate X coordinates - error %lu\n", __func__, (unsigned long)status); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psX11Window->i32Right = psX11Window->i32Left + psX11Window->ui32Width - 1; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psX11Window->i32Bottom = psX11Window->i32Top + psX11Window->ui32Height - 1; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static psb_x11_clip_list_t * 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)psb_x11_createClipBoxNode(psb_x11_win_t * pRect, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb_x11_clip_list_t * pClipNext) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch psb_x11_clip_list_t * pCurrent = NULL; 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCurrent = (psb_x11_clip_list_t *)calloc(1, sizeof(psb_x11_clip_list_t)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pCurrent) { 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pCurrent->rect = *pRect; 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pCurrent->next = pClipNext; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pCurrent; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pClipNext; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)psb_x11_freeWindowClipBoxList(psb_x11_clip_list_t * pHead) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb_x11_clip_list_t * pNext = NULL; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pHead) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pNext = pHead->next; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(pHead); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pHead = pNext; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define IS_BETWEEN_RANGE(a,b,c) ((a<=b)&&(b<=c)) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static psb_x11_clip_list_t * 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)psb_x11_substractRects(Display * display, 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psb_x11_clip_list_t * psRegion, 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psb_x11_win_t * psRect) 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psb_x11_clip_list_t * psCur, * psPrev, * psFirst, * psNext; 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psb_x11_win_t sCreateRect; 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int display_width = (int)(DisplayWidth(display, DefaultScreen(display))) - 1; 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int display_height = (int)(DisplayHeight(display, DefaultScreen(display))) - 1; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst = psb_x11_createClipBoxNode(psRect, NULL); 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (psFirst->rect.i32Left < 0) 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) psFirst->rect.i32Left = 0; 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else if (psFirst->rect.i32Left > display_width) 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) psFirst->rect.i32Left = display_width; 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (psFirst->rect.i32Right < 0) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst->rect.i32Right = 0; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (psFirst->rect.i32Right > display_width) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst->rect.i32Right = display_width; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (psFirst->rect.i32Top < 0) 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst->rect.i32Top = 0; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (psFirst->rect.i32Top > display_height) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst->rect.i32Top = display_height; 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (psFirst->rect.i32Bottom < 0) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst->rect.i32Bottom = 0; 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else if (psFirst->rect.i32Bottom > display_height) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst->rect.i32Bottom = display_height; 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (psRegion) { 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psCur = psFirst; 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psPrev = NULL; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (psCur) { 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psNext = psCur->next; 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if ((psRegion->rect.i32Left > psCur->rect.i32Left) && 1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) (psRegion->rect.i32Left <= psCur->rect.i32Right)) { 1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) sCreateRect.i32Right = psRegion->rect.i32Left - 1; 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sCreateRect.i32Left = psCur->rect.i32Left; 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sCreateRect.i32Top = psCur->rect.i32Top; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Bottom = psCur->rect.i32Bottom; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psFirst = psb_x11_createClipBoxNode(&sCreateRect, psFirst); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!psPrev) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psPrev = psFirst; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psCur->rect.i32Left = psRegion->rect.i32Left; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((psRegion->rect.i32Right >= psCur->rect.i32Left) && 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (psRegion->rect.i32Right < psCur->rect.i32Right)) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Left = psRegion->rect.i32Right + 1; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Right = psCur->rect.i32Right; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Top = psCur->rect.i32Top; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Bottom = psCur->rect.i32Bottom; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psFirst = psb_x11_createClipBoxNode(&sCreateRect, psFirst); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!psPrev) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psPrev = psFirst; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psCur->rect.i32Right = psRegion->rect.i32Right; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((psRegion->rect.i32Top > psCur->rect.i32Top) && 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (psRegion->rect.i32Top <= psCur->rect.i32Bottom)) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Bottom = psRegion->rect.i32Top - 1; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Left = psCur->rect.i32Left; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Right = psCur->rect.i32Right; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Top = psCur->rect.i32Top; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psFirst = psb_x11_createClipBoxNode(&sCreateRect, psFirst); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!psPrev) 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) psPrev = psFirst; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psCur->rect.i32Top = psRegion->rect.i32Top; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((psRegion->rect.i32Bottom >= psCur->rect.i32Top) && 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (psRegion->rect.i32Bottom < psCur->rect.i32Bottom)) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Top = psRegion->rect.i32Bottom + 1; 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sCreateRect.i32Left = psCur->rect.i32Left; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Right = psCur->rect.i32Right; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sCreateRect.i32Bottom = psCur->rect.i32Bottom; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psFirst = psb_x11_createClipBoxNode(&sCreateRect, psFirst); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!psPrev) 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) psPrev = psFirst; 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) psCur->rect.i32Bottom = psRegion->rect.i32Bottom; 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((IS_BETWEEN_RANGE(psRegion->rect.i32Left, psCur->rect.i32Left, psRegion->rect.i32Right)) && 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (IS_BETWEEN_RANGE(psRegion->rect.i32Left, psCur->rect.i32Right, psRegion->rect.i32Right)) && 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (IS_BETWEEN_RANGE(psRegion->rect.i32Top, psCur->rect.i32Top, psRegion->rect.i32Bottom)) && 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (IS_BETWEEN_RANGE(psRegion->rect.i32Top, psCur->rect.i32Bottom, psRegion->rect.i32Bottom))) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (psPrev) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psPrev->next = psCur->next; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(psCur); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psCur = psPrev; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(psCur); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psCur = NULL; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psFirst = psNext; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psPrev = psCur; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psCur = psNext; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }//while(psCur) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psRegion = psRegion->next; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }//while(psRegion) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return psFirst; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)psb_x11_createWindowClipBoxList(Display * display, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window x11_window_id, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb_x11_clip_list_t ** ppWindowClipBoxList, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int * pui32NumClipBoxList) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window CurrentWindow = x11_window_id; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window RootWindow, ParentWindow, ChildWindow; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window * pChildWindow; 2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Status XResult; 2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) unsigned int i32NumChildren, i; 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int bIsVisible; 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) unsigned int ui32NumRects = 0; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb_x11_clip_list_t *psRegions = NULL; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb_x11_win_t sRect; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!display || (!ppWindowClipBoxList) || (!pui32NumClipBoxList)) 2696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return -1; 2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) XResult = XQueryTree(display, 2726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CurrentWindow, 2736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &RootWindow, 2746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &ParentWindow, 2756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &pChildWindow, 2766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &i32NumChildren); 2776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (XResult == 0) 2786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return -2; 2796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (i32NumChildren) { 2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (i = 0; i < i32NumChildren; i++) { 2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) psb_x11_getWindowCoordinate(display, x11_window_id, &sRect, &bIsVisible); 2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (bIsVisible) { 2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) psRegions = psb_x11_createClipBoxNode(&sRect, psRegions); 2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ui32NumRects++; 2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) XFree(pChildWindow); 2906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) i32NumChildren = 0; 2916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) while (CurrentWindow != RootWindow) { 2946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChildWindow = CurrentWindow; 2956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CurrentWindow = ParentWindow; 2966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) XResult = XQueryTree(display, 2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CurrentWindow, 2996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &RootWindow, 3006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &ParentWindow, 3016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &pChildWindow, 3026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &i32NumChildren); 3036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (XResult == 0) { 3046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (i32NumChildren) 3056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) XFree(pChildWindow); 3066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) psb_x11_freeWindowClipBoxList(psRegions); 3086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return -3; 3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (i32NumChildren) { 3126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) unsigned int iStartWindow = 0; 3136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (i = 0; i < i32NumChildren; i++) { 3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (pChildWindow[i] == ChildWindow) { 3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) iStartWindow = i; 3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) break; 3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (i == i32NumChildren) { 3226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) XFree(pChildWindow); 3236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) psb_x11_freeWindowClipBoxList(psRegions); 3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return -4; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = iStartWindow + 1; i < i32NumChildren; i++) { 328 psb_x11_getWindowCoordinate(display, pChildWindow[i], &sRect, &bIsVisible); 329 if (bIsVisible) { 330 psRegions = psb_x11_createClipBoxNode(&sRect, psRegions); 331 ui32NumRects++; 332 } 333 } 334 335 XFree(pChildWindow); 336 } 337 } 338 339 ui32NumRects = 0; 340 341 if (psRegions) { 342 psb_x11_getWindowCoordinate(display, x11_window_id, &sRect, &bIsVisible); 343 *ppWindowClipBoxList = psb_x11_substractRects(display, psRegions, &sRect); 344 psb_x11_freeWindowClipBoxList(psRegions); 345 346 psRegions = *ppWindowClipBoxList; 347 348 while (psRegions) { 349 ui32NumRects++; 350 psRegions = psRegions->next; 351 } 352 } else { 353 *ppWindowClipBoxList = psb_x11_substractRects(display, NULL, &sRect); 354 ui32NumRects = 1; 355 } 356 357 *pui32NumClipBoxList = ui32NumRects; 358 359 return 0; 360} 361 362static int psb_cleardrawable_stopoverlay( 363 VADriverContextP ctx, 364 Drawable draw, /* X Drawable */ 365 short destx, 366 short desty, 367 unsigned short destw, 368 unsigned short desth 369) 370{ 371 INIT_DRIVER_DATA; 372 INIT_OUTPUT_PRIV; 373 374 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, destx, desty, destw, desth); 375 XSync((Display *)ctx->native_dpy, False); 376 377 driver_data->cur_displaying_surface = VA_INVALID_SURFACE; 378 driver_data->last_displaying_surface = VA_INVALID_SURFACE; 379 380 return 0; 381} 382 383static VAStatus psb_DisplayRGBASubpicture( 384 PsbVASurfaceRec *subpicture, 385 VADriverContextP ctx, 386 int win_width, 387 int win_height, 388 int surface_x, 389 int surface_y, 390 int surface_w, 391 int surface_h, 392 psb_extvideo_subtitle subtitle 393) 394{ 395 INIT_DRIVER_DATA; 396 INIT_OUTPUT_PRIV; 397 XImage *ximg = NULL; 398 Visual *visual; 399 PsbPortPrivRec *pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); 400 struct _WsbmBufferObject *bo = subpicture->bo; 401 int image_width, image_height, width, height, size; 402 int srcx, srcy, srcw, srch; 403 int destx, desty, destw, desth; 404 int depth, i; 405 406 if (subpicture->fourcc != VA_FOURCC_RGBA) { 407 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Invalid image format, ONLY support RGBA subpicture now.\n", __func__); 408 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; 409 } 410 411 for (i = 0; subpicture != NULL; subpicture = subpicture->next, i++) { 412 srcx = subpicture->subpic_srcx; 413 srcy = subpicture->subpic_srcy; 414 srcw = subpicture->subpic_srcw; 415 srch = subpicture->subpic_srch; 416 417 destx = subpicture->subpic_dstx + surface_x; 418 desty = subpicture->subpic_dsty + surface_y; 419 destw = subpicture->subpic_dstw; 420 desth = subpicture->subpic_dsth; 421 422 image_width = subpicture->width; 423 image_height = subpicture->height; 424 size = subpicture->size; 425 426 //clip in image region 427 if (srcx < 0) { 428 srcw += srcx; 429 srcx = 0; 430 } 431 432 if (srcy < 0) { 433 srch += srcy; 434 srcy = 0; 435 } 436 437 if ((srcx + srcw) > image_width) 438 srcw = image_width - srcx; 439 if ((srcy + srch) > image_height) 440 srch = image_height - srcy; 441 442 //clip in drawable region 443 if (destx < 0) { 444 destw += destx; 445 destx = 0; 446 } 447 448 if (desty < 0) { 449 desth += desty; 450 desty = 0; 451 } 452 453 if ((destx + destw) > surface_w) 454 destw = surface_w - destx; 455 if ((desty + desth) > surface_h) 456 desth = surface_h - desty; 457 458 if (srcw <= destw) 459 width = srcw; 460 else 461 width = destw; 462 463 if (srch <= desth) 464 height = srch; 465 else 466 height = desth; 467 468 visual = DefaultVisual(ctx->native_dpy, 0); 469 depth = DefaultDepth(ctx->native_dpy, 0); 470 471 ximg = XCreateImage(ctx->native_dpy, visual, depth, ZPixmap, 0, NULL, image_width, image_height, 32, 0); 472 473 if (NULL == ximg) { 474 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: XCreateImage failed! at L%d\n", __func__, __LINE__); 475 return VA_STATUS_ERROR_UNKNOWN; 476 } 477 478 ximg->data = wsbmBOMap(bo, WSBM_ACCESS_READ); 479 if (NULL == ximg->data) { 480 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to map to ximg->data.\n", __func__); 481 return VA_STATUS_ERROR_ALLOCATION_FAILED; 482 } 483 484 pPriv->clear_key[i].subpic_dstx = destx; 485 pPriv->clear_key[i].subpic_dsty = desty; 486 pPriv->clear_key[i].subpic_dstw = destw; 487 pPriv->clear_key[i].subpic_dsth = desth; 488 if (psb_xrandr_extvideo_mode()) { 489 /*It is a HACK: Adjust subtitle to proper position.*/ 490 float xScale, yScale; 491 492 xScale = win_width * 1.0 / surface_w; 493 yScale = win_height * 1.0 / surface_h; 494 destx = subpicture->subpic_dstx * xScale; 495 desty = subpicture->subpic_dsty * yScale; 496 } 497 XPutImage(ctx->native_dpy, output->output_drawable, output->gc, ximg, srcx, srcy, destx, desty, width, height); 498 XSync((Display *)ctx->native_dpy, False); 499 500 if (psb_xrandr_extvideo_mode() && 501 (subtitle == ONLY_HDMI || subtitle == BOTH)) { 502 float xScale, yScale; 503 504 xScale = pPriv->extend_display_width * 1.0 / surface_w; 505 yScale = pPriv->extend_display_height * 1.0 / surface_h; 506 507 destx = subpicture->subpic_dstx * xScale; 508 desty = subpicture->subpic_dsty * yScale; 509 510 XPutImage(ctx->native_dpy, output->extend_drawable, output->extend_gc, ximg, 511 srcx, srcy, destx, desty, destw, desth); 512 XSync((Display *)ctx->native_dpy, False); 513 } 514 515 pPriv->subpic_clear_flag = 0; 516 ximg->data = NULL; 517 wsbmBOUnmap(bo); 518 if (NULL != ximg) 519 XDestroyImage(ximg); 520 } 521 return VA_STATUS_SUCCESS; 522} 523 524static VAStatus psb_repaint_colorkey( 525 VADriverContextP ctx, 526 Drawable draw, /* X Drawable */ 527 VASurfaceID surface, 528 int x11_window_width, 529 int x11_window_height 530) 531{ 532 INIT_DRIVER_DATA; 533 INIT_OUTPUT_PRIV; 534 int i, ret; 535 psb_x11_clip_list_t *pClipNext = NULL; 536 VARectangle *pVaWindowClipRects = NULL; 537 object_surface_p obj_surface = SURFACE(surface); 538 PsbPortPrivRec *pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); 539 540 if (output->frame_count % 500 == 0 || driver_data->xrandr_update) { 541 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Repaint color key.\n"); 542 if (output->pClipBoxList) 543 psb_x11_freeWindowClipBoxList(output->pClipBoxList); 544 /* get window clipbox */ 545 ret = psb_x11_createWindowClipBoxList(ctx->native_dpy, draw, &output->pClipBoxList, &output->ui32NumClipBoxList); 546 if (ret != 0) { 547 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: get window clip boxes error # %d\n", __func__, ret); 548 return VA_STATUS_ERROR_UNKNOWN; 549 } 550 if (output->frame_count == 500) 551 output->frame_count = 0; 552 553 driver_data->xrandr_update = 0; 554 } 555 556 pVaWindowClipRects = (VARectangle *)calloc(1, sizeof(VARectangle) * output->ui32NumClipBoxList); 557 if (!pVaWindowClipRects) { 558 psb_x11_freeWindowClipBoxList(output->pClipBoxList); 559 return VA_STATUS_ERROR_ALLOCATION_FAILED; 560 } 561 562 memset(pVaWindowClipRects, 0, sizeof(VARectangle)*output->ui32NumClipBoxList); 563 pClipNext = output->pClipBoxList; 564#ifdef CLIP_DEBUG 565 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Total %d clip boxes\n", __func__, output->ui32NumClipBoxList); 566#endif 567 for (i = 0; i < output->ui32NumClipBoxList; i++) { 568 pVaWindowClipRects[i].x = pClipNext->rect.i32Left; 569 pVaWindowClipRects[i].y = pClipNext->rect.i32Top; 570 pVaWindowClipRects[i].width = pClipNext->rect.i32Right - pClipNext->rect.i32Left; 571 pVaWindowClipRects[i].height = pClipNext->rect.i32Bottom - pClipNext->rect.i32Top; 572#ifdef CLIP_DEBUG 573 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: clip boxes Left Top (%d, %d) Right Bottom (%d, %d) width %d height %d\n", __func__, 574 pClipNext->rect.i32Left, pClipNext->rect.i32Top, 575 pClipNext->rect.i32Right, pClipNext->rect.i32Bottom, 576 pVaWindowClipRects[i].width, pVaWindowClipRects[i].height); 577#endif 578 pClipNext = pClipNext->next; 579 } 580 581 /* repaint the color key when window size changed*/ 582 if (!obj_surface->subpictures && 583 ((pPriv->x11_window_width != x11_window_width) || 584 (pPriv->x11_window_height != x11_window_height))) { 585 pPriv->x11_window_width = x11_window_width; 586 pPriv->x11_window_height = x11_window_height; 587 XSetForeground((Display *)ctx->native_dpy, output->gc, pPriv->colorKey); 588 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); 589 XSync((Display *)ctx->native_dpy, False); 590 } 591 592 593 if ((!obj_surface->subpictures) && 594 ((output->ui32NumClipBoxList != pPriv->last_num_clipbox) || 595 (memcmp(&pVaWindowClipRects[0], &(pPriv->last_clipbox[0]), (output->ui32NumClipBoxList > 16 ? 16 : output->ui32NumClipBoxList)*sizeof(VARectangle)) != 0))) { 596 pPriv->last_num_clipbox = output->ui32NumClipBoxList; 597 memcpy(&pPriv->last_clipbox[0], &pVaWindowClipRects[0], (output->ui32NumClipBoxList > 16 ? 16 : output->ui32NumClipBoxList)*sizeof(VARectangle)); 598 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); 599 XSync((Display *)ctx->native_dpy, False); 600 } 601 602 free(pVaWindowClipRects); 603 604 return VA_STATUS_SUCCESS; 605} 606 607static VAStatus psb_extendMode_getCoordinate( 608 PsbPortPrivPtr pPriv, 609 psb_xrandr_location extend_location, 610 short destx, 611 short desty, 612 short srcx, 613 short srcy, 614 float xScaleFactor, 615 float yScaleFactor, 616 int *x11_window_width, 617 int *x11_window_height, 618 psb_overlay_rect_p local_rect, 619 psb_overlay_rect_p extend_rect, 620 enum overlay_id_t *extend_overlay 621) 622{ 623 switch (extend_location) { 624 case LEFT_OF: 625 if ((destx + *x11_window_width) > (pPriv->display_width + pPriv->extend_display_width)) { 626 *x11_window_width = pPriv->display_width + pPriv->extend_display_width - destx; 627 } 628 if (((desty + *x11_window_height) < pPriv->display_height) && 629 ((desty + *x11_window_height) < pPriv->extend_display_height)) 630 local_rect->dHeight = extend_rect->dHeight = *x11_window_height; 631 else if (pPriv->display_height < pPriv->extend_display_height) { 632 local_rect->dHeight = pPriv->display_height - desty; 633 if ((desty + *x11_window_height) > pPriv->extend_display_height) 634 extend_rect->dHeight = *x11_window_height = pPriv->extend_display_height - desty; 635 else 636 extend_rect->dHeight = *x11_window_height; 637 } else { 638 extend_rect->dHeight = pPriv->extend_display_height - desty; 639 if ((desty + *x11_window_height) > pPriv->display_height) 640 local_rect->dHeight = *x11_window_height = pPriv->display_height - desty; 641 else 642 local_rect->dHeight = *x11_window_height; 643 } 644 645 if ((destx < pPriv->extend_display_width) && ((destx + *x11_window_width) < pPriv->extend_display_width)) { 646 local_rect->dWidth = 0; 647 extend_rect->dWidth = *x11_window_width; 648 *extend_overlay = OVERLAY_A; 649 local_rect->destx = 0; 650 } else if ((destx < pPriv->extend_display_width) && ((destx + *x11_window_width) >= pPriv->extend_display_width)) { 651 extend_rect->dWidth = pPriv->extend_display_width - destx; 652 local_rect->dWidth = *x11_window_width - extend_rect->dWidth; 653 local_rect->destx = 0; 654 } else { 655 local_rect->dWidth = *x11_window_width; 656 extend_rect->dWidth = 0; 657 local_rect->destx = destx - pPriv->extend_display_width; 658 } 659 local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); 660 local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); 661 extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); 662 extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); 663 664 local_rect->srcx = srcx + extend_rect->sWidth; 665 extend_rect->srcx = srcx; 666 local_rect->srcy = extend_rect->srcy = srcy; 667 668 extend_rect->destx = destx; 669 local_rect->desty = extend_rect->desty = desty; 670 break; 671 case RIGHT_OF: 672 if ((destx + *x11_window_width) > (pPriv->display_width + pPriv->extend_display_width)) { 673 *x11_window_width = pPriv->display_width + pPriv->extend_display_width - destx; 674 } 675 if (((desty + *x11_window_height) < pPriv->display_height) && 676 ((desty + *x11_window_height) < pPriv->extend_display_height)) 677 local_rect->dHeight = extend_rect->dHeight = *x11_window_height; 678 else if (pPriv->display_height < pPriv->extend_display_height) { 679 local_rect->dHeight = pPriv->display_height - desty; 680 if ((desty + *x11_window_height) > pPriv->extend_display_height) 681 extend_rect->dHeight = *x11_window_height = pPriv->extend_display_height - desty; 682 else 683 extend_rect->dHeight = *x11_window_height; 684 } else { 685 extend_rect->dHeight = pPriv->extend_display_height - desty; 686 if ((desty + *x11_window_height) > pPriv->display_height) 687 local_rect->dHeight = *x11_window_height = pPriv->display_height - desty; 688 else 689 local_rect->dHeight = *x11_window_height; 690 } 691 692 if ((destx < pPriv->display_width) && ((destx + *x11_window_width) < pPriv->display_width)) { 693 local_rect->dWidth = *x11_window_width; 694 extend_rect->dWidth = 0; 695 extend_rect->destx = 0; 696 } else if ((destx < pPriv->display_width) && ((destx + *x11_window_width) >= pPriv->display_width)) { 697 local_rect->dWidth = pPriv->display_width - destx; 698 extend_rect->dWidth = *x11_window_width - local_rect->dWidth; 699 extend_rect->destx = 0; 700 } else { 701 local_rect->dWidth = 0; 702 extend_rect->dWidth = *x11_window_width; 703 *extend_overlay = OVERLAY_A; 704 extend_rect->destx = destx - pPriv->display_width; 705 } 706 local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); 707 local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); 708 extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); 709 extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); 710 711 local_rect->srcx = srcx; 712 extend_rect->srcx = srcx + local_rect->sWidth; 713 local_rect->srcy = extend_rect->srcy = srcy; 714 715 local_rect->destx = destx; 716 local_rect->desty = extend_rect->desty = desty; 717 break; 718 case ABOVE: 719 if (((destx + *x11_window_width) < pPriv->display_width) && 720 ((destx + *x11_window_width) < pPriv->extend_display_width)) 721 local_rect->dWidth = extend_rect->dWidth = *x11_window_width; 722 else if (pPriv->display_width < pPriv->extend_display_width) { 723 local_rect->dWidth = pPriv->display_width - destx; 724 if ((destx + *x11_window_width) > pPriv->extend_display_width) 725 extend_rect->dWidth = *x11_window_width = pPriv->extend_display_width - destx; 726 else 727 extend_rect->dWidth = *x11_window_width; 728 } else { 729 extend_rect->dWidth = pPriv->extend_display_width - destx; 730 if ((destx + *x11_window_width) > pPriv->display_width) 731 local_rect->dWidth = *x11_window_width = pPriv->display_width - destx; 732 else 733 local_rect->dWidth = *x11_window_width; 734 } 735 736 if ((desty + *x11_window_height) > (pPriv->display_height + pPriv->extend_display_height)) { 737 *x11_window_height = pPriv->display_height + pPriv->extend_display_height - desty; 738 } 739 740 if ((desty < pPriv->extend_display_height) && ((desty + *x11_window_height) < pPriv->extend_display_height)) { 741 local_rect->dHeight = 0; 742 extend_rect->dHeight = *x11_window_height; 743 *extend_overlay = OVERLAY_A; 744 local_rect->desty = 0; 745 } else if ((desty < pPriv->extend_display_height) && ((desty + *x11_window_height) >= pPriv->extend_display_height)) { 746 extend_rect->dHeight = pPriv->extend_display_height - desty; 747 local_rect->dHeight = *x11_window_height - extend_rect->dHeight; 748 local_rect->desty = 0; 749 } else { 750 local_rect->dHeight = *x11_window_height; 751 extend_rect->dHeight = 0; 752 local_rect->desty = desty - pPriv->extend_display_height; 753 } 754 local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); 755 local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); 756 extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); 757 extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); 758 759 local_rect->srcy = srcy + extend_rect->sHeight; 760 extend_rect->srcy = srcy; 761 local_rect->srcx = extend_rect->srcx = srcx; 762 763 extend_rect->desty = desty; 764 local_rect->destx = extend_rect->destx = destx; 765 break; 766 case BELOW: 767 if (((destx + *x11_window_width) < pPriv->display_width) && 768 ((destx + *x11_window_width) < pPriv->extend_display_width)) 769 local_rect->dWidth = extend_rect->dWidth = *x11_window_width; 770 else if (pPriv->display_width < pPriv->extend_display_width) { 771 local_rect->dWidth = pPriv->display_width - destx; 772 if ((destx + *x11_window_width) > pPriv->extend_display_width) 773 extend_rect->dWidth = *x11_window_width = pPriv->extend_display_width - destx; 774 else 775 extend_rect->dWidth = *x11_window_width; 776 } else { 777 extend_rect->dWidth = pPriv->extend_display_width - destx; 778 if ((destx + *x11_window_width) > pPriv->display_width) 779 local_rect->dWidth = *x11_window_width = pPriv->display_width - destx; 780 else 781 local_rect->dWidth = *x11_window_width; 782 } 783 784 if ((desty + *x11_window_height) > (pPriv->display_height + pPriv->extend_display_height)) { 785 *x11_window_height = pPriv->display_height + pPriv->extend_display_height - desty; 786 } 787 788 if ((desty < pPriv->display_height) && ((desty + *x11_window_height) < pPriv->display_height)) { 789 local_rect->dHeight = *x11_window_height; 790 extend_rect->dHeight = 0; 791 extend_rect->desty = 0; 792 } else if ((desty < pPriv->display_height) && ((desty + *x11_window_height) >= pPriv->display_height)) { 793 local_rect->dHeight = pPriv->display_height - desty; 794 extend_rect->dHeight = *x11_window_height - local_rect->dHeight; 795 extend_rect->desty = 0; 796 } else { 797 local_rect->dHeight = 0; 798 extend_rect->dHeight = *x11_window_height; 799 *extend_overlay = OVERLAY_A; 800 extend_rect->desty = desty - pPriv->display_height; 801 } 802 local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); 803 local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); 804 extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); 805 extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); 806 807 local_rect->srcy = srcy; 808 extend_rect->srcy = srcy + local_rect->sHeight; 809 local_rect->srcx = extend_rect->srcx = srcx; 810 811 local_rect->desty = desty; 812 local_rect->destx = extend_rect->destx = destx; 813 break; 814 case NORMAL: 815 default: 816 break; 817 } 818 return VA_STATUS_SUCCESS; 819} 820 821static void psb_init_subpicture(VADriverContextP ctx, PsbPortPrivPtr pPriv) 822{ 823 INIT_DRIVER_DATA; 824 struct drm_psb_register_rw_arg regs; 825 unsigned int subpicture_enable_mask = REGRWBITS_DSPACNTR; 826 827 if (!pPriv->subpicture_enabled) { 828 if (psb_xrandr_hdmi_enabled()) 829 subpicture_enable_mask |= REGRWBITS_DSPBCNTR; 830 if (psb_xrandr_mipi1_enabled()) 831 subpicture_enable_mask |= REGRWBITS_DSPCCNTR; 832 833 memset(®s, 0, sizeof(regs)); 834 regs.subpicture_enable_mask = subpicture_enable_mask; 835 pPriv->subpicture_enable_mask = subpicture_enable_mask; 836 pPriv->subpicture_enabled = 1; 837 drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); 838 } 839} 840 841static void psb_clear_subpictures( 842 VADriverContextP ctx, 843 PsbPortPrivPtr pPriv, 844 int win_width, 845 int win_height, 846 object_surface_p obj_surface 847) 848{ 849 INIT_OUTPUT_PRIV; 850 PsbVASurfaceRec *subpicture = (PsbVASurfaceRec *)obj_surface->subpictures; 851 int i; 852 853 if (subpicture == NULL) { 854 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Surface has no subpicture to render.\n"); 855 return; 856 } 857 858 for (i = 0; subpicture != NULL; subpicture = subpicture->next, i++) { 859 if ((subpicture->subpic_dstx != pPriv->clear_key[i].subpic_dstx) || 860 (subpicture->subpic_dsty != pPriv->clear_key[i].subpic_dsty) || 861 (subpicture->subpic_dstw != pPriv->clear_key[i].subpic_dstw) || 862 (subpicture->subpic_dsth != pPriv->clear_key[i].subpic_dsth)) { 863 XSetForeground((Display *)ctx->native_dpy, output->gc, 0); 864 XFillRectangle((Display *)ctx->native_dpy, output->output_drawable, output->gc, 0, 0, win_width, win_height); 865 XSync((Display *)ctx->native_dpy, False); 866 if (psb_xrandr_extvideo_mode()) { 867 XSetForeground((Display *)ctx->native_dpy, output->extend_gc, 0); 868 XFillRectangle((Display *)ctx->native_dpy, output->extend_drawable, output->extend_gc, 869 0, 0, pPriv->extend_display_width, pPriv->extend_display_height); 870 XSync((Display *)ctx->native_dpy, False); 871 } 872 pPriv->subpic_clear_flag = 1; 873 } 874 } 875 return; 876} 877 878VAStatus psb_putsurface_coverlay( 879 VADriverContextP ctx, 880 VASurfaceID surface, 881 Drawable draw, /* X Drawable */ 882 short srcx, 883 short srcy, 884 unsigned short srcw, 885 unsigned short srch, 886 short destx, 887 short desty, 888 unsigned short destw, 889 unsigned short desth, 890 VARectangle *cliprects, /* client supplied clip list */ 891 unsigned int number_cliprects, /* number of clip rects in the clip list */ 892 unsigned int flags /* de-interlacing flags */ 893) 894{ 895 INIT_DRIVER_DATA; 896 INIT_OUTPUT_PRIV; 897 int ret; 898 int x11_window_width = destw, x11_window_height = desth; 899 psb_xrandr_location extend_location; 900 object_surface_p obj_surface = SURFACE(surface); 901 PsbPortPrivRec *pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); 902 int primary_crtc_x, primary_crtc_y, extend_crtc_x, extend_crtc_y; 903 enum pipe_id_t local_pipe = PIPEA, extend_pipe = PIPEB; 904 int surfacex = destx, surfacey = desty; 905 float xScaleFactor, yScaleFactor; 906 Rotation rotation = RR_Rotate_0; 907 psb_output_device local_device, extend_device; 908 psb_extvideo_subtitle subtitle; 909 910 if (flags & VA_CLEAR_DRAWABLE) { 911 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Clean draw with color 0x%08x\n", driver_data->clear_color); 912 psb_cleardrawable_stopoverlay(ctx, draw, destx, desty, destw, desth); 913 914 return VA_STATUS_SUCCESS; 915 } 916 917 if (output->frame_count % 500 == 0 || driver_data->xrandr_update) { 918 /* get window screen coordination */ 919 ret = psb_x11_getWindowCoordinate(ctx->native_dpy, draw, &output->winRect, &output->bIsVisible); 920 if (ret != 0) { 921 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get X11 window coordinates error # %d\n", __func__, ret); 922 return VA_STATUS_ERROR_UNKNOWN; 923 } 924 } 925 926 if (!output->bIsVisible) { 927 return VA_STATUS_SUCCESS; 928 } 929 930 if (NULL == obj_surface) { 931 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Invalid surface id 0x%08x.\n", __func__, surface); 932 return VA_STATUS_ERROR_INVALID_SURFACE; 933 } 934 935 if (output->output_drawable != draw) { 936 output->output_drawable = draw; 937 } 938 939 if (!output->gc) { 940 output->gc = XCreateGC((Display *)ctx->native_dpy, draw, 0, NULL); 941 /* paint the color key */ 942 if (!obj_surface->subpictures && !driver_data->overlay_auto_paint_color_key) { 943 XSetForeground((Display *)ctx->native_dpy, output->gc, pPriv->colorKey); 944 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); 945 XSync((Display *)ctx->native_dpy, False); 946 } 947 } 948 949 if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) { 950 ret = psb_xrandr_thread_create(ctx); 951 if (ret != 0) { 952 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to create psb xrandr thread error # %d\n", __func__, ret); 953 return VA_STATUS_ERROR_UNKNOWN; 954 } 955 } 956 957 ret = psb_xrandr_local_crtc_coordinate(&local_device, &primary_crtc_x, &primary_crtc_y, &pPriv->display_width, &pPriv->display_height, &rotation); 958 if (ret != VA_STATUS_SUCCESS) { 959 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret); 960 return VA_STATUS_ERROR_UNKNOWN; 961 } 962 switch (local_device) { 963 case LVDS0: 964 case MIPI0: 965 local_pipe = PIPEA; 966 break; 967 /* single HDMI */ 968 case HDMI: 969 local_pipe = PIPEB; 970 break; 971 case MIPI1: 972 local_pipe = PIPEC; 973 break; 974 } 975 976 if (!psb_xrandr_single_mode()) { 977 978 ret = psb_xrandr_extend_crtc_coordinate(&extend_device, &extend_crtc_x, &extend_crtc_y, 979 &pPriv->extend_display_width, &pPriv->extend_display_height, &extend_location, &rotation); 980 if (ret != VA_STATUS_SUCCESS) { 981 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret); 982 return VA_STATUS_ERROR_UNKNOWN; 983 } 984 985 switch (extend_device) { 986 case HDMI: 987 extend_pipe = PIPEB; 988 break; 989 case MIPI1: 990 extend_pipe = PIPEC; 991 break; 992 default: 993 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to get extend pipe\n", __func__); 994 break; 995 } 996 } 997 998 /*clip in the window area*/ 999 if (destx < 0) { 1000 x11_window_width += destx; 1001 destx = 0; 1002 } 1003 1004 if (desty < 0) { 1005 x11_window_height += desty; 1006 desty = 0; 1007 } 1008 1009 if (srcx < 0) { 1010 srcw += srcx; 1011 srcx = 0; 1012 } 1013 1014 if (srcy < 0) { 1015 srch += srcy; 1016 srcy = 0; 1017 } 1018 1019 if ((destx + x11_window_width) > output->winRect.ui32Width) 1020 x11_window_width = output->winRect.ui32Width - destx; 1021 1022 if ((desty + x11_window_height) > output->winRect.ui32Height) 1023 x11_window_height = output->winRect.ui32Height - desty; 1024 1025 /*translate destx, desty into screen coordinate*/ 1026 destx += output->winRect.i32Left; 1027 desty += output->winRect.i32Top; 1028 1029 /*clip in the screen area*/ 1030 xScaleFactor = srcw * 1.0 / x11_window_width; 1031 yScaleFactor = srch * 1.0 / x11_window_height; 1032 1033 if (destx < 0) { 1034 x11_window_width += destx; 1035 srcx = (short)((-destx) * xScaleFactor); 1036 destx = 0; 1037 } 1038 1039 if (desty < 0) { 1040 x11_window_height += desty; 1041 srcy = (short)((-desty) * yScaleFactor); 1042 desty = 0; 1043 } 1044 1045 /* display by overlay */ 1046 if (psb_xrandr_single_mode() || IS_MRST(driver_data)) { 1047 if ((destx + x11_window_width) > pPriv->display_width) { 1048 x11_window_width = pPriv->display_width - destx; 1049 srcw = (unsigned short)(x11_window_width * xScaleFactor); 1050 } 1051 1052 if ((desty + x11_window_height) > pPriv->display_height) { 1053 x11_window_height = pPriv->display_height - desty; 1054 srch = (unsigned short)(x11_window_height * yScaleFactor); 1055 } 1056 1057 if (!driver_data->overlay_auto_paint_color_key) { 1058 ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); 1059 if (ret != 0) { 1060 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to repaint color key error # %d\n", __func__, ret); 1061 return VA_STATUS_ERROR_UNKNOWN; 1062 } 1063 } 1064 1065 psb_putsurface_overlay( 1066 ctx, surface, srcx, srcy, srcw, srch, 1067 /* screen coordinate */ 1068 destx, desty, x11_window_width, x11_window_height, 1069 flags, OVERLAY_A, local_pipe); 1070 } else if (psb_xrandr_clone_mode()) { 1071 psb_overlay_rect_t local_rect, extend_rect; 1072 1073 if (output->extend_drawable) { 1074 XDestroyWindow(ctx->native_dpy, output->extend_drawable); 1075 output->extend_drawable = 0; 1076 XFreeGC((Display *)ctx->native_dpy, output->extend_gc); 1077 output->extend_gc = 0; 1078 } 1079 1080 if (((destx + x11_window_width) < pPriv->display_width) && 1081 ((destx + x11_window_width) < pPriv->extend_display_width)) 1082 local_rect.dWidth = extend_rect.dWidth = x11_window_width; 1083 else if (pPriv->display_width < pPriv->extend_display_width) { 1084 local_rect.dWidth = pPriv->display_width - destx; 1085 if ((destx + x11_window_width) > pPriv->extend_display_width) 1086 extend_rect.dWidth = x11_window_width = pPriv->extend_display_width - destx; 1087 else 1088 extend_rect.dWidth = x11_window_width; 1089 } else { 1090 extend_rect.dWidth = pPriv->extend_display_width - destx; 1091 if ((destx + x11_window_width) > pPriv->display_width) 1092 local_rect.dWidth = x11_window_width = pPriv->display_width - destx; 1093 else 1094 local_rect.dWidth = x11_window_width; 1095 } 1096 1097 if (((desty + x11_window_height) < pPriv->display_height) && 1098 ((desty + x11_window_height) < pPriv->extend_display_height)) 1099 local_rect.dHeight = extend_rect.dHeight = x11_window_height; 1100 else if (pPriv->display_height < pPriv->extend_display_height) { 1101 local_rect.dHeight = pPriv->display_height - desty; 1102 if ((desty + x11_window_height) > pPriv->extend_display_height) 1103 extend_rect.dHeight = x11_window_height = pPriv->extend_display_height - desty; 1104 else 1105 extend_rect.dHeight = x11_window_height; 1106 } else { 1107 extend_rect.dHeight = pPriv->extend_display_height - desty; 1108 if ((desty + x11_window_height) > pPriv->display_height) 1109 local_rect.dHeight = x11_window_height = pPriv->display_height - desty; 1110 else 1111 local_rect.dHeight = x11_window_height; 1112 } 1113 if ((driver_data->mipi0_rotation != VA_ROTATION_NONE) || 1114 (driver_data->hdmi_rotation != VA_ROTATION_NONE)) { 1115 local_rect.sWidth = srcw; 1116 local_rect.sHeight = srch; 1117 extend_rect.sWidth = srcw; 1118 extend_rect.sHeight = srch; 1119 } else { 1120 local_rect.sWidth = (unsigned short)(local_rect.dWidth * xScaleFactor); 1121 local_rect.sHeight = (unsigned short)(local_rect.dHeight * yScaleFactor); 1122 extend_rect.sWidth = (unsigned short)(extend_rect.dWidth * xScaleFactor); 1123 extend_rect.sHeight = (unsigned short)(extend_rect.dHeight * yScaleFactor); 1124 } 1125 ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); 1126 if (ret != 0) { 1127 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to repaint color key error # %d\n", __func__, ret); 1128 return VA_STATUS_ERROR_UNKNOWN; 1129 } 1130 psb_putsurface_overlay( 1131 ctx, surface, srcx, srcy, extend_rect.sWidth, extend_rect.sHeight, 1132 /* screen coordinate */ 1133 destx, desty, extend_rect.dWidth, extend_rect.dHeight, 1134 flags, OVERLAY_C, extend_pipe); 1135 psb_putsurface_overlay( 1136 ctx, surface, srcx, srcy, local_rect.sWidth, local_rect.sHeight, 1137 /* screen coordinate */ 1138 destx, desty, local_rect.dWidth, local_rect.dHeight, 1139 flags, OVERLAY_A, local_pipe); 1140 } else if (psb_xrandr_extend_mode()) { 1141 if (driver_data->extend_fullscreen) { 1142 switch (extend_location) { 1143 case RIGHT_OF: 1144 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, pPriv->display_width, 0, pPriv->extend_display_width, pPriv->extend_display_height); 1145 break; 1146 case BELOW: 1147 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, 0, pPriv->display_height, pPriv->extend_display_width, pPriv->extend_display_height); 1148 break; 1149 case LEFT_OF: 1150 case ABOVE: 1151 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, 0, 0, pPriv->extend_display_width, pPriv->extend_display_height); 1152 break; 1153 default: 1154 break; 1155 1156 } 1157 XSetForeground((Display *)ctx->native_dpy, output->gc, pPriv->colorKey); 1158 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, pPriv->extend_display_width, pPriv->extend_display_height); 1159 XFlush(ctx->native_dpy); 1160 1161 psb_putsurface_overlay( 1162 ctx, surface, srcx, srcy, srcw, srch, 1163 /* screen coordinate */ 1164 0, 0, pPriv->extend_display_width, pPriv->extend_display_height, 1165 flags, OVERLAY_A, PIPEB); 1166 } else { 1167 psb_overlay_rect_t local_rect, extend_rect; 1168 enum overlay_id_t extend_overlay = OVERLAY_C; 1169 1170 if (output->extend_drawable) { 1171 XDestroyWindow(ctx->native_dpy, output->extend_drawable); 1172 output->extend_drawable = 0; 1173 XFreeGC((Display *)ctx->native_dpy, output->extend_gc); 1174 output->extend_gc = 0; 1175 } 1176 memset(&local_rect, 0, sizeof(psb_overlay_rect_t)); 1177 memset(&extend_rect, 0, sizeof(psb_overlay_rect_t)); 1178 psb_extendMode_getCoordinate(pPriv, extend_location, destx, desty, srcx, srcy, 1179 xScaleFactor, yScaleFactor, &x11_window_width, &x11_window_height, 1180 &local_rect, &extend_rect, &extend_overlay); 1181 1182 ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); 1183 if (ret != 0) { 1184 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to repaint color key error # %d\n", __func__, ret); 1185 return VA_STATUS_ERROR_UNKNOWN; 1186 } 1187 1188 if ((extend_rect.dWidth > 0) && (extend_rect.dHeight > 0)) { 1189 psb_putsurface_overlay( 1190 ctx, surface, 1191 extend_rect.srcx, extend_rect.srcy, extend_rect.sWidth, extend_rect.sHeight, 1192 extend_rect.destx, extend_rect.desty, extend_rect.dWidth, extend_rect.dHeight, 1193 flags, extend_overlay, extend_pipe); 1194 } 1195 if ((local_rect.dWidth > 0) && (local_rect.dHeight > 0)) { 1196 psb_putsurface_overlay( 1197 ctx, surface, 1198 local_rect.srcx, local_rect.srcy, local_rect.sWidth, local_rect.sHeight, 1199 local_rect.destx, local_rect.desty, local_rect.dWidth, local_rect.dHeight, 1200 flags, OVERLAY_A, local_pipe); 1201 } 1202 } 1203 } else if (psb_xrandr_extvideo_mode()) { 1204 unsigned int xres, yres, xoffset, yoffset, overscanmode, pannelfitting, x, y; 1205 psb_extvideo_center center; 1206 1207 psb_xrandr_extvideo_prop(&xres, &yres, &xoffset, &yoffset, ¢er, &subtitle, &overscanmode, &pannelfitting); 1208 x = xoffset; 1209 y = yoffset; 1210 1211 switch (extend_location) { 1212 case RIGHT_OF: 1213 x += pPriv->display_width; 1214 break; 1215 case BELOW: 1216 y += pPriv->display_height; 1217 break; 1218 case NORMAL: 1219 break; 1220 case LEFT_OF: 1221 if (driver_data->xrandr_dirty & PSB_NEW_EXTVIDEO) { 1222 destx += pPriv->extend_display_width; 1223 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, destx, desty, x11_window_width, x11_window_height); 1224 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); 1225 XFlush(ctx->native_dpy); 1226 } 1227 destx = destx - pPriv->extend_display_width; 1228 break; 1229 case ABOVE: 1230 if (driver_data->xrandr_dirty & PSB_NEW_EXTVIDEO) { 1231 desty += pPriv->extend_display_height; 1232 XMoveResizeWindow(ctx->native_dpy, output->output_drawable, destx, desty, x11_window_width, x11_window_height); 1233 XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); 1234 XFlush(ctx->native_dpy); 1235 } 1236 desty = desty - pPriv->extend_display_height; 1237 break; 1238 } 1239 if ((destx + x11_window_width) > pPriv->display_width) 1240 x11_window_width = pPriv->display_width - destx; 1241 if ((desty + x11_window_height) > pPriv->display_height) 1242 x11_window_height = pPriv->display_height - desty; 1243 1244 if (driver_data->xrandr_dirty & PSB_NEW_EXTVIDEO) { 1245 Window extend_win; 1246 extend_win = psb_xrandr_create_full_screen_window(x, y, xres, yres); 1247 if (output->extend_drawable != extend_win) { 1248 output->extend_drawable = extend_win; 1249 if (output->extend_gc) 1250 XFreeGC((Display *)ctx->native_dpy, output->extend_gc); 1251 output->extend_gc = XCreateGC((Display *)ctx->native_dpy, extend_win, 0, NULL); 1252 1253 /* paint the color key */ 1254 if (!obj_surface->subpictures) { 1255 XSetForeground((Display *)ctx->native_dpy, output->extend_gc, pPriv->colorKey); 1256 XFillRectangle((Display *)ctx->native_dpy, extend_win, output->extend_gc, 0, 0, xres, yres); 1257 XSync((Display *)ctx->native_dpy, False); 1258 } 1259 } 1260 driver_data->xrandr_dirty &= ~PSB_NEW_EXTVIDEO; 1261 } 1262 1263 ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); 1264 if (ret != 0) { 1265 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: Failed to repaint color key error # %d\n", __func__, ret); 1266 return VA_STATUS_ERROR_UNKNOWN; 1267 } 1268 1269 psb_putsurface_overlay( 1270 ctx, surface, srcx, srcy, srcw, srch, 1271 /* screen coordinate */ 1272 xoffset, yoffset, xres, yres, 1273 flags, OVERLAY_C, PIPEB); 1274 psb_putsurface_overlay( 1275 ctx, surface, srcx, srcy, srcw, srch, 1276 /* screen coordinate */ 1277 destx, desty, 1278 x11_window_width, x11_window_height, 1279 flags, OVERLAY_A, local_pipe); 1280 } 1281 1282 /*Init Overlay subpicuture blending and make proper clear.*/ 1283 if (pPriv->is_mfld && obj_surface->subpictures) { 1284 PsbVASurfaceRec *subpicture = (PsbVASurfaceRec *)obj_surface->subpictures; 1285 1286 psb_init_subpicture(ctx, pPriv); 1287 /*clear changed subpicture zones in drawable.*/ 1288 psb_clear_subpictures(ctx, pPriv, x11_window_width, x11_window_height, obj_surface); 1289 if (pPriv->subpic_clear_flag) { 1290 psb_DisplayRGBASubpicture(subpicture, ctx, x11_window_width, x11_window_height, 1291 surfacex, surfacey, obj_surface->width, obj_surface->height, subtitle); 1292 } 1293 } 1294 1295 output->frame_count++; 1296 1297 return VA_STATUS_SUCCESS; 1298} 1299