📄 radeon_video.c
字号:
OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18))); } info->adaptor = adapt; return adapt;}static XF86VideoAdaptorPtrRADEONSetupImageVideo(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONPortPrivPtr pPriv; XF86VideoAdaptorPtr adapt; if(!(adapt = RADEONAllocAdaptor(pScrn))) return NULL; adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; adapt->name = "ATI Radeon Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = &DummyEncoding; adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = 1; adapt->nAttributes = NUM_ATTRIBUTES; adapt->pAttributes = Attributes; adapt->nImages = NUM_IMAGES; adapt->pImages = Images; adapt->PutVideo = NULL; adapt->PutStill = NULL; adapt->GetVideo = NULL; adapt->GetStill = NULL; adapt->StopVideo = RADEONStopVideo; adapt->SetPortAttribute = RADEONSetPortAttribute; adapt->GetPortAttribute = RADEONGetPortAttribute; adapt->QueryBestSize = RADEONQueryBestSize; adapt->PutImage = RADEONPutImage; adapt->QueryImageAttributes = RADEONQueryImageAttributes; pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr); REGION_INIT(pScreen, &(pPriv->clip), NullBox, 0); xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); xvSaturation = MAKE_ATOM("XV_SATURATION"); xvColor = MAKE_ATOM("XV_COLOR"); xvContrast = MAKE_ATOM("XV_CONTRAST"); xvColorKey = MAKE_ATOM("XV_COLORKEY"); xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); xvHue = MAKE_ATOM("XV_HUE"); xvRedIntensity = MAKE_ATOM("XV_RED_INTENSITY"); xvGreenIntensity = MAKE_ATOM("XV_GREEN_INTENSITY"); xvBlueIntensity = MAKE_ATOM("XV_BLUE_INTENSITY"); xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); RADEONResetVideo(pScrn); return adapt;}static voidRADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup){ RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; REGION_EMPTY(pScrn->pScreen, &pPriv->clip); if(cleanup) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_OV0_SCALE_CNTL, 0); } if(info->videoLinear) { xf86FreeOffscreenLinear(info->videoLinear); info->videoLinear = NULL; } pPriv->videoStatus = 0; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { pPriv->videoStatus |= OFF_TIMER; pPriv->offTime = currentTime.milliseconds + OFF_DELAY; } }}static intRADEONSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data){ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; Bool setTransform = FALSE; info->accel->Sync(pScrn);#define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0)#define RTFBrightness(a) (((a)*1.0)/2000.0)#define RTFIntensity(a) (((a)*1.0)/2000.0)#define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0)#define RTFHue(a) (((a)*3.1416)/1000.0)#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) if(attribute == xvAutopaintColorkey) { pPriv->autopaint_colorkey = ClipValue (value, 0, 1); } else if(attribute == xvSetDefaults) { pPriv->autopaint_colorkey = TRUE; pPriv->brightness = 0; pPriv->saturation = 0; pPriv->contrast = 0; pPriv->hue = 0; pPriv->red_intensity = 0; pPriv->green_intensity = 0; pPriv->blue_intensity = 0; pPriv->doubleBuffer = FALSE; setTransform = TRUE; } else if(attribute == xvBrightness) { pPriv->brightness = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if((attribute == xvSaturation) || (attribute == xvColor)) { pPriv->saturation = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if(attribute == xvContrast) { pPriv->contrast = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if(attribute == xvHue) { pPriv->hue = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if(attribute == xvRedIntensity) { pPriv->red_intensity = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if(attribute == xvGreenIntensity) { pPriv->green_intensity = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if(attribute == xvBlueIntensity) { pPriv->blue_intensity = ClipValue (value, -1000, 1000); setTransform = TRUE; } else if(attribute == xvDoubleBuffer) { pPriv->doubleBuffer = ClipValue (value, 0, 1); pPriv->doubleBuffer = value; } else if(attribute == xvColorKey) { pPriv->colorKey = value; RADEONSetColorKey (pScrn, pPriv->colorKey); REGION_EMPTY(pScrn->pScreen, &pPriv->clip); } else return BadMatch; if (setTransform) { RADEONSetTransform(pScrn, RTFBrightness(pPriv->brightness), RTFContrast(pPriv->contrast), RTFSaturation(pPriv->saturation), RTFHue(pPriv->hue), RTFIntensity(pPriv->red_intensity), RTFIntensity(pPriv->green_intensity), RTFIntensity(pPriv->blue_intensity), pPriv->transform_index); } return Success;}static intRADEONGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data){ RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; if (info->accelOn) info->accel->Sync(pScrn); if(attribute == xvAutopaintColorkey) *value = pPriv->autopaint_colorkey; else if(attribute == xvBrightness) *value = pPriv->brightness; else if((attribute == xvSaturation) || (attribute == xvColor)) *value = pPriv->saturation; else if(attribute == xvContrast) *value = pPriv->contrast; else if(attribute == xvHue) *value = pPriv->hue; else if(attribute == xvRedIntensity) *value = pPriv->red_intensity; else if(attribute == xvGreenIntensity) *value = pPriv->green_intensity; else if(attribute == xvBlueIntensity) *value = pPriv->blue_intensity; else if(attribute == xvDoubleBuffer) *value = pPriv->doubleBuffer ? 1 : 0; else if(attribute == xvColorKey) *value = pPriv->colorKey; else return BadMatch; return Success;}static voidRADEONQueryBestSize( ScrnInfoPtr pScrn, Bool motion, short vid_w, short vid_h, short drw_w, short drw_h, unsigned int *p_w, unsigned int *p_h, pointer data){ if(vid_w > (drw_w << 4)) drw_w = vid_w >> 4; if(vid_h > (drw_h << 4)) drw_h = vid_h >> 4; *p_w = drw_w; *p_h = drw_h;}static voidRADEONCopyData( unsigned char *src, unsigned char *dst, int srcPitch, int dstPitch, int h, int w){ w <<= 1; while(h--) { memcpy(dst, src, w); src += srcPitch; dst += dstPitch; }}static voidRADEONCopyMungedData( unsigned char *src1, unsigned char *src2, unsigned char *src3, unsigned char *dst1, int srcPitch, int srcPitch2, int dstPitch, int h, int w){ CARD32 *dst; CARD8 *s1, *s2, *s3; int i, j; w >>= 1; for(j = 0; j < h; j++) { dst = (pointer)dst1; s1 = src1; s2 = src2; s3 = src3; i = w; while(i > 4) { dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24); dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24); dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24); dst += 4; s2 += 4; s3 += 4; s1 += 8; i -= 4; } while(i--) { dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); dst++; s2++; s3++; s1 += 2; } dst1 += dstPitch; src1 += srcPitch; if(j & 1) { src2 += srcPitch2; src3 += srcPitch2; } }}static FBLinearPtrRADEONAllocateMemory( ScrnInfoPtr pScrn, FBLinearPtr linear, int size){ ScreenPtr pScreen; FBLinearPtr new_linear; if(linear) { if(linear->size >= size) return linear; if(xf86ResizeOffscreenLinear(linear, size)) return linear; xf86FreeOffscreenLinear(linear); } pScreen = screenInfo.screens[pScrn->scrnIndex]; new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL, NULL, NULL); if(!new_linear) { int max_size; xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, PRIORITY_EXTREME); if(max_size < size) return NULL; xf86PurgeUnlockedOffscreenAreas(pScreen); new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, NULL, NULL, NULL); } return new_linear;}static voidRADEONDisplayVideo( ScrnInfoPtr pScrn, int id, int offset1, int offset2, short width, short height, int pitch, int left, int right, int top, BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h){ RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; int v_inc, h_inc, step_by, tmp; int p1_h_accum_init, p23_h_accum_init; int p1_v_accum_init; int ecp_div; int v_inc_shift; int y_mult; int x_off; CARD32 scaler_src; /* Unlike older Mach64 chips, RADEON has only two ECP settings: 0 for PIXCLK < 175Mhz, and 1 (divide by 2) for higher clocks, sure makes life nicer Here we need to find ecp_div again, as the user may have switched resolutions */ if(info->ModeReg.dot_clock_freq < 17500) ecp_div = 0; else ecp_div = 1; OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8)); v_inc_shift = 20; if (pScrn->currentMode->Flags & V_INTERLACE) v_inc_shift++; if (pScrn->currentMode->Flags & V_DBLSCAN) v_inc_shift--; if (pScrn->currentMode->Flags & RADEON_USE_RMX) { v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h; } else { v_inc = (src_h << v_inc_shift) / drw_h; } h_inc = ((src_w << (12 + ecp_div)) / drw_w); step_by = 1; while(h_inc >= (2 << 12)) { step_by++; h_inc >>= 1; } /* keep everything in 16.16 */ offset1 += ((left >> 16) & ~7) << 1; offset2 += ((left >> 16) & ~7) << 1; if (info->IsSecondary) { offset1 += info->FbMapSize; offset2 += info->FbMapSize; } tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); p1_h_accum_init = ((tmp << 4) & 0x000f8000) | ((tmp << 12) & 0xf0000000); tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); p23_h_accum_init = ((tmp << 4) & 0x000f8000) | ((tmp << 12) & 0x70000000); tmp = (top & 0x0000ffff) + 0x00018000; p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001; left = (left >> 16) & 7; RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_OV0_REG_LOAD_CNTL, 1); if (info->accelOn) info->accel->Sync(pScrn); while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & (1 << 3))); RADEONWaitForFifo(pScrn, 14); OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc >> 1) << 16)); OUTREG(RADEON_OV0_STEP_BY, step_by | (step_by << 8)); y_mult = 1; if (pScrn->currentMode->Flags & V_DBLSCAN) y_mult = 2; x_off = 8; if ((info->ChipFamily == CHIP_FAMILY_R300) || (info->ChipFamily == CHIP_FAMILY_R350) || (info->ChipFamily == CHIP_FAMILY_RV350) || (info->ChipFamily == CHIP_FAMILY_R200)) x_off = 0; /* Put the hardware overlay on CRTC2: * * Since one hardware overlay can not be displayed on two heads * at the same time, we might need to consider using software * rendering for the second head. */ if ((info->Clone && info->OverlayOnCRTC2) || info->IsSecondary) { x_off = 0; OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off - info->CloneFrameX0 + pScrn->frameX0) | ((dstBox->y1*y_mult - info->CloneFrameY0 + pScrn->frameY0) << 16))); OUTREG(RADEON_OV1_Y_X_END, ((dstBox->x2 + x_off - info->CloneFrameX0 + pScrn->frameX0) | ((dstBox->y2*y_mult - info->CloneFrameY0 + pScrn->frameY0) << 16))); scaler_src = (1 << 14); } else { OUTREG(RADEON_OV0_Y_X_START, ((dstBox->x1 + x_off) | ((dstBox->y1*y_mult) << 16))); OUTREG(RADEON_OV0_Y_X_END, ((dstBox->x2 + x_off) | ((dstBox->y2*y_mult) << 16))); scaler_src = 0; } OUTREG(RADEON_OV0_V_INC, v_inc); OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16)); OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE, pitch); OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE, pitch); OUTREG(RADEON_OV0_P1_X_START_END, (src_w + left - 1) | (left << 16)); left >>= 1; src_w >>= 1; OUTREG(RADEON_OV0_P2_X_START_END, (src_w + left - 1) | (left << 16)); OUTREG(RADEON_OV0_P3_X_START_END, (src_w + left - 1) | (left << 16)); OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS, offset1 & 0xfffffff0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -