⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 overlay.c

📁 ati driver
💻 C
📖 第 1 页 / 共 3 页
字号:
	}		// get initial horizontal scaler values, taking care of precharge	// don't ask questions about formulas - take them as is	// (TBD: home-brewed sub-pixel source clipping may be wrong, 	//       especially for uv-planes)	{		uint32 p23_group_size;	    tmp = ((src_left & 0xffff) >> 11) + (	    	(		    	I2FF( p1_x_start % factors->group_size, 12 ) + 		    	I2FF( 2.5, 12 ) + 		    	p1_h_inc / 2 +		    	I2FF( 0.5, 12-5 )	// rounding	        ) >> (12 - 5));	// scaled by 1 << 5	        	    SHOW_FLOW( 3, "p1_h_accum_init=%x", tmp );			p1_h_accum_init = 			((tmp << 15) & RADEON_OV0_P1_H_ACCUM_INIT_MASK) |			((tmp << 23) & RADEON_OV0_P1_PRESHIFT_MASK);						p23_group_size = 2;				tmp = ((src_left & 0xffff) >> 11) + (			(				I2FF( p23_x_start % p23_group_size, 12 ) + 				I2FF( 2.5, 12 ) +				p23_h_inc / 2 +				I2FF( 0.5, 12-5 )	// rounding 			) >> (12 - 5)); // scaled by 1 << 5			SHOW_FLOW( 3, "p23_h_accum_init=%x", tmp );			p23_h_accum_init = 			((tmp << 15) & RADEON_OV0_P23_H_ACCUM_INIT_MASK) |			((tmp << 23) & RADEON_OV0_P23_PRESHIFT_MASK);	}	// get initial vertical scaler values, taking care of precharge	{		uint extra_full_line;		extra_full_line = factors->p1_step_by == 0 ? 1 : 0;		    tmp = ((src_top & 0x0000ffff) >> 11) + (	    	(min( 		    	I2FF( 1.5, 20 ) + I2FF( extra_full_line, 20 ) + v_inc / 2, 	    		I2FF( 2.5, 20 ) + 2 * I2FF( extra_full_line, 20 )	    	 ) + I2FF( 0.5, 20-5 )) // rounding	    	>> (20 - 5)); // scaled by 1 << 5	    		    SHOW_FLOW( 3, "p1_v_accum_init=%x", tmp );			p1_v_accum_init = 			((tmp << 15) & RADEON_OV0_P1_V_ACCUM_INIT_MASK) | 0x00000001;			extra_full_line = factors->p23_step_by == 0 ? 1 : 0;			if( params->v_uv_sub_sample_shift > 0 ) {			tmp = ((src_top & 0x0000ffff) >> 11) + (				(min( 					I2FF( 1.5, 20 ) + 						I2FF( extra_full_line, 20 ) + 						((v_inc / 2) >> params->v_uv_sub_sample_shift), 					I2FF( 2.5, 20 ) + 						2 * I2FF( extra_full_line, 20 )				 ) + I2FF( 0.5, 20-5 )) // rounding				>> (20 - 5)); // scaled by 1 << 5		} else {			tmp = ((src_top & 0x0000ffff) >> 11) + (				(					I2FF( 2.5, 20 ) + 					2 * I2FF( extra_full_line, 20 ) +					I2FF( 0.5, 20-5 )	// rounding				) >> (20 - 5)); // scaled by 1 << 5		}				SHOW_FLOW( 3, "p23_v_accum_init=%x", tmp );			p23_v_accum_init = 			((tmp << 15) & RADEON_OV0_P23_V_ACCUM_INIT_MASK) | 0x00000001;			}	// show me what you've got!	// we could lock double buffering of overlay unit during update	// (new values are copied during vertical blank, so if we've updated	// only some of them, you get a whole frame of mismatched values)	// but during tests I couldn't get the artifacts go away, so	// we use the dangerous way which has the pro to not require any	// waiting		// let's try to lock overlay unit	// we had to wait now until the lock takes effect, but this is	// impossible with CCE; perhaps we have to convert this code to 	// direct register access; did that - let's see what happens...	OUTREG( regs, RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK );		// wait until register access is locked	while( (INREG( regs, RADEON_OV0_REG_LOAD_CNTL) 		& RADEON_REG_LD_CTL_LOCK_READBACK) == 0 )		;		OUTREG( regs, RADEON_OV0_VID_BUF0_BASE_ADRS, offset );	OUTREG( regs, RADEON_OV0_VID_BUF_PITCH0_VALUE, node->buffer.bytes_per_row );	OUTREG( regs, RADEON_OV0_H_INC, p1_h_inc | (p23_h_inc << 16) );	OUTREG( regs, RADEON_OV0_STEP_BY, factors->p1_step_by | (factors->p23_step_by << 8) );	OUTREG( regs, RADEON_OV0_V_INC, v_inc );		OUTREG( regs,		crtc->crtc_idx == 0 ? RADEON_OV0_Y_X_START : RADEON_OV1_Y_X_START, 		(dest_left) | (dest_top << 16) );	OUTREG( regs, 		crtc->crtc_idx == 0 ? RADEON_OV0_Y_X_END : RADEON_OV1_Y_X_END,		(dest_right - 1) | ((dest_bottom - 1) << 16) );	OUTREG( regs, RADEON_OV0_P1_BLANK_LINES_AT_TOP, 		RADEON_P1_BLNK_LN_AT_TOP_M1_MASK | (p1_active_lines << 16) );	OUTREG( regs, RADEON_OV0_P1_X_START_END, p1_x_end | (p1_x_start << 16) );	OUTREG( regs, RADEON_OV0_P1_H_ACCUM_INIT, p1_h_accum_init );	OUTREG( regs, RADEON_OV0_P1_V_ACCUM_INIT, p1_v_accum_init );		OUTREG( regs, RADEON_OV0_P23_BLANK_LINES_AT_TOP, 		RADEON_P23_BLNK_LN_AT_TOP_M1_MASK | (p23_active_lines << 16) );	OUTREG( regs, RADEON_OV0_P2_X_START_END, 		p23_x_end | (p23_x_start << 16) );	OUTREG( regs, RADEON_OV0_P3_X_START_END, 		p23_x_end | (p23_x_start << 16) );	OUTREG( regs, RADEON_OV0_P23_H_ACCUM_INIT, p23_h_accum_init );	OUTREG( regs, RADEON_OV0_P23_V_ACCUM_INIT, p23_v_accum_init );		OUTREG( regs, RADEON_OV0_TEST, node->test_reg );	OUTREG( regs, RADEON_OV0_SCALE_CNTL, 		RADEON_SCALER_ENABLE | 		RADEON_SCALER_DOUBLE_BUFFER | 		(node->ati_space << 8) | 		/*RADEON_SCALER_ADAPTIVE_DEINT |*/ 		(crtc->crtc_idx == 0 ? 0 : RADEON_SCALER_CRTC_SEL ));		si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;		OUTREG( regs, RADEON_OV0_AUTO_FLIP_CNTRL, 		si->overlay_mgr.auto_flip_reg );		OUTREG( regs, RADEON_OV0_REG_LOAD_CNTL, 0 );	done:	ai->si->active_overlay.on = ai->si->pending_overlay.on;	ai->si->active_overlay.ow = ai->si->pending_overlay.ow;	ai->si->active_overlay.ov = ai->si->pending_overlay.ov;	ai->si->active_overlay.ob = ai->si->pending_overlay.ob;	ai->si->active_overlay.h_display_start = vc->mode.h_display_start;	ai->si->active_overlay.v_display_start = vc->mode.v_display_start;	return B_OK;}// hide overlay, but not permanentlyvoid Radeon_TempHideOverlay( 	accelerator_info *ai ){	SHOW_FLOW0( 3, "" );	OUTREG( ai->regs, RADEON_OV0_SCALE_CNTL, 0 );}// hide overlay (can be called even if there is none visible)void Radeon_HideOverlay( 	accelerator_info *ai ){	shared_info *si = ai->si;		Radeon_TempHideOverlay( ai );	// remember that there is no overlay to be shown		si->active_overlay.on = NULL;	si->active_overlay.prev_on = NULL;	si->pending_overlay.on = NULL;		// invalidate active head so it will be setup again once	// a new overlay is shown	si->active_overlay.crtc_idx = -1;}// show new overlay buffer with same parameters as last onestatic void Radeon_ReplaceOverlayBuffer( 	accelerator_info *ai ){#if 0	shared_info *si = ai->si;	vuint8 *regs = ai->regs;	uint32 offset;	int /*old_buf, */new_buf;		offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;	/*old_buf = si->overlay_mgr.auto_flip_reg & RADEON_OV0_SOFT_BUF_NUM_MASK;	new_buf = old_buf == 0 ? 3 : 0;	si->overlay_mgr.auto_flip_reg &= ~RADEON_OV0_SOFT_BUF_NUM_MASK;	si->overlay_mgr.auto_flip_reg |= new_buf;*/	new_buf = 0;		// lock overlay registers/*	OUTREG( regs, RADEON_OV0_REG_LOAD_CNTL, RADEON_REG_LD_CTL_LOCK );		// wait until register access is locked	while( (INREG( regs, RADEON_OV0_REG_LOAD_CNTL) 		& RADEON_REG_LD_CTL_LOCK_READBACK) == 0 )		;*/		// setup new buffer	/*OUTREG( regs, 		new_buf == 0 ? RADEON_OV0_VID_BUF_PITCH0_VALUE : RADEON_OV0_VID_BUF_PITCH1_VALUE, 		si->pending_overlay.on->buffer.bytes_per_row );*/	OUTREG( regs, 		new_buf == 0 ? RADEON_OV0_VID_BUF0_BASE_ADRS : RADEON_OV0_VID_BUF3_BASE_ADRS, 		offset | (new_buf == 0 ? 0 : RADEON_VIF_BUF0_PITCH_SEL));		// make changes visible		si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;		OUTREG( regs, RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );		// unlock overlay registers//	OUTREG( regs, RADEON_OV0_REG_LOAD_CNTL, 0 );	ai->si->active_overlay.on = ai->si->pending_overlay.on;#else	shared_info *si = ai->si;	uint32 offset;		START_IB();	offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;		WRITE_IB_REG( RADEON_OV0_VID_BUF0_BASE_ADRS, offset);		si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;	WRITE_IB_REG( RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );		SUBMIT_IB();		ai->si->active_overlay.on = ai->si->pending_overlay.on;#endif}// get number of pixels of overlay shown on virtual portstatic int getIntersectArea( 	accelerator_info *ai, overlay_window *ow, crtc_info *crtc ){	virtual_card *vc = ai->vc;	int left, top, right, bottom;		left = ow->h_start - (vc->mode.h_display_start + crtc->rel_x);	top = ow->v_start - (vc->mode.v_display_start + crtc->rel_y);	right = left + ow->width;	bottom = top + ow->height;		if( left < 0 )		left = 0;	if( top < 0 )		top = 0;	if( right > crtc->mode.timing.h_display )		right = crtc->mode.timing.h_display;	if( bottom > crtc->mode.timing.v_display )		bottom = crtc->mode.timing.v_display;			if( right < left || bottom < top )		return 0;			return (right - left) * (bottom - top);}// update overlay, to be called whenever something in terms of // overlay have or can have been changedstatus_t Radeon_UpdateOverlay( 	accelerator_info *ai ){	virtual_card *vc = ai->vc;	shared_info *si = ai->si;	int crtc_idx;		float brightness = 0.0f;	float contrast = 1.0f;	float saturation = 1.0f;	float hue = 0.0f;    int32 ref = 0;        SHOW_FLOW0( 3, "" );	// don't mess around with overlay of someone else        if( !vc->uses_overlay )    	return B_OK;	// make sure there really is an overlay	if( si->pending_overlay.on == NULL )		return B_OK;	// verify that the overlay is still valid	if( (uint32)si->pending_overlay.ot != si->overlay_mgr.token )		return B_BAD_VALUE;			if( vc->different_heads > 1 ) {		int area0, area1;		// determine on which port most of the overlay is shown		area0 = getIntersectArea( ai, &si->pending_overlay.ow, &si->crtc[0] );		area1 = getIntersectArea( ai, &si->pending_overlay.ow, &si->crtc[0] );				SHOW_FLOW( 3, "area0=%d, area1=%d", area0, area1 );				if( area0 >= area1 )			crtc_idx = 0;		else			crtc_idx = 1;				} else if( vc->independant_heads > 1 ) {		// both ports show the same, use "swap displays" to decide		// where to show the overlay (to be improved as this flag isn't		// really designed for that)		if( vc->swap_displays )			crtc_idx = 1;		else			crtc_idx = 0;				} else {			// one crtc used only - pick the one that we use		crtc_idx = vc->used_crtc[0] ? 0 : 1;	}		si->pending_overlay.crtc_idx = crtc_idx;	// only update registers that have been changed to minimize work	if( si->active_overlay.crtc_idx != si->pending_overlay.crtc_idx ) {		Radeon_InitOverlay( ai, crtc_idx );	} 		if( si->active_overlay.ob.space != si->pending_overlay.ob.space ) {		Radeon_SetTransform( ai, brightness, contrast, saturation, hue, 0, 0, 0, ref );	}	if( memcmp( &si->active_overlay.ow, &si->pending_overlay.ow, sizeof( si->active_overlay.ow )) != 0 || 		memcmp( &si->active_overlay.ov, &si->pending_overlay.ov, sizeof( si->active_overlay.ov )) != 0 ||		si->active_overlay.h_display_start != vc->mode.h_display_start ||		si->active_overlay.v_display_start != vc->mode.v_display_start ||		si->active_overlay.ob.width != si->pending_overlay.ob.width ||		si->active_overlay.ob.height != si->pending_overlay.ob.height ||		si->active_overlay.ob.bytes_per_row != si->pending_overlay.ob.bytes_per_row )		Radeon_ShowOverlay( ai, crtc_idx );			else if( si->active_overlay.on != si->pending_overlay.on )		Radeon_ReplaceOverlayBuffer( ai );			SHOW_FLOW0( 3, "success" );		return B_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -