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

📄 renderer.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / Scene Rendering sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/renderer_dev.h>/*for user and terminal API (options and InputSensor)*/#include <gpac/terminal.h>#include <gpac/options.h>#ifndef GPAC_DISABLE_SVG#include <gpac/nodes_svg_da.h>#include <gpac/scenegraph_svg.h>#ifdef GPAC_ENABLE_SVG_SA#include <gpac/nodes_svg_sa.h>#endif#ifdef GPAC_ENABLE_SVG_SANI#include <gpac/nodes_svg_sani.h>#endif#endif/*macro for size event format/send*/#define GF_USER_SETSIZE(_user, _w, _h)	\	{	\		GF_Event evt;	\		if (_user->EventProc) {	\			evt.type = GF_EVENT_SIZE;	\			evt.size.width = _w;	\			evt.size.height = _h;	\			_user->EventProc(_user->opaque, &evt);	\		}	\	}void gf_sr_simulation_tick(GF_Renderer *sr);GF_Err gf_sr_set_output_size(GF_Renderer *sr, u32 Width, u32 Height){	GF_Err e;	gf_sr_lock(sr, 1);	/*FIXME: need to check for max resolution*/	sr->width = Width;	sr->height = Height;	e = sr->visual_renderer->RecomputeAR(sr->visual_renderer);	sr->draw_next_frame = 1;	gf_sr_lock(sr, 0);	return e;}static void gf_sr_set_fullscreen(GF_Renderer *sr){	GF_Err e;	if (!sr->video_out->SetFullScreen) return;	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Switching fullscreen %s\n", sr->fullscreen ? "off" : "on"));	/*move to FS*/	sr->fullscreen = !sr->fullscreen;	e = sr->video_out->SetFullScreen(sr->video_out, sr->fullscreen, &sr->width, &sr->height);	if (e) {		GF_USER_MESSAGE(sr->user, "VideoRenderer", "Cannot switch to fullscreen", e);		sr->fullscreen = 0;		e = sr->video_out->SetFullScreen(sr->video_out, 0, &sr->width, &sr->height);	}	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] recomputing aspect ratio\n"));	e = sr->visual_renderer->RecomputeAR(sr->visual_renderer);	/*force signaling graphics reset*/	sr->reset_graphics = 1;}/*this is needed for:- audio: since the audio renderer may not be threaded, it must be reconfigured by another thread otherwise we lock the audio module- video: this is typical to OpenGL&co: multithreaded is forbidden, so resizing/fullscreen MUST be done by the same thread accessing the HW ressources*/static void gf_sr_reconfig_task(GF_Renderer *sr){	GF_Event evt;	u32 width,height;		/*reconfig audio if needed (non-threaded renderers)*/	if (sr->audio_renderer && !sr->audio_renderer->th) gf_sr_ar_reconfig(sr->audio_renderer);	if (sr->msg_type) {		sr->msg_type |= GF_SR_IN_RECONFIG;		/*scene size has been overriden*/		if (sr->msg_type & GF_SR_CFG_OVERRIDE_SIZE) {			assert(!(sr->override_size_flags & 2));			sr->override_size_flags |= 2;			width = sr->scene_width;			height = sr->scene_height;			sr->has_size_info = 1;			gf_sr_set_size(sr, width, height);			GF_USER_SETSIZE(sr->user, width, height);		}		/*size changed from scene cfg: resize window first*/		if (sr->msg_type & GF_SR_CFG_SET_SIZE) {			u32 fs_width, fs_height;			Bool restore_fs = sr->fullscreen;			GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Changing display size to %d x %d\n", sr->new_width, sr->new_height));			fs_width = fs_height = 0;			if (restore_fs) {				//gf_sr_set_fullscreen(sr);				fs_width = sr->width;				fs_height = sr->height;			}			evt.type = GF_EVENT_SIZE;			evt.size.width = sr->new_width;			evt.size.height = sr->new_height;			/*send resize event*/			if (!(sr->msg_type & GF_SR_CFG_WINDOWSIZE_NOTIF)) {				sr->video_out->ProcessEvent(sr->video_out, &evt);			}			if (restore_fs) {				//gf_sr_set_fullscreen(sr);				sr->width = fs_width;				sr->height = fs_height;				sr->visual_renderer->RecomputeAR(sr->visual_renderer);			} else {				gf_sr_set_output_size(sr, evt.size.width, evt.size.height);			}			sr->reset_graphics = 1;			//			if (!sr->user->os_window_handler) //				GF_USER_SENDEVENT(sr->user, &evt);		}		/*aspect ratio modif*/		if (sr->msg_type & GF_SR_CFG_AR) {			sr->visual_renderer->RecomputeAR(sr->visual_renderer);		}		/*fullscreen on/off request*/		if (sr->msg_type & GF_SR_CFG_FULLSCREEN) {			gf_sr_set_fullscreen(sr);			sr->draw_next_frame = 1;		}		sr->new_width = sr->new_height = 0;		sr->msg_type = 0;	}	/*3D driver changed message, recheck extensions*/	if (sr->reset_graphics) {		sr->visual_renderer->GraphicsReset(sr->visual_renderer);		evt.type = GF_EVENT_SYS_COLORS;		if (sr->user->EventProc && sr->user->EventProc(sr->user->opaque, &evt) ) {			u32 i;			for (i=0; i<28; i++) {				sr->sys_colors[i] = evt.sys_cols.sys_colors[i] & 0x00FFFFFF;			}		}	}}Bool gf_sr_render_frame(GF_Renderer *sr){		/*render*/	gf_sr_simulation_tick(sr);	return sr->draw_next_frame;}u32 SR_RenderRun(void *par){		GF_Renderer *sr = (GF_Renderer *) par;	sr->video_th_state = 1;	GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Renderer] Entering thread ID %d\n", gf_th_id() ));	while (sr->video_th_state == 1) {		/*sleep or render*/		if (sr->is_hidden) 			gf_sleep(sr->frame_duration);		else			gf_sr_simulation_tick(sr);	}	/*destroy video out here if w're using openGL, to avoid threading issues*/	sr->video_out->Shutdown(sr->video_out);	gf_modules_close_interface((GF_BaseInterface *)sr->video_out);	sr->video_out = NULL;	sr->video_th_state = 3;	return 0;}/*forces graphics redraw*/GF_EXPORTvoid gf_sr_reset_graphics(GF_Renderer *sr){		if (sr) {		gf_sr_lock(sr, 1);		sr->reset_graphics = 1;		gf_sr_lock(sr, 0);	}}void SR_ResetFrameRate(GF_Renderer *sr){	u32 i;	for (i=0; i<GF_SR_FPS_COMPUTE_SIZE; i++) sr->frame_time[i] = 0;	sr->current_frame = 0;}void SR_SetFontEngine(GF_Renderer *sr);static void gf_sr_on_event(void *cbck, GF_Event *event);static Bool check_graphics2D_driver(GF_Raster2D *ifce){	/*check base*/	if (!ifce->stencil_new || !ifce->surface_new) return 0;	/*if these are not set we cannot draw*/	if (!ifce->surface_clear || !ifce->surface_set_path || !ifce->surface_fill) return 0;	/*check we can init a surface with the current driver (the rest is optional)*/	if (ifce->surface_attach_to_buffer) return 1;	return 0;}static GF_Renderer *SR_New(GF_User *user){	const char *sOpt;	GF_VisualRenderer *vrend;	GF_GLConfig cfg, *gl_cfg;	Bool forced = 1;	GF_Renderer *tmp;	GF_SAFEALLOC(tmp, GF_Renderer);	if (!tmp) return NULL;	tmp->user = user;	/*load renderer to check for GL flag*/	if (! (user->init_flags & (GF_TERM_FORCE_2D | GF_TERM_FORCE_3D)) ) {		sOpt = gf_cfg_get_key(user->config, "Rendering", "RendererName");		if (sOpt) {			tmp->visual_renderer = (GF_VisualRenderer *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RENDERER_INTERFACE);			if (!tmp->visual_renderer) sOpt = NULL;		}		forced = 0;	}	if (!tmp->visual_renderer) {		u32 i, count;		count = gf_modules_get_count(user->modules);		for (i=0; i<count; i++) {			tmp->visual_renderer = (GF_VisualRenderer *) gf_modules_load_interface(user->modules, i, GF_RENDERER_INTERFACE);			if (tmp->visual_renderer) {				if ((tmp->visual_renderer->bNeedsGL && (user->init_flags & GF_TERM_FORCE_2D)) 					|| (!tmp->visual_renderer->bNeedsGL && (user->init_flags & GF_TERM_FORCE_3D)) ) {					GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Renderer] Renderer %s loaded but not matching init flags %08x\n", tmp->visual_renderer->module_name, user->init_flags));					gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer);					tmp->visual_renderer = NULL;					continue;				}				break;			}		}		if (!forced && tmp->visual_renderer) gf_cfg_set_key(user->config, "Rendering", "RendererName", tmp->visual_renderer->module_name);	}	if (!tmp->visual_renderer) {		GF_LOG(GF_LOG_ERROR, GF_LOG_RENDER, ("[Renderer] Cannot load any visual renderer - aborting\n"));		free(tmp);		return NULL;	}	memset(&cfg, 0, sizeof(cfg));	cfg.double_buffered = 1;	gl_cfg = tmp->visual_renderer->bNeedsGL ? &cfg : NULL;	vrend = tmp->visual_renderer;	tmp->visual_renderer = NULL;	/*load video out*/	sOpt = gf_cfg_get_key(user->config, "Video", "DriverName");	if (sOpt) {		tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_VIDEO_OUTPUT_INTERFACE);		if (tmp->video_out) {			tmp->video_out->evt_cbk_hdl = tmp;			tmp->video_out->on_event = gf_sr_on_event;			/*init hw*/			if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags, gl_cfg) != GF_OK) {				gf_modules_close_interface((GF_BaseInterface *)tmp->video_out);				tmp->video_out = NULL;			}		} else {			sOpt = NULL;		}	}	if (!tmp->video_out) {		u32 i, count;		count = gf_modules_get_count(user->modules);		for (i=0; i<count; i++) {			tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface(user->modules, i, GF_VIDEO_OUTPUT_INTERFACE);			if (!tmp->video_out) continue;			tmp->video_out->evt_cbk_hdl = tmp;			tmp->video_out->on_event = gf_sr_on_event;			/*init hw*/			if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags, gl_cfg)==GF_OK) {				gf_cfg_set_key(user->config, "Video", "DriverName", tmp->video_out->module_name);				break;			}			gf_modules_close_interface((GF_BaseInterface *)tmp->video_out);			tmp->video_out = NULL;		}	}	tmp->visual_renderer = vrend;	if (!tmp->video_out ) {		gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer);		free(tmp);		return NULL;	}	/*try to load a raster driver*/	sOpt = gf_cfg_get_key(user->config, "Rendering", "Raster2D");	if (sOpt) {		tmp->r2d = (GF_Raster2D *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RASTER_2D_INTERFACE);		if (!tmp->r2d) {			sOpt = NULL;		} else if (!check_graphics2D_driver(tmp->r2d)) {			gf_modules_close_interface((GF_BaseInterface *)tmp->r2d);			tmp->r2d = NULL;			sOpt = NULL;		}	}	if (!tmp->r2d) {		u32 i, count;		count = gf_modules_get_count(user->modules);		for (i=0; i<count; i++) {			tmp->r2d = (GF_Raster2D *) gf_modules_load_interface(user->modules, i, GF_RASTER_2D_INTERFACE);			if (!tmp->r2d) continue;			if (check_graphics2D_driver(tmp->r2d)) break;			gf_modules_close_interface((GF_BaseInterface *)tmp->r2d);			tmp->r2d = NULL;		}		if (tmp->r2d) gf_cfg_set_key(user->config, "Rendering", "Raster2D", tmp->r2d->module_name);	}	/*and init*/	if (tmp->visual_renderer->LoadRenderer(tmp->visual_renderer, tmp) != GF_OK) {		gf_modules_close_interface((GF_BaseInterface *)tmp->visual_renderer);		tmp->video_out->Shutdown(tmp->video_out);		gf_modules_close_interface((GF_BaseInterface *)tmp->video_out);		free(tmp);		return NULL;	}	tmp->mx = gf_mx_new();	tmp->textures = gf_list_new();	tmp->frame_rate = 30.0;		tmp->frame_duration = 33;	tmp->time_nodes = gf_list_new();#ifdef GF_SR_EVENT_QUEUE	tmp->events = gf_list_new();	tmp->ev_mx = gf_mx_new();#endif		SR_ResetFrameRate(tmp);		/*set font engine if any*/	SR_SetFontEngine(tmp);		tmp->extra_scenes = gf_list_new();	tmp->interaction_level = GF_INTERACT_NORMAL | GF_INTERACT_INPUT_SENSOR | GF_INTERACT_NAVIGATION;	return tmp;}GF_Renderer *gf_sr_new(GF_User *user, Bool self_threaded, GF_Terminal *term){	GF_Renderer *tmp = SR_New(user);	if (!tmp) return NULL;	tmp->term = term;	/**/	tmp->audio_renderer = gf_sr_ar_load(user);		if (!tmp->audio_renderer) GF_USER_MESSAGE(user, "", "NO AUDIO RENDERER", GF_OK);	gf_mx_p(tmp->mx);	/*run threaded*/	if (self_threaded) {		tmp->VisualThread = gf_th_new();		gf_th_run(tmp->VisualThread, SR_RenderRun, tmp);		while (tmp->video_th_state!=1) {			gf_sleep(10);			if (tmp->video_th_state==3) {				gf_mx_v(tmp->mx);				gf_sr_del(tmp);				return NULL;			}		}	}	/*set default size if owning output*/	if (!tmp->user->os_window_handler) {		gf_sr_set_size(tmp, 320, 20);	}	gf_mx_v(tmp->mx);	return tmp;}void gf_sr_del(GF_Renderer *sr){	if (!sr) return;	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Destroying Renderer\n"));	gf_sr_lock(sr, 1);	if (sr->VisualThread) {		sr->video_th_state = 2;		while (sr->video_th_state!=3) gf_sleep(10);		gf_th_del(sr->VisualThread);	}	if (sr->video_out) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Closing video output\n"));		sr->video_out->Shutdown(sr->video_out);		gf_modules_close_interface((GF_BaseInterface *)sr->video_out);	}	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Closing visual renderer\n"));	sr->visual_renderer->UnloadRenderer(sr->visual_renderer);	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Unloading visual renderer module\n"));	gf_modules_close_interface((GF_BaseInterface *)sr->visual_renderer);	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] visual renderer module unloaded\n"));	if (sr->audio_renderer) gf_sr_ar_del(sr->audio_renderer);#ifdef GF_SR_EVENT_QUEUE	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);		free(ev);	}	gf_mx_v(sr->ev_mx);	gf_mx_del(sr->ev_mx);	gf_list_del(sr->events);#endif	if (sr->font_engine) {		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Closing font engine\n"));		sr->font_engine->shutdown_font_engine(sr->font_engine);		gf_modules_close_interface((GF_BaseInterface *)sr->font_engine);	}	gf_list_del(sr->textures);	gf_list_del(sr->time_nodes);	gf_list_del(sr->extra_scenes);	gf_sr_lock(sr, 0);	gf_mx_del(sr->mx);	free(sr);	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Renderer destroyed\n"));}void gf_sr_set_fps(GF_Renderer *sr, Double fps){	if (fps) {		sr->frame_rate = fps;		sr->frame_duration = (u32) (1000 / fps);		SR_ResetFrameRate(sr);		}}u32 gf_sr_get_audio_buffer_length(GF_Renderer *sr){	if (!sr || !sr->audio_renderer || !sr->audio_renderer->audio_out) return 0;	return sr->audio_renderer->audio_out->GetTotalBufferTime(sr->audio_renderer->audio_out);}static void gf_sr_pause(GF_Renderer *sr, u32 PlayState){	if (!sr || !sr->audio_renderer) return;	if (!sr->paused && !PlayState) return;	if (sr->paused && (PlayState==GF_STATE_PAUSED)) return;	/*step mode*/	if (PlayState==GF_STATE_STEP_PAUSE) {

⌨️ 快捷键说明

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