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

📄 renderer.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	GF_Err e;	if (!sr || !framebuffer) return GF_BAD_PARAM;	gf_mx_p(sr->mx);	e = sr->visual_renderer->GetScreenBuffer(sr->visual_renderer, framebuffer);	if (e != GF_OK) gf_mx_v(sr->mx);	return e;}GF_Err gf_sr_release_screen_buffer(GF_Renderer *sr, GF_VideoSurface *framebuffer){	GF_Err e;	if (!sr || !framebuffer) return GF_BAD_PARAM;	e = sr->visual_renderer->ReleaseScreenBuffer(sr->visual_renderer, framebuffer);	gf_mx_v(sr->mx);	return e;}Double gf_sr_get_fps(GF_Renderer *sr, Bool absoluteFPS){	Double fps;	u32 ind, num, frames, run_time;	/*start from last frame and get first frame time*/	ind = sr->current_frame;	frames = 0;	run_time = sr->frame_time[ind];	for (num=0; num<GF_SR_FPS_COMPUTE_SIZE; num++) {		if (absoluteFPS) {			run_time += sr->frame_time[ind];		} else {			run_time += MAX(sr->frame_time[ind], sr->frame_duration);		}		frames++;		if (frames==GF_SR_FPS_COMPUTE_SIZE) break;		if (!ind) {			ind = GF_SR_FPS_COMPUTE_SIZE;		} else {			ind--;		}	}	if (!run_time) return (Double) sr->frame_rate;	fps = 1000*frames;	fps /= run_time;	return fps;}void gf_sr_register_time_node(GF_Renderer *sr, GF_TimeNode *tn){	/*may happen with DEF/USE */	if (tn->is_registered) return;	if (tn->needs_unregister) return;	gf_list_add(sr->time_nodes, tn);	tn->is_registered = 1;}void gf_sr_unregister_time_node(GF_Renderer *sr, GF_TimeNode *tn){	gf_list_del_item(sr->time_nodes, tn);}GF_Node *gf_sr_pick_node(GF_Renderer *sr, s32 X, s32 Y){	return NULL;}static u32 last_lclick_time = 0;static void SR_ForwardUserEvent(GF_Renderer *sr, GF_Event *ev){	GF_USER_SENDEVENT(sr->user, ev);	if ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT)) {		u32 now;		GF_Event event;		/*emulate doubleclick*/		now = gf_sys_clock();		if (now - last_lclick_time < 250) {			event.type = GF_EVENT_MOUSEDOUBLECLICK;			event.mouse.key_states = sr->key_states;			event.mouse.x = ev->mouse.x;			event.mouse.y = ev->mouse.y;			GF_USER_SENDEVENT(sr->user, &event);		}		last_lclick_time = now;	}}void gf_sr_simulation_tick(GF_Renderer *sr){		u32 in_time, end_time, i, count;	/*lock renderer for the whole render cycle*/	gf_sr_lock(sr, 1);	/*first thing to do, let the video output handle user event if it is not threaded*/	sr->video_out->ProcessEvent(sr->video_out, NULL);	if (sr->freeze_display) {		gf_sr_lock(sr, 0);		gf_sleep(sr->frame_duration);		return;	}	gf_sr_reconfig_task(sr);	/* if there is no scene, we draw a black screen to flush the screen */	if (!sr->scene) {		sr->visual_renderer->DrawScene(sr->visual_renderer);		gf_sr_lock(sr, 0);		gf_sleep(sr->frame_duration);		return;	}//	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[General] Time %f - Composing new frame #%d\n", gf_node_get_scene_time(gf_sg_get_root_node(sr->scene)), sr->frame_number));	in_time = gf_sys_clock();	if (sr->reset_graphics) sr->draw_next_frame = 1;#ifdef GF_SR_EVENT_QUEUE	/*process pending user events*/	gf_mx_p(sr->ev_mx);	while (gf_list_count(sr->events)) {		GF_Event *ev = (GF_Event*)gf_list_get(sr->events, 0);		gf_list_rem(sr->events, 0);		if (!sr->visual_renderer->ExecuteEvent(sr->visual_renderer, ev)) {			SR_ForwardUserEvent(sr, ev);		}		free(ev);	}	gf_mx_v(sr->ev_mx);#endif#if 0	if (sr->frame_number == 0 && sr->user->EventProc) {		GF_Event evt;		evt.type = GF_EVENT_UPDATE_RTI;		evt.caption.caption = "UPDATE - Before first call to draw scene";		sr->user->EventProc(sr->user->opaque, &evt);	}#endif	/*execute all routes before updating textures, otherwise nodes inside composite texture may never see their	dirty flag set*/	gf_sg_activate_routes(sr->scene);#ifndef GPAC_DISABLE_SVG#if SVG_FIXME	{ /* Experimental (Not SVG compliant system events (i.e. battery, cpu ...) triggered to the root node)*/		GF_Node *root = gf_sg_get_root_node(sr->scene);		GF_DOM_Event evt;		if (gf_dom_listener_count(root)) {			u32 i, count;			count = gf_dom_listener_count(root);			for (i=0;i<count; i++) {				SVG_SA_listenerElement *l = gf_dom_listener_get(root, i);				if (l->event.type == GF_EVENT_CPU) {					GF_SystemRTInfo sys_rti;					if (gf_sys_get_rti(500, &sys_rti, GF_RTI_ALL_PROCESSES_TIMES)) {						evt.type = GF_EVENT_CPU;						evt.cpu_percentage = sys_rti.total_cpu_usage;						//printf("%d\n",sys_rti.total_cpu_usage);						gf_dom_event_fire(root, NULL, &evt);					} 				} else if (l->event.type == GF_EVENT_BATTERY) { //&& l->observer.target == (SVG_SA_Element *)node) {					evt.type = GF_EVENT_BATTERY;					gf_sys_get_battery_state(&evt.onBattery, &evt.batteryState, &evt.batteryLevel);					gf_dom_event_fire(root, NULL, &evt);				}			}		}	}#endif	if (gf_smil_notify_timed_elements(sr->scene)) {		sr->draw_next_frame = 1;	}#if 0	for (i=0; i<gf_list_count(sr->secondary_scenes); i++) {		if (gf_smil_notify_timed_elements(gf_list_get(sr->secondary_scenes, i))) {			sr->draw_next_frame = 1;		}	}#endif#endif	/*update all textures*/	count = gf_list_count(sr->textures);	for (i=0; i<count; i++) {		GF_TextureHandler *st = (GF_TextureHandler *)gf_list_get(sr->textures, i);		/*signal graphics reset before updating*/		if (sr->reset_graphics && st->hwtx) sr->visual_renderer->TextureHWReset(st);		st->update_texture_fcnt(st);	}	/*if invalidated, draw*/	if (sr->draw_next_frame) {		/*video flush only*/		if (sr->draw_next_frame==2) {			GF_Window rc;			rc.x = rc.y = 0; 			rc.w = sr->width;				rc.h = sr->height;					sr->draw_next_frame = 0;			sr->video_out->Flush(sr->video_out, &rc);		} else {			sr->draw_next_frame = 0;			GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Redrawing scene\n"));			sr->visual_renderer->DrawScene(sr->visual_renderer);#if 0			if (sr->frame_number == 0 && sr->user->EventProc) {				GF_Event evt;				evt.type = GF_EVENT_UPDATE_RTI;				evt.caption.caption = "Before first call to draw scene";				sr->user->EventProc(sr->user->opaque, &evt);			}#endif		}		sr->reset_graphics = 0;		GF_LOG(GF_LOG_INFO, GF_LOG_RENDER, ("[Render] Scene drawn in %d ms\n", gf_sys_clock() - in_time));		if (sr->stress_mode) {			sr->draw_next_frame = 1;			sr->reset_graphics = 1;		}	}	/*release all textures - we must release them to handle a same OD being used by several textures*/	count = gf_list_count(sr->textures);	for (i=0; i<count; i++) {		GF_TextureHandler *st = (GF_TextureHandler *)gf_list_get(sr->textures, i);		gf_sr_texture_release_stream(st);	}	/*update all timed nodes */	for (i=0; i<gf_list_count(sr->time_nodes); i++) {		GF_TimeNode *tn = (GF_TimeNode *)gf_list_get(sr->time_nodes, i);		if (!tn->needs_unregister) tn->UpdateTimeNode(tn);		if (tn->needs_unregister) {			tn->is_registered = 0;			tn->needs_unregister = 0;			gf_list_rem(sr->time_nodes, i);			i--;			continue;		}	}	end_time = gf_sys_clock() - in_time;	gf_sr_lock(sr, 0);	sr->current_frame = (sr->current_frame+1) % GF_SR_FPS_COMPUTE_SIZE;	sr->frame_time[sr->current_frame] = end_time;	sr->frame_number++;#if 0	if (sr->user->EventProc) {		char legend[100];		GF_Event evt;		evt.type = GF_EVENT_UPDATE_RTI;		sprintf(legend, "After rendering of frame %d", sr->frame_number);		evt.caption.caption = legend;		sr->user->EventProc(sr->user->opaque, &evt);	}#endif	/*step mode on, pause and return*/	if (sr->step_mode) {		sr->step_mode = 0;		if (sr->term) gf_term_set_option(sr->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED);		return;	}	/*not threaded, let the owner decide*/	if ((sr->user->init_flags & GF_TERM_NO_VISUAL_THREAD) || !sr->frame_duration) return;	/*compute sleep time till next frame, otherwise we'll kill the CPU*/	i=1;	while (i * sr->frame_duration < end_time) i++;	in_time = i * sr->frame_duration - end_time;	gf_sleep(in_time);}GF_Err gf_sr_get_viewpoint(GF_Renderer *sr, u32 viewpoint_idx, const char **outName, Bool *is_bound){	if (!sr->visual_renderer->GetViewpoint) return GF_NOT_SUPPORTED;	return sr->visual_renderer->GetViewpoint(sr->visual_renderer, viewpoint_idx, outName, is_bound);}GF_Err gf_sr_set_viewpoint(GF_Renderer *sr, u32 viewpoint_idx, const char *viewpoint_name){	if (!sr->visual_renderer->SetViewpoint) return GF_NOT_SUPPORTED;	return sr->visual_renderer->SetViewpoint(sr->visual_renderer, viewpoint_idx, viewpoint_name);}void gf_sr_render_inline(GF_Renderer *sr, GF_Node *inline_parent, GF_Node *inline_root, void *rs){	if (sr->visual_renderer->RenderInline) sr->visual_renderer->RenderInline(sr->visual_renderer, inline_parent, inline_root, rs);}static Bool SR_UserInputIntern(GF_Renderer *sr, GF_Event *event, Bool from_user){#ifdef GF_SR_EVENT_QUEUE	GF_Event *ev;#else	Bool ret;#endif	if (sr->term && (sr->interaction_level & GF_INTERACT_INPUT_SENSOR) && (event->type<=GF_EVENT_MOUSEWHEEL))		gf_term_mouse_input(sr->term, &event->mouse);	if (!sr->interaction_level || (sr->interaction_level==GF_INTERACT_INPUT_SENSOR) ) {		if (!from_user) {			GF_USER_SENDEVENT(sr->user, event);		}		return 0;	}#ifdef GF_SR_EVENT_QUEUE	switch (event->type) {	case GF_EVENT_MOUSEMOVE:	{		u32 i, count;		gf_mx_p(sr->ev_mx);		count = gf_list_count(sr->events);		for (i=0; i<count; i++) {			ev = (GF_Event *)gf_list_get(sr->events, i);			if (ev->type == GF_EVENT_MOUSEMOVE) {				ev->mouse =  event->mouse;				gf_mx_v(sr->ev_mx);				return 1;			}		}		gf_mx_v(sr->ev_mx);	}	default:		ev = (GF_Event *)malloc(sizeof(GF_Event));		ev->type = event->type;		if (event->type<=GF_EVENT_MOUSEWHEEL) {			ev->mouse = event->mouse;		} else if (event->type==GF_EVENT_TEXTINPUT) {			ev->character = event->character;		} else {			ev->key = event->key;		}		gf_mx_p(sr->ev_mx);		gf_list_add(sr->events, ev);		gf_mx_v(sr->ev_mx);		break;	}	return 0;#else	gf_sr_lock(sr, 1);	ret = sr->visual_renderer->ExecuteEvent(sr->visual_renderer, event);	gf_sr_lock(sr, 0);	if (!ret && !from_user) {		SR_ForwardUserEvent(sr, event);	}	return ret;#endif}static Bool gf_sr_on_event_ex(GF_Renderer *sr , GF_Event *event, Bool from_user){	/*not assigned yet*/	if (!sr || !sr->visual_renderer) return 0;	/*we're reconfiguring the video output, cancel all messages*/	if (sr->msg_type & GF_SR_IN_RECONFIG) return 0;	switch (event->type) {	case GF_EVENT_REFRESH:		if (!sr->draw_next_frame) sr->draw_next_frame = 2;		break;	case GF_EVENT_VIDEO_SETUP:		gf_sr_reset_graphics(sr);		break;	case GF_EVENT_SIZE:		/*resize message from plugin: if we own the output, resize*/		if (!sr->user->os_window_handler) {			/*EXTRA CARE HERE: the caller (video output) is likely a different thread than the renderer one, and the			renderer may be locked on the video output (flush or whatever)!!			*/			Bool lock_ok = gf_mx_try_lock(sr->mx);			sr->new_width = event->size.width;			sr->new_height = event->size.height;			sr->msg_type |= GF_SR_CFG_SET_SIZE;			if (lock_ok) gf_sr_lock(sr, 0);		}		/*otherwise let the user decide*/		else {			GF_USER_SENDEVENT(sr->user, event);		}		break;	case GF_EVENT_KEYDOWN:	case GF_EVENT_KEYUP:		switch (event->key.key_code) {		case GF_KEY_SHIFT: 			if (event->type==GF_EVENT_KEYDOWN) {				sr->key_states |= GF_KEY_MOD_SHIFT; 			} else {				sr->key_states &= ~GF_KEY_MOD_SHIFT; 			}			break;		case GF_KEY_CONTROL: 			if (event->type==GF_EVENT_KEYDOWN) {				sr->key_states |= GF_KEY_MOD_CTRL; 			} else {				sr->key_states &= ~GF_KEY_MOD_CTRL; 			}			break;		case GF_KEY_ALT: 			if (event->type==GF_EVENT_KEYDOWN) {				sr->key_states |= GF_KEY_MOD_ALT;			} else {				sr->key_states &= ~GF_KEY_MOD_ALT;			}			break;		}		event->key.flags |= sr->key_states;		/*key sensor*/		if (sr->term && (sr->interaction_level & GF_INTERACT_INPUT_SENSOR) ) {			gf_term_keyboard_input(sr->term, event->key.key_code, event->key.hw_code, (event->type==GF_EVENT_KEYUP) ? 1 : 0);		}				return SR_UserInputIntern(sr, event, from_user);	case GF_EVENT_TEXTINPUT:		if (sr->term && (sr->interaction_level & GF_INTERACT_INPUT_SENSOR) )			gf_term_string_input(sr->term , event->character.unicode_char);		return SR_UserInputIntern(sr, event, from_user);	/*switch fullscreen off!!!*/	case GF_EVENT_SHOWHIDE:		gf_sr_set_option(sr, GF_OPT_FULLSCREEN, !sr->fullscreen);		break;	case GF_EVENT_SET_CAPTION:		sr->video_out->ProcessEvent(sr->video_out, event);		break;	case GF_EVENT_MOUSEMOVE:		event->mouse.button = 0;	case GF_EVENT_MOUSEDOWN:	case GF_EVENT_MOUSEUP:	case GF_EVENT_MOUSEWHEEL:		event->mouse.key_states = sr->key_states;		return SR_UserInputIntern(sr, event, from_user);	/*when we process events we don't forward them to the user*/	default:		GF_USER_SENDEVENT(sr->user, event);		break;	}	return 1;}static void gf_sr_on_event(void *cbck, GF_Event *event){	gf_sr_on_event_ex((GF_Renderer *)cbck, event, 0);}Bool gf_sr_user_event(GF_Renderer *sr, GF_Event *event){	switch (event->type) {	case GF_EVENT_SHOWHIDE:	case GF_EVENT_MOVE:	case GF_EVENT_SET_CAPTION:		sr->video_out->ProcessEvent(sr->video_out, event);		return 0;	default:		return gf_sr_on_event_ex(sr, event, 1);	}}void gf_sr_register_extra_graph(GF_Renderer *sr, GF_SceneGraph *extra_scene, Bool do_remove){	gf_sr_lock(sr, 1);	if (do_remove) gf_list_del_item(sr->extra_scenes, extra_scene);	else if (gf_list_find(sr->extra_scenes, extra_scene)<0) gf_list_add(sr->extra_scenes, extra_scene);	gf_sr_lock(sr, 0);}u32 gf_sr_get_audio_delay(GF_Renderer *sr){	return sr->audio_renderer ? sr->audio_renderer->audio_delay : 0;}void *gf_sr_get_visual_renderer(GF_Renderer *sr){	return sr->visual_renderer;}

⌨️ 快捷键说明

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