📄 renderer.c
字号:
sr->step_mode = 1; /*resume for next step*/ if (sr->paused && sr->term) gf_term_set_option(sr->term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); } else { if (sr->audio_renderer) gf_sr_ar_control(sr->audio_renderer, (sr->paused && (PlayState==0xFF)) ? 2 : sr->paused); sr->paused = (PlayState==GF_STATE_PAUSED) ? 1 : 0; }}u32 gf_sr_get_clock(GF_Renderer *sr){ return gf_sr_ar_get_clock(sr->audio_renderer);}static GF_Err SR_SetSceneSize(GF_Renderer *sr, u32 Width, u32 Height){ if (!Width || !Height) { sr->has_size_info = 0; if (sr->override_size_flags) { /*specify a small size to detect biggest bitmap but not 0 in case only audio..*/ sr->scene_height = 20; sr->scene_width = 320; } else { /*use current res*/ sr->scene_width = sr->width ? sr->width : sr->new_width; sr->scene_height = (sr->height==20) ? 240 : (sr->height ? sr->height : sr->new_height); } } else { sr->has_size_info = 1; sr->scene_height = Height; sr->scene_width = Width; } return GF_OK;}Bool gf_sr_get_size(GF_Renderer *sr, u32 *Width, u32 *Height){ *Height = sr->scene_height; *Width = sr->scene_width; return 1;}#ifndef GPAC_DISABLE_SVGstatic Fixed convert_svg_length_to_user(GF_Renderer *sr, SVG_Length *length){ // Assuming the environment is 90dpi switch (length->type) { case SVG_NUMBER_PERCENTAGE: break; case SVG_NUMBER_EMS: break; case SVG_NUMBER_EXS: break; case SVG_NUMBER_VALUE: break; case SVG_NUMBER_PX: return length->value; case SVG_NUMBER_CM: return gf_mulfix(length->value, FLT2FIX(35.43307f)); break; case SVG_NUMBER_MM: return gf_mulfix(length->value, FLT2FIX(3.543307f)); case SVG_NUMBER_IN: return length->value * 90; case SVG_NUMBER_PT: return 5 * length->value / 4; case SVG_NUMBER_PC: return length->value * 15; case SVG_NUMBER_INHERIT: break; } return length->value;}#endifGF_Err gf_sr_set_scene(GF_Renderer *sr, GF_SceneGraph *scene_graph){ u32 width, height; Bool do_notif; if (!sr) return GF_BAD_PARAM; gf_sr_lock(sr, 1); GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, (scene_graph ? "[Render] Attaching new scene\n" : "[Render] Detaching scene\n")); if (sr->audio_renderer && (sr->scene != scene_graph)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting audio render\n")); gf_sr_ar_reset(sr->audio_renderer); }#ifdef GF_SR_EVENT_QUEUE GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting event queue\n")); 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); }#endif GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting render module\n")); /*reset main surface*/ sr->visual_renderer->SceneReset(sr->visual_renderer); /*set current graph*/ sr->scene = scene_graph; do_notif = 0; if (scene_graph) {#ifndef GPAC_DISABLE_SVG SVG_Length *w, *h;#endif const char *opt; Bool is_svg = 0; u32 tag; GF_Node *top_node; Bool had_size_info = sr->has_size_info; /*get pixel size if any*/ gf_sg_get_scene_size_info(sr->scene, &width, &height); sr->has_size_info = (width && height) ? 1 : 0; if (sr->has_size_info != had_size_info) sr->scene_width = sr->scene_height = 0; /*default back color is black*/ if (! (sr->user->init_flags & GF_TERM_WINDOWLESS)) sr->back_color = 0xFF000000; top_node = gf_sg_get_root_node(sr->scene); tag = 0; if (top_node) tag = gf_node_get_tag(top_node);#ifndef GPAC_DISABLE_SVG w = h = NULL; if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) { GF_FieldInfo info; is_svg = 1; if (gf_svg_get_attribute_by_tag(top_node, TAG_SVG_ATT_width, 0, 0, &info)==GF_OK) w = info.far_ptr; if (gf_svg_get_attribute_by_tag(top_node, TAG_SVG_ATT_height, 0, 0, &info)==GF_OK) h = info.far_ptr; }#ifdef GPAC_ENABLE_SVG_SA else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) { SVG_SA_svgElement *root = (SVG_SA_svgElement *) top_node; is_svg = 1; w = &root->width; h = &root->height; }#endif#ifdef GPAC_ENABLE_SVG_SANI else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) { SVG_SANI_svgElement *root = (SVG_SANI_svgElement*) top_node; is_svg = 1; w = &root->width; h = &root->height; }#endif /*default back color is white*/ if (is_svg && ! (sr->user->init_flags & GF_TERM_WINDOWLESS)) sr->back_color = 0xFFFFFFFF; /*hack for SVG where size is set in %*/ if (!sr->has_size_info && w && h) { sr->has_size_info = 1; sr->aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN; if (w->type!=SVG_NUMBER_PERCENTAGE) { width = FIX2INT(convert_svg_length_to_user(sr, w) ); } else { width = 320; //FIX2INT(root->viewBox.width); } if (h->type!=SVG_NUMBER_PERCENTAGE) { height = FIX2INT(convert_svg_length_to_user(sr, h) ); } else { height = 240; //FIX2INT(root->viewBox.height); } }#endif /*default back color is key color*/ if (sr->user->init_flags & GF_TERM_WINDOWLESS) { opt = gf_cfg_get_key(sr->user->config, "Rendering", "ColorKey"); if (opt) { u32 r, g, b, a; sscanf(opt, "%02X%02X%02X%02X", &a, &r, &g, &b); sr->back_color = GF_COL_ARGB(0xFF, r, g, b); } } /*set scene size only if different, otherwise keep scaling/FS*/ if ( !width || (sr->scene_width!=width) || !height || (sr->scene_height!=height)) { do_notif = sr->has_size_info || (!sr->scene_width && !sr->scene_height); SR_SetSceneSize(sr, width, height); /*get actual size in pixels*/ width = sr->scene_width; height = sr->scene_height; if (!sr->user->os_window_handler) { /*only notify user if we are attached to a window*/ do_notif = 0; if (sr->video_out->max_screen_width && (width > sr->video_out->max_screen_width)) width = sr->video_out->max_screen_width; if (sr->video_out->max_screen_height && (height > sr->video_out->max_screen_height)) height = sr->video_out->max_screen_height; gf_sr_set_size(sr,width, height); } } } SR_ResetFrameRate(sr); #ifdef GF_SR_EVENT_QUEUE gf_mx_v(sr->ev_mx);#endif gf_sr_lock(sr, 0); /*here's a nasty trick: the app may respond to this by calling a gf_sr_set_size from a different thread, but in an atomic way (typically happen on Win32 when changing the window size). WE MUST NOTIFY THE SIZE CHANGE AFTER RELEASING THE RENDERER MUTEX*/ if (do_notif && sr->user->EventProc) { GF_Event evt; evt.type = GF_EVENT_SCENE_SIZE; evt.size.width = width; evt.size.height = height; sr->user->EventProc(sr->user->opaque, &evt); } if (scene_graph) sr->draw_next_frame = 1; return GF_OK;}void gf_sr_lock_audio(GF_Renderer *sr, Bool doLock){ if (sr->audio_renderer) { gf_mixer_lock(sr->audio_renderer->mixer, doLock); }}GF_EXPORTvoid gf_sr_lock(GF_Renderer *sr, Bool doLock){ //GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Render] Thread ID %d is %s the scene\n", gf_th_id(), doLock ? "locking" : "unlocking" )); if (doLock) gf_mx_p(sr->mx); else { gf_mx_v(sr->mx); }}GF_Err gf_sr_set_size(GF_Renderer *sr, u32 NewWidth, u32 NewHeight){ Bool lock_ok; if (!NewWidth || !NewHeight) { sr->override_size_flags &= ~2; return GF_OK; } /*EXTRA CARE HERE: the caller (user app) is likely a different thread than the renderer one, and depending on window manager we may get called here as a result of a message sent to user but not yet returned */ lock_ok = gf_mx_try_lock(sr->mx); sr->new_width = NewWidth; sr->new_height = NewHeight; sr->msg_type |= GF_SR_CFG_SET_SIZE; /*if same size only request for video setup */ if ((sr->width == NewWidth) && (sr->height == NewHeight) ) sr->msg_type |= GF_SR_CFG_WINDOWSIZE_NOTIF; if (lock_ok) gf_sr_lock(sr, 0); return GF_OK;}void SR_ReloadConfig(GF_Renderer *sr){ const char *sOpt, *dr_name; /*changing drivers needs exclusive access*/ gf_sr_lock(sr, 1); sOpt = gf_cfg_get_key(sr->user->config, "Rendering", "ForceSceneSize"); if (sOpt && ! stricmp(sOpt, "yes")) { sr->override_size_flags = 1; } else { sr->override_size_flags = 0; } sOpt = gf_cfg_get_key(sr->user->config, "Rendering", "AntiAlias"); if (sOpt) { if (! stricmp(sOpt, "None")) gf_sr_set_option(sr, GF_OPT_ANTIALIAS, GF_ANTIALIAS_NONE); else if (! stricmp(sOpt, "Text")) gf_sr_set_option(sr, GF_OPT_ANTIALIAS, GF_ANTIALIAS_TEXT); else gf_sr_set_option(sr, GF_OPT_ANTIALIAS, GF_ANTIALIAS_FULL); } else { gf_cfg_set_key(sr->user->config, "Rendering", "AntiAlias", "All"); gf_sr_set_option(sr, GF_OPT_ANTIALIAS, GF_ANTIALIAS_FULL); } sOpt = gf_cfg_get_key(sr->user->config, "Rendering", "StressMode"); gf_sr_set_option(sr, GF_OPT_STRESS_MODE, (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0); sOpt = gf_cfg_get_key(sr->user->config, "Rendering", "FastRender"); gf_sr_set_option(sr, GF_OPT_HIGHSPEED, (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0); sOpt = gf_cfg_get_key(sr->user->config, "Rendering", "BoundingVolume"); if (sOpt) { if (! stricmp(sOpt, "Box")) gf_sr_set_option(sr, GF_OPT_DRAW_BOUNDS, GF_BOUNDS_BOX); else if (! stricmp(sOpt, "AABB")) gf_sr_set_option(sr, GF_OPT_DRAW_BOUNDS, GF_BOUNDS_AABB); else gf_sr_set_option(sr, GF_OPT_DRAW_BOUNDS, GF_BOUNDS_NONE); } else { gf_cfg_set_key(sr->user->config, "Rendering", "BoundingVolume", "None"); gf_sr_set_option(sr, GF_OPT_DRAW_BOUNDS, GF_BOUNDS_NONE); } sOpt = gf_cfg_get_key(sr->user->config, "FontEngine", "DriverName"); if (sOpt && sr->font_engine) { dr_name = sr->font_engine->module_name; if (stricmp(dr_name, sOpt)) SR_SetFontEngine(sr); } sOpt = gf_cfg_get_key(sr->user->config, "FontEngine", "TextureTextMode"); if (sOpt && !stricmp(sOpt, "Always")) sr->texture_text_mode = GF_TEXTURE_TEXT_ALWAYS; else if (sOpt && !stricmp(sOpt, "3D")) sr->texture_text_mode = GF_TEXTURE_TEXT_3D; else sr->texture_text_mode = GF_TEXTURE_TEXT_NONE; if (sr->audio_renderer) { sOpt = gf_cfg_get_key(sr->user->config, "Audio", "NoResync"); if (sOpt && !stricmp(sOpt, "yes")) sr->audio_renderer->flags |= GF_SR_AUDIO_NO_RESYNC; else sr->audio_renderer->flags &= ~GF_SR_AUDIO_NO_RESYNC; sOpt = gf_cfg_get_key(sr->user->config, "Audio", "DisableMultiChannel"); if (sOpt && !stricmp(sOpt, "yes")) sr->audio_renderer->flags |= GF_SR_AUDIO_NO_MULTI_CH; else sr->audio_renderer->flags &= ~GF_SR_AUDIO_NO_MULTI_CH; } sr->draw_next_frame = 1; gf_sr_lock(sr, 0);}GF_Err gf_sr_set_option(GF_Renderer *sr, u32 type, u32 value){ GF_Err e; gf_sr_lock(sr, 1); e = GF_OK; switch (type) { case GF_OPT_PLAY_STATE: gf_sr_pause(sr, value); break; case GF_OPT_AUDIO_VOLUME: gf_sr_ar_set_volume(sr->audio_renderer, value); break; case GF_OPT_AUDIO_PAN: gf_sr_ar_set_pan(sr->audio_renderer, value); break; case GF_OPT_OVERRIDE_SIZE: sr->override_size_flags = value ? 1 : 0; sr->draw_next_frame = 1; break; case GF_OPT_STRESS_MODE: sr->stress_mode = value; break; case GF_OPT_ANTIALIAS: sr->antiAlias = value; sr->draw_next_frame = 1; break; case GF_OPT_HIGHSPEED: sr->high_speed = value; sr->draw_next_frame = 1; break; case GF_OPT_DRAW_BOUNDS: sr->draw_bvol = value; sr->draw_next_frame = 1; break; case GF_OPT_TEXTURE_TEXT: sr->texture_text_mode = value; sr->draw_next_frame = 1; break; case GF_OPT_ASPECT_RATIO: sr->aspect_ratio = value; sr->msg_type |= GF_SR_CFG_AR; break; case GF_OPT_INTERACTION_LEVEL: sr->interaction_level = value; sr->draw_next_frame = 1; break; case GF_OPT_REFRESH: sr->reset_graphics = value; break; case GF_OPT_FULLSCREEN: if (sr->fullscreen != value) sr->msg_type |= GF_SR_CFG_FULLSCREEN; sr->draw_next_frame = 1; break; case GF_OPT_ORIGINAL_VIEW: e = sr->visual_renderer->SetOption(sr->visual_renderer, type, value); gf_sr_set_size(sr, sr->scene_width, sr->scene_height); break; case GF_OPT_VISIBLE: sr->is_hidden = !value; if (sr->video_out->ProcessEvent) { GF_Event evt; evt.type = GF_EVENT_SHOWHIDE; evt.show.show_type = value ? 1 : 0; e = sr->video_out->ProcessEvent(sr->video_out, &evt); } sr->draw_next_frame = 1; break; case GF_OPT_FREEZE_DISPLAY: sr->freeze_display = value; sr->draw_next_frame = 1; break; case GF_OPT_RELOAD_CONFIG: SR_ReloadConfig(sr); sr->draw_next_frame = 1; default: e = sr->visual_renderer->SetOption(sr->visual_renderer, type, value); break; } gf_sr_lock(sr, 0); return e;}u32 gf_sr_get_option(GF_Renderer *sr, u32 type){ switch (type) { case GF_OPT_PLAY_STATE: return sr->paused ? 1 : 0; case GF_OPT_OVERRIDE_SIZE: return (sr->override_size_flags & 1) ? 1 : 0; case GF_OPT_IS_FINISHED: { if (sr->interaction_sensors) return 0; if (gf_list_count(sr->time_nodes)) return 0; return 1; } case GF_OPT_STRESS_MODE: return sr->stress_mode; case GF_OPT_AUDIO_VOLUME: return sr->audio_renderer->volume; case GF_OPT_AUDIO_PAN: return sr->audio_renderer->pan; case GF_OPT_ANTIALIAS: return sr->antiAlias; case GF_OPT_HIGHSPEED: return sr->high_speed; case GF_OPT_ASPECT_RATIO: return sr->aspect_ratio; case GF_OPT_FULLSCREEN: return sr->fullscreen; case GF_OPT_INTERACTION_LEVEL: return sr->interaction_level; case GF_OPT_VISIBLE: return !sr->is_hidden; case GF_OPT_FREEZE_DISPLAY: return sr->freeze_display; case GF_OPT_TEXTURE_TEXT: return sr->texture_text_mode; default: return sr->visual_renderer->GetOption(sr->visual_renderer, type); }}void gf_sr_map_point(GF_Renderer *sr, s32 X, s32 Y, Fixed *bifsX, Fixed *bifsY){ /*coordinates are in user-like OS....*/ X = X - sr->width/2; Y = sr->height/2 - Y; *bifsX = INT2FIX(X); *bifsY = INT2FIX(Y);}void SR_SetFontEngine(GF_Renderer *sr){ const char *sOpt; u32 i, count; GF_FontRaster *ifce; ifce = NULL; sOpt = gf_cfg_get_key(sr->user->config, "FontEngine", "DriverName"); if (sOpt) ifce = (GF_FontRaster *) gf_modules_load_interface_by_name(sr->user->modules, sOpt, GF_FONT_RASTER_INTERFACE); if (!ifce) { count = gf_modules_get_count(sr->user->modules); for (i=0; i<count; i++) { ifce = (GF_FontRaster *) gf_modules_load_interface(sr->user->modules, i, GF_FONT_RASTER_INTERFACE); if (ifce) { gf_cfg_set_key(sr->user->config, "FontEngine", "DriverName", ifce->module_name); sOpt = ifce->module_name; break; } } } if (!ifce) return; /*cannot init font engine*/ if (ifce->init_font_engine(ifce) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)ifce); return; } /*shutdown current*/ gf_sr_lock(sr, 1); if (sr->font_engine) { sr->font_engine->shutdown_font_engine(sr->font_engine); gf_modules_close_interface((GF_BaseInterface *)sr->font_engine); } sr->font_engine = ifce; /*success*/ gf_cfg_set_key(sr->user->config, "FontEngine", "DriverName", sOpt); sr->draw_next_frame = 1; gf_sr_lock(sr, 0);}GF_Err gf_sr_get_screen_buffer(GF_Renderer *sr, GF_VideoSurface *framebuffer){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -