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

📄 render2d.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
Bool R2D_IsPixelMetrics(GF_Node *n){	GF_SceneGraph *sg = gf_node_get_graph(n);	return gf_sg_use_pixel_metrics(sg);}static GF_Err R2D_RecomputeAR(GF_VisualRenderer *vr){	Double ratio;	GF_Event evt;	u32 out_width, out_height;	Fixed scaleX, scaleY;	Render2D *sr = (Render2D *)vr->user_priv;	if (!sr->compositor->scene_height || !sr->compositor->scene_width) return GF_OK;	if (!sr->compositor->height || !sr->compositor->width) return GF_OK;	sr->cur_width = sr->compositor->scene_width;	sr->cur_height = sr->compositor->scene_height;	sr->offset_x = sr->offset_y = 0;	/*force complete clean*/	sr->top_effect->invalidate_all = 1;	if (!sr->compositor->has_size_info && !(sr->compositor->override_size_flags & 2) ) {		sr->cur_width = sr->compositor->width;		sr->cur_height = sr->compositor->height;		R2D_SetScaling(sr, FIX_ONE, FIX_ONE);		/*and resize hardware surface*/		evt.type = GF_EVENT_VIDEO_SETUP;		evt.size.width = sr->cur_width;		evt.size.height = sr->cur_height;		return sr->compositor->video_out->ProcessEvent(sr->compositor->video_out, &evt);	}	out_width = sr->compositor->width;	out_height = sr->compositor->height;	switch (sr->compositor->aspect_ratio) {	case GF_ASPECT_RATIO_FILL_SCREEN:		break;	case GF_ASPECT_RATIO_16_9:		out_width = sr->compositor->width;		out_height = 9 * sr->compositor->width / 16;		if (out_height>sr->compositor->height) {			out_height = sr->compositor->height;			out_width = 16 * sr->compositor->height / 9;		}		break;	case GF_ASPECT_RATIO_4_3:		out_width = sr->compositor->width;		out_height = 3 * sr->compositor->width / 4;		if (out_height>sr->compositor->height) {			out_height = sr->compositor->height;			out_width = 4 * sr->compositor->height / 3;		}		break;	default:		ratio = sr->compositor->scene_height;		ratio /= sr->compositor->scene_width;		if (out_width * ratio > out_height) {			out_width = out_height * sr->compositor->scene_width;			out_width /= sr->compositor->scene_height;		}		else {			out_height = out_width * sr->compositor->scene_height;			out_height /= sr->compositor->scene_width;		}		break;	}	sr->offset_x = (sr->compositor->width - out_width) / 2;	sr->offset_y = (sr->compositor->height - out_height) / 2;	scaleX = gf_divfix(INT2FIX(out_width), INT2FIX(sr->compositor->scene_width));	scaleY = gf_divfix(INT2FIX(out_height), INT2FIX(sr->compositor->scene_height));	if (!sr->scalable_zoom) {		sr->cur_width = sr->compositor->scene_width;		sr->cur_height = sr->compositor->scene_height;		out_width = FIX2INT(gf_divfix(INT2FIX(sr->compositor->width), scaleX));		out_height = FIX2INT(gf_divfix(INT2FIX(sr->compositor->height), scaleY));		sr->offset_x = (out_width - sr->cur_width) / 2;		sr->offset_y = (out_height - sr->cur_height) / 2;		scaleX = scaleY = FIX_ONE;	} else {		sr->cur_width = out_width;		sr->cur_height = out_height;		out_width = sr->compositor->width;		out_height = sr->compositor->height;	}	/*set scale factor*/	R2D_SetScaling(sr, scaleX, scaleY);	gf_sr_invalidate(sr->compositor, NULL);	/*and resize hardware surface*/	evt.type = GF_EVENT_VIDEO_SETUP;	evt.size.width = out_width;	evt.size.height = out_height;	return sr->compositor->video_out->ProcessEvent(sr->compositor->video_out, &evt);}GF_Node *R2D_PickNode(GF_VisualRenderer *vr, s32 X, s32 Y){	GF_Node *res = NULL;	Render2D *sr = (Render2D *)vr->user_priv;	if (!sr) return NULL;	/*lock to prevent any change while picking*/	gf_sr_lock(sr->compositor, 1);	if (sr->compositor->scene) {		R2D_MapCoordsToAR(sr, &X, &Y);		res = VS2D_PickNode(sr->surface, INT2FIX(X), INT2FIX(Y) );	}	gf_sr_lock(sr->compositor, 0);	return res;}GF_Err R2D_GetSurfaceAccess(VisualSurface2D *surf){	GF_Err e;	Render2D *sr = surf->render;	if (!surf->the_surface) return GF_BAD_PARAM;	sr->locked = 0;	e = GF_IO_ERR;		/*try from device*/	if (sr->compositor->r2d->surface_attach_to_device && sr->compositor->video_out->LockOSContext) {		sr->hardware_context = sr->compositor->video_out->LockOSContext(sr->compositor->video_out, 1);		if (sr->hardware_context) {			e = sr->compositor->r2d->surface_attach_to_device(surf->the_surface, sr->hardware_context, sr->cur_width, sr->cur_height);			if (!e) {				surf->is_attached = 1;				GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render2D] Video surface handle attached to raster\n"));				return GF_OK;			}			sr->compositor->video_out->LockOSContext(sr->compositor->video_out, 0);			GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Render2D] Cannot attach video surface handle to raster: %s\n", gf_error_to_string(e) ));		}	}		/*TODO - collect hw accelerated blit routines if any*/	if (sr->compositor->video_out->LockBackBuffer(sr->compositor->video_out, &sr->hw_surface, 1)==GF_OK) {		sr->locked = 1;		e = sr->compositor->r2d->surface_attach_to_buffer(surf->the_surface, sr->hw_surface.video_buffer, 							sr->hw_surface.width, 							sr->hw_surface.height,							sr->hw_surface.pitch,							(GF_PixelFormat) sr->hw_surface.pixel_format);		if (!e) {			surf->is_attached = 1;			GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render2D] Video surface memory attached to raster\n"));			return GF_OK;		}		GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Render2D] Cannot attach video surface memory to raster: %s\n", gf_error_to_string(e) ));		sr->compositor->video_out->LockBackBuffer(sr->compositor->video_out, &sr->hw_surface, 0);	}	sr->locked = 0;	surf->is_attached = 0;	return e;		}void R2D_ReleaseSurfaceAccess(VisualSurface2D *surf){	Render2D *sr = surf->render;	if (surf->is_attached) {		sr->compositor->r2d->surface_detach(surf->the_surface);		surf->is_attached = 0;	}	if (sr->hardware_context) {		sr->compositor->video_out->LockOSContext(sr->compositor->video_out, 0);		sr->hardware_context = NULL;	} else if (sr->locked) {		sr->compositor->video_out->LockBackBuffer(sr->compositor->video_out, &sr->hw_surface, 0);		sr->locked = 0;	}}Bool R2D_SupportsFormat(VisualSurface2D *surf, u32 pixel_format){	switch (pixel_format) {	case GF_PIXEL_RGB_24:	case GF_PIXEL_BGR_24:	case GF_PIXEL_RGB_555:	case GF_PIXEL_RGB_565:	case GF_PIXEL_ARGB:	case GF_PIXEL_RGBA:	case GF_PIXEL_YV12:	case GF_PIXEL_IYUV:	case GF_PIXEL_I420:		return 1;	/*the rest has to be displayed through brush for now, we only use YUV and RGB pool*/	default:		return 0;	}}void R2D_DrawBitmap(VisualSurface2D *surf, struct _gf_sr_texture_handler *txh, GF_IRect *clip, GF_Rect *unclip, u8 alpha, u32 *col_key, GF_ColorMatrix *cmat){	GF_VideoSurface video_src;	Fixed w_scale, h_scale, tmp;	GF_Err e;	Bool use_soft_stretch;	GF_Window src_wnd, dst_wnd;	u32 start_x, start_y, cur_width, cur_height;	GF_IRect clipped_final = *clip;	GF_Rect final = *unclip;	if (!txh->data) return;	if (!surf->render->compositor->has_size_info && !(surf->render->compositor->msg_type & GF_SR_CFG_OVERRIDE_SIZE) 		&& (surf->render->compositor->override_size_flags & 1) 		&& !(surf->render->compositor->override_size_flags & 2) 		) {		if ( (surf->render->compositor->scene_width < txh->width) 			|| (surf->render->compositor->scene_height < txh->height)) {			surf->render->compositor->scene_width = txh->width;			surf->render->compositor->scene_height = txh->height;			surf->render->compositor->msg_type |= GF_SR_CFG_OVERRIDE_SIZE;			return;		}	}		/*this should never happen but we check for float rounding safety*/	if (final.width<=0 || final.height <=0) return;	w_scale = final.width / txh->width;	h_scale = final.height / txh->height;	/*take care of pixel rounding for odd width/height and make sure we strictly draw in the clipped bounds*/	cur_width = surf->render->cur_width;	cur_height = surf->render->cur_height;	if (surf->center_coords) {		if (cur_width % 2) {			clipped_final.x += (cur_width-1) / 2;			final.x += INT2FIX( (cur_width-1) / 2 );		} else {			clipped_final.x += cur_width / 2;			final.x += INT2FIX( cur_width / 2 );		}		if (cur_height % 2) {			clipped_final.y = (cur_height-1) / 2 - clipped_final.y;			final.y = INT2FIX( (cur_height - 1) / 2) - final.y;		} else {			clipped_final.y = cur_height/ 2 - clipped_final.y;			final.y = INT2FIX( cur_height / 2) - final.y;		}	} else {		final.x -= surf->render->offset_x;		clipped_final.x -= surf->render->offset_x;		final.y -= surf->render->offset_y + final.height;		clipped_final.y -= surf->render->offset_y + clipped_final.height;	}	/*make sure we lie in the final rect (this is needed for directRender mode)*/	if (clipped_final.x<0) {		clipped_final.width += clipped_final.x;		clipped_final.x = 0;		if (clipped_final.width <= 0) return;	}	if (clipped_final.y<0) {		clipped_final.height += clipped_final.y;		clipped_final.y = 0;		if (clipped_final.height <= 0) return;	}	if (clipped_final.x + clipped_final.width > (s32) cur_width) {		clipped_final.width = cur_width - clipped_final.x;		clipped_final.x = cur_width - clipped_final.width;	}	if (clipped_final.y + clipped_final.height > (s32) cur_height) {		clipped_final.height = cur_height - clipped_final.y;		clipped_final.y = cur_height - clipped_final.height;	}	/*needed in direct rendering since clipping is not performed*/	if (clipped_final.width<=0 || clipped_final.height <=0) 		return;	/*compute X offset in src bitmap*/	start_x = 0;	tmp = INT2FIX(clipped_final.x);	if (tmp >= final.x)		start_x = FIX2INT( gf_divfix(tmp - final.x, w_scale) );	/*compute Y offset in src bitmap*/	start_y = 0;	tmp = INT2FIX(clipped_final.y);	if (tmp >= final.y)		start_y = FIX2INT( gf_divfix(tmp - final.y, h_scale) );		/*add AR offset */	clipped_final.x += surf->render->offset_x;	clipped_final.y += surf->render->offset_y;	dst_wnd.x = (u32) clipped_final.x;	dst_wnd.y = (u32) clipped_final.y;	dst_wnd.w = (u32) clipped_final.width;	dst_wnd.h = (u32) clipped_final.height;	src_wnd.w = FIX2INT( gf_divfix(INT2FIX(dst_wnd.w), w_scale) );	src_wnd.h = FIX2INT( gf_divfix(INT2FIX(dst_wnd.h), h_scale) );	if (src_wnd.w>txh->width) src_wnd.w=txh->width;	if (src_wnd.h>txh->height) src_wnd.h=txh->height;		src_wnd.x = start_x;	src_wnd.y = start_y;	if (!src_wnd.w || !src_wnd.h) return;	/*make sure we lie in src bounds*/	if (src_wnd.x + src_wnd.w>txh->width) src_wnd.w = txh->width - src_wnd.x;	if (src_wnd.y + src_wnd.h>txh->height) src_wnd.h = txh->height - src_wnd.y;	use_soft_stretch = 1;	if (!cmat && (alpha==0xFF) && surf->render->compositor->video_out->Blit) {		u32 hw_caps = surf->render->compositor->video_out->hw_caps;		/*get the right surface and copy the part of the image on it*/		switch (txh->pixelformat) {		case GF_PIXEL_RGB_24:		case GF_PIXEL_BGR_24:			use_soft_stretch = 0;			break;		case GF_PIXEL_YV12:		case GF_PIXEL_IYUV:		case GF_PIXEL_I420:			if (surf->render->enable_yuv_hw && (hw_caps & GF_VIDEO_HW_HAS_YUV))				use_soft_stretch = 0;			break;		default:			break;		}		if (col_key && (GF_COL_A(*col_key) || !(hw_caps & GF_VIDEO_HW_HAS_COLOR_KEY))) use_soft_stretch = 1;	}	/*most graphic cards can't perform bliting on locked surface - force unlock by releasing the hardware*/	VS2D_TerminateSurface(surf);	video_src.height = txh->height;	video_src.width = txh->width;	video_src.pitch = txh->stride;	video_src.pixel_format = txh->pixelformat;	video_src.video_buffer = txh->data;	if (!use_soft_stretch) {		e = surf->render->compositor->video_out->Blit(surf->render->compositor->video_out, &video_src, &src_wnd, &dst_wnd, col_key);		/*HW pb, try soft*/		if (e) {			GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Render 2D] Error during hardware blit - trying with soft one\n"));			use_soft_stretch = 1;		}	}	if (use_soft_stretch) {		GF_VideoSurface backbuffer;		e = surf->render->compositor->video_out->LockBackBuffer(surf->render->compositor->video_out, &backbuffer, 1);		gf_stretch_bits(&backbuffer, &video_src, &dst_wnd, &src_wnd, 0, alpha, 0, col_key, cmat);		e = surf->render->compositor->video_out->LockBackBuffer(surf->render->compositor->video_out, &backbuffer, 0);	}	VS2D_InitSurface(surf);}GF_Err R2D_LoadRenderer(GF_VisualRenderer *vr, GF_Renderer *compositor){	Render2D *sr;	const char *sOpt;	if (vr->user_priv) return GF_BAD_PARAM;	GF_SAFEALLOC(sr, Render2D);	if (!sr) return GF_OUT_OF_MEM;	sr->compositor = compositor;	sr->strike_bank = gf_list_new();	sr->surfaces_2D = gf_list_new();	GF_SAFEALLOC(sr->top_effect, RenderEffect2D);	sr->top_effect->sensors = gf_list_new();	sr->sensors = gf_list_new();		/*and create main surface*/	sr->surface = NewVisualSurface2D();	sr->surface->GetSurfaceAccess = R2D_GetSurfaceAccess;	sr->surface->ReleaseSurfaceAccess = R2D_ReleaseSurfaceAccess;	sr->surface->DrawBitmap = R2D_DrawBitmap;	sr->surface->SupportsFormat = R2D_SupportsFormat;	sr->surface->render = sr;	gf_list_add(sr->surfaces_2D, sr->surface);	sr->zoom = sr->scale_x = sr->scale_y = FIX_ONE;	vr->user_priv = sr;	sOpt = gf_cfg_get_key(compositor->user->config, "Render2D", "FocusHighlightFill");	if (sOpt) sscanf(sOpt, "%x", &sr->highlight_fill);	sOpt = gf_cfg_get_key(compositor->user->config, "Render2D", "FocusHighlightStroke");	if (sOpt) sscanf(sOpt, "%x", &sr->highlight_stroke);	else sr->highlight_stroke = 0xFF000000;	/*create a drawable for focus highlight*/	sr->focus_highlight = drawable_new();	/*associate a dummy node for rendering*/	sr->focus_highlight->node = gf_node_new(NULL, TAG_UndefinedNode);	gf_node_register(sr->focus_highlight->node, NULL);	gf_node_set_callback_function(sr->focus_highlight->node, drawable_render_focus);

⌨️ 快捷键说明

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