amdgpu_video.c revision 24b90cf4
1 2#ifdef HAVE_CONFIG_H 3#include "config.h" 4#endif 5 6#include <stdlib.h> 7#include <string.h> 8#include <stdio.h> 9#include <math.h> 10 11#include "amdgpu_drv.h" 12#include "amdgpu_glamor.h" 13#include "amdgpu_probe.h" 14#include "amdgpu_video.h" 15#include "amdgpu_pixmap.h" 16 17#include "xf86.h" 18#include "dixstruct.h" 19 20/* DPMS */ 21#ifdef HAVE_XEXTPROTO_71 22#include <X11/extensions/dpmsconst.h> 23#else 24#define DPMS_SERVER 25#include <X11/extensions/dpms.h> 26#endif 27 28#include <X11/extensions/Xv.h> 29#include "fourcc.h" 30 31#define OFF_DELAY 250 /* milliseconds */ 32#define FREE_DELAY 15000 33 34#define OFF_TIMER 0x01 35#define FREE_TIMER 0x02 36#define CLIENT_VIDEO_ON 0x04 37 38static void amdgpu_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) 39{ 40 dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; 41 dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; 42 dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; 43 dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; 44 45 if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2) 46 dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; 47} 48 49static void amdgpu_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) 50{ 51 if (crtc->enabled) { 52 crtc_box->x1 = crtc->x; 53 crtc_box->x2 = 54 crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); 55 crtc_box->y1 = crtc->y; 56 crtc_box->y2 = 57 crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); 58 } else 59 crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; 60} 61 62static int amdgpu_box_area(BoxPtr box) 63{ 64 return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1); 65} 66 67Bool amdgpu_crtc_is_enabled(xf86CrtcPtr crtc) 68{ 69 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 70 return drmmode_crtc->dpms_mode == DPMSModeOn; 71} 72 73xf86CrtcPtr 74amdgpu_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled, 75 int x1, int x2, int y1, int y2) 76{ 77 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 78 int coverage, best_coverage, c, cd; 79 BoxRec box, crtc_box, cover_box; 80 RROutputPtr primary_output = NULL; 81 xf86CrtcPtr best_crtc = NULL, primary_crtc = NULL; 82 83 if (!pScrn->vtSema) 84 return NULL; 85 86 box.x1 = x1; 87 box.x2 = x2; 88 box.y1 = y1; 89 box.y2 = y2; 90 best_coverage = 0; 91 92 /* Prefer the CRTC of the primary output */ 93 if (dixPrivateKeyRegistered(rrPrivKey)) 94 { 95 primary_output = RRFirstOutput(pScrn->pScreen); 96 } 97 if (primary_output && primary_output->crtc) 98 primary_crtc = primary_output->crtc->devPrivate; 99 100 /* first consider only enabled CRTCs 101 * then on second pass consider disabled ones 102 */ 103 for (cd = 0; cd < (consider_disabled ? 2 : 1); cd++) { 104 for (c = 0; c < xf86_config->num_crtc; c++) { 105 xf86CrtcPtr crtc = xf86_config->crtc[c]; 106 107 if (!cd && !amdgpu_crtc_is_enabled(crtc)) 108 continue; 109 110 amdgpu_crtc_box(crtc, &crtc_box); 111 amdgpu_box_intersect(&cover_box, &crtc_box, &box); 112 coverage = amdgpu_box_area(&cover_box); 113 if (coverage > best_coverage || 114 (coverage == best_coverage && 115 crtc == primary_crtc)) { 116 best_crtc = crtc; 117 best_coverage = coverage; 118 } 119 } 120 if (best_crtc) 121 break; 122 } 123 124 return best_crtc; 125} 126 127void AMDGPUInitVideo(ScreenPtr pScreen) 128{ 129 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 130 AMDGPUInfoPtr info = AMDGPUPTR(pScrn); 131 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 132 XF86VideoAdaptorPtr texturedAdaptor = NULL; 133 int num_adaptors; 134 135 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 136 newAdaptors = 137 malloc((num_adaptors + 2) * sizeof(*newAdaptors)); 138 if (newAdaptors == NULL) 139 return; 140 141 memcpy(newAdaptors, adaptors, 142 num_adaptors * sizeof(XF86VideoAdaptorPtr)); 143 adaptors = newAdaptors; 144 145 if (info->use_glamor) { 146 texturedAdaptor = amdgpu_glamor_xv_init(pScreen, 16); 147 if (texturedAdaptor != NULL) { 148 adaptors[num_adaptors++] = texturedAdaptor; 149 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 150 "Set up textured video (glamor)\n"); 151 } else 152 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 153 "Failed to set up textured video (glamor)\n"); 154 } 155 156 if (num_adaptors) 157 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 158 159 if (newAdaptors) 160 free(newAdaptors); 161 162} 163