📄 render2d.c
字号:
/*load options*/ sOpt = gf_cfg_get_key(compositor->user->config, "Render2D", "DirectRender"); if (sOpt && ! stricmp(sOpt, "yes")) sr->top_effect->trav_flags |= TF_RENDER_DIRECT; else sr->top_effect->trav_flags &= ~TF_RENDER_DIRECT; sOpt = gf_cfg_get_key(compositor->user->config, "Render2D", "ScalableZoom"); sr->scalable_zoom = (!sOpt || !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_cfg_get_key(compositor->user->config, "Render2D", "DisableYUV"); sr->enable_yuv_hw = (sOpt && !stricmp(sOpt, "yes") ) ? 0 : 1; return GF_OK;}void R2D_UnloadRenderer(GF_VisualRenderer *vr){ Render2D *sr = (Render2D *)vr->user_priv; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render2D] Destroying 2D renderer\n")); gf_node_unregister(sr->focus_highlight->node, NULL); drawable_del_ex(sr->focus_highlight, sr); DeleteVisualSurface2D(sr->surface); gf_list_del(sr->sensors); gf_list_del(sr->surfaces_2D); gf_list_del(sr->strike_bank); effect_delete(sr->top_effect); free(sr); vr->user_priv = NULL; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render2D] 2D renderer destroyed\n"));}GF_Err R2D_AllocTexture(GF_TextureHandler *hdl){ if (hdl->hwtx) return GF_BAD_PARAM; hdl->hwtx = hdl->compositor->r2d->stencil_new(hdl->compositor->r2d, GF_STENCIL_TEXTURE); return GF_OK;}void R2D_ReleaseTexture(GF_TextureHandler *hdl){ if (hdl->hwtx) hdl->compositor->r2d->stencil_delete(hdl->hwtx); hdl->hwtx = NULL;}GF_Err R2D_SetTextureData(GF_TextureHandler *hdl){ Render2D *sr = (Render2D *) hdl->compositor->visual_renderer->user_priv; return hdl->compositor->r2d->stencil_set_texture(hdl->hwtx, hdl->data, hdl->width, hdl->height, hdl->stride, (GF_PixelFormat) hdl->pixelformat, (GF_PixelFormat) sr->compositor->video_out->pixel_format, 0);}/*no module used HW for texturing for now*/void R2D_TextureHWReset(GF_TextureHandler *hdl){ return;}void R2D_GraphicsReset(GF_VisualRenderer *vr){}void R2D_ReloadConfig(GF_VisualRenderer *vr){ const char *sOpt; Render2D *sr = (Render2D *)vr->user_priv; gf_sr_lock(sr->compositor, 1); sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render2D", "DirectRender"); if (sOpt && !stricmp(sOpt, "yes") ) { sr->top_effect->trav_flags |= TF_RENDER_DIRECT; } else { sr->top_effect->trav_flags &= ~TF_RENDER_DIRECT; } sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render2D", "ScalableZoom"); sr->scalable_zoom = (!sOpt || !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render2D", "DisableYUV"); sr->enable_yuv_hw = (sOpt && !stricmp(sOpt, "yes") ) ? 0 : 1; sr->compositor->msg_type |= GF_SR_CFG_AR; sr->compositor->draw_next_frame = 1; gf_sr_lock(sr->compositor, 0);}GF_Err R2D_SetOption(GF_VisualRenderer *vr, u32 option, u32 value){ Render2D *sr = (Render2D *)vr->user_priv; switch (option) { case GF_OPT_DIRECT_RENDER: gf_sr_lock(sr->compositor, 1); if (value) { sr->top_effect->trav_flags |= TF_RENDER_DIRECT; } else { sr->top_effect->trav_flags &= ~TF_RENDER_DIRECT; } /*force redraw*/ gf_sr_invalidate(sr->compositor, NULL); gf_sr_lock(sr->compositor, 0); return GF_OK; case GF_OPT_SCALABLE_ZOOM: sr->scalable_zoom = value; /*emulate size message to force AR recompute*/ sr->compositor->msg_type |= GF_SR_CFG_AR; return GF_OK; case GF_OPT_YUV_HARDWARE: sr->enable_yuv_hw = value; return GF_OK; case GF_OPT_RELOAD_CONFIG: R2D_ReloadConfig(vr); return GF_OK; case GF_OPT_ORIGINAL_VIEW: R2D_SetUserTransform(sr, FIX_ONE, 0, 0, 1); return GF_OK; case GF_OPT_NAVIGATION_TYPE: R2D_SetUserTransform(sr, FIX_ONE, 0, 0, 1); return GF_OK; case GF_OPT_NAVIGATION: if (sr->navigation_disabled) return GF_NOT_SUPPORTED; if ((value!=GF_NAVIGATE_NONE) && (value!=GF_NAVIGATE_SLIDE)) return GF_NOT_SUPPORTED; sr->navigate_mode = value; return GF_OK; case GF_OPT_HEADLIGHT: return GF_NOT_SUPPORTED; case GF_OPT_COLLISION: return GF_NOT_SUPPORTED; case GF_OPT_GRAVITY: return GF_NOT_SUPPORTED; default: return GF_BAD_PARAM; }}u32 R2D_GetOption(GF_VisualRenderer *vr, u32 option){ Render2D *sr = (Render2D *)vr->user_priv; switch (option) { case GF_OPT_DIRECT_RENDER: return (sr->top_effect->trav_flags & TF_RENDER_DIRECT) ? 1 : 0; case GF_OPT_SCALABLE_ZOOM: return sr->scalable_zoom; case GF_OPT_YUV_HARDWARE: return sr->enable_yuv_hw; case GF_OPT_YUV_FORMAT: return sr->enable_yuv_hw ? sr->compositor->video_out->yuv_pixel_format : 0; case GF_OPT_NAVIGATION_TYPE: return sr->navigation_disabled ? GF_NAVIGATE_TYPE_NONE : GF_NAVIGATE_TYPE_2D; case GF_OPT_NAVIGATION: return sr->navigate_mode; case GF_OPT_HEADLIGHT: return 0; case GF_OPT_COLLISION: return GF_COLLISION_NONE; case GF_OPT_GRAVITY: return 0; default: return 0; }}/*render inline scene*/static void R2D_RenderInlineMPEG4(GF_VisualRenderer *vr, GF_Node *inline_parent, GF_Node *inline_root, void *rs){ Bool use_pm; u32 h, w; GF_Matrix2D mx_bck, mx; GF_SceneGraph *in_scene; RenderEffect2D *eff = (RenderEffect2D *)rs; in_scene = gf_node_get_graph(inline_root); use_pm = gf_sg_use_pixel_metrics(in_scene); if (use_pm == eff->is_pixel_metrics) { gf_node_render(inline_root, rs); return; } gf_mx2d_copy(mx_bck, eff->transform); /*override aspect ratio if any size info is given in the scene*/ if (gf_sg_get_scene_size_info(in_scene, &w, &h)) { Fixed scale = INT2FIX( MIN(w, h) / 2); if (scale) eff->min_hsize = scale; } gf_mx2d_init(mx); /*apply meterMetrics<->pixelMetrics scale*/ if (!use_pm) { gf_mx2d_add_scale(&mx, eff->min_hsize, eff->min_hsize); } else { Fixed inv_scale = gf_invfix(eff->min_hsize); gf_mx2d_add_scale(&mx, inv_scale, inv_scale); } eff->is_pixel_metrics = use_pm; gf_mx2d_add_matrix(&eff->transform, &mx); gf_node_render(inline_root, rs); eff->is_pixel_metrics = !use_pm; gf_mx2d_copy(eff->transform, mx_bck);}void R2D_RenderInline(GF_VisualRenderer *vr, GF_Node *inline_parent, GF_Node *inline_root, void *rs){ switch (gf_node_get_tag(inline_parent)) {#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_animation: { u32 tag = gf_node_get_tag(inline_root); if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) { R2D_render_svg_sa_animation(inline_parent, inline_root, rs); } else { RenderEffect2D *eff = (RenderEffect2D *)rs; GF_Matrix2D mx, bck; gf_mx2d_copy(bck, eff->transform); gf_mx2d_init(mx); /*match both coordinate systems: 1- we decide SVG center is aligned with BIFS center, so no translation 2- since parent is SVG (top-left origin), flip the entire subscene */ gf_mx2d_add_scale(&mx, 1, -1); gf_mx2d_pre_multiply(&eff->transform, &mx); R2D_RenderInlineMPEG4(vr, inline_parent, inline_root, rs); gf_mx2d_copy(eff->transform, bck); } } break; case TAG_SVG_SA_use: R2D_render_svg_sa_use(inline_parent, inline_root, rs); break;#endif#ifdef GPAC_ENABLE_SVG_SANI case TAG_SVG_SANI_use: r2d_render_svg_sani_use(inline_parent, inline_root, rs); break;#endif case TAG_SVG_use: r2d_render_svg_use(inline_parent, inline_root, rs); break;#endif default: if (!inline_root) return; R2D_RenderInlineMPEG4(vr, inline_parent, inline_root, rs); break; }}GF_Err R2D_GetScreenBuffer(GF_VisualRenderer *vr, GF_VideoSurface *framebuffer){ Render2D *sr = (Render2D *)vr->user_priv; return sr->compositor->video_out->LockBackBuffer(sr->compositor->video_out, framebuffer, 1);}GF_Err R2D_ReleaseScreenBuffer(GF_VisualRenderer *vr, GF_VideoSurface *framebuffer){ Render2D *sr = (Render2D *)vr->user_priv; return sr->compositor->video_out->LockBackBuffer(sr->compositor->video_out, framebuffer, 0);}static Bool R2D_ScriptAction(GF_VisualRenderer *vr, u32 type, GF_Node *n, GF_JSAPIParam *param){ Render2D *sr = (Render2D *)vr->user_priv; switch (type) { case GF_JSAPI_OP_GET_SCALE: param->val = sr->zoom; return 1; case GF_JSAPI_OP_SET_SCALE: R2D_SetUserTransform(sr, param->val, sr->trans_x, sr->trans_y, 0); return 1; case GF_JSAPI_OP_GET_ROTATION: param->val = gf_divfix(180*sr->rotation, GF_PI); return 1; case GF_JSAPI_OP_SET_ROTATION: sr->rotation = gf_mulfix(GF_PI, param->val/180); R2D_SetUserTransform(sr, sr->zoom, sr->trans_x, sr->trans_y, 0); return 1; case GF_JSAPI_OP_GET_TRANSLATE: param->pt.x = sr->trans_x; param->pt.y = sr->trans_y; return 1; case GF_JSAPI_OP_SET_TRANSLATE: R2D_SetUserTransform(sr, sr->zoom, param->pt.x, param->pt.y, 0); return 1; /*FIXME - better SMIL timelines support*/ case GF_JSAPI_OP_GET_TIME: param->time = gf_node_get_scene_time(n); return 1; case GF_JSAPI_OP_SET_TIME: /*seek_to(param->time);*/ return 0; /*FIXME - this will not work for inline docs, we will have to store the clipper at the <svg> level*/ case GF_JSAPI_OP_GET_VIEWPORT: param->rc = gf_rect_ft(&sr->surface->top_clipper); if (!sr->surface->center_coords) param->rc.y = param->rc.height - param->rc.y; return 1; case GF_JSAPI_OP_SET_FOCUS: sr->focus_node = param->node; return 1; case GF_JSAPI_OP_GET_FOCUS: param->node = sr->focus_node; return 1; /*same routine: traverse tree from root to target, collecting both bounds and transform matrix*/ case GF_JSAPI_OP_GET_LOCAL_BBOX: case GF_JSAPI_OP_GET_SCREEN_BBOX: case GF_JSAPI_OP_GET_TRANSFORM: { RenderEffect2D eff; memset(&eff, 0, sizeof(eff)); eff.traversing_mode = TRAVERSE_GET_BOUNDS; eff.surface = sr->surface; eff.for_node = n; gf_mx2d_init(eff.transform); gf_node_render(gf_sg_get_root_node(sr->compositor->scene), &eff); if (type==GF_JSAPI_OP_GET_LOCAL_BBOX) gf_bbox_from_rect(¶m->bbox, &eff.bounds); else if (type==GF_JSAPI_OP_GET_TRANSFORM) gf_mx_from_mx2d(¶m->mx, &eff.transform); else { gf_mx2d_apply_rect(&eff.transform, &eff.bounds); gf_bbox_from_rect(¶m->bbox, &eff.bounds); } } return 1; case GF_JSAPI_OP_LOAD_URL: { GF_Node *target; char *sub_url = strrchr(param->uri.url, '#'); if (!sub_url) return 0; target = gf_sg_find_node_by_name(gf_node_get_graph(n), sub_url+1); if (target && (gf_node_get_tag(target)==TAG_MPEG4_Viewport) ) { ((M_Viewport *)target)->set_bind = 1; ((M_Viewport *)target)->on_set_bind(n); return 1; } return 0; } } return 0;}GF_Err R2D_GetViewport(GF_VisualRenderer *vr, u32 viewpoint_idx, const char **outName, Bool *is_bound);GF_Err R2D_SetViewport(GF_VisualRenderer *vr, u32 viewpoint_idx, const char *viewpoint_name);GF_VisualRenderer *NewVisualRenderer(){ GF_VisualRenderer *sr; GF_SAFEALLOC(sr, GF_VisualRenderer); if (!sr) return NULL; sr->LoadRenderer = R2D_LoadRenderer; sr->UnloadRenderer = R2D_UnloadRenderer; sr->GraphicsReset = R2D_GraphicsReset; sr->NodeChanged = R2D_NodeChanged; sr->NodeInit = R2D_NodeInit; sr->DrawScene = R2D_DrawScene; sr->ExecuteEvent = R2D_ExecuteEvent; sr->RecomputeAR = R2D_RecomputeAR; sr->SceneReset = R2D_SceneReset; sr->RenderInline = R2D_RenderInline; sr->AllocTexture = R2D_AllocTexture; sr->ReleaseTexture = R2D_ReleaseTexture; sr->SetTextureData = R2D_SetTextureData; sr->TextureHWReset = R2D_TextureHWReset; sr->SetOption = R2D_SetOption; sr->GetOption = R2D_GetOption; sr->GetScreenBuffer = R2D_GetScreenBuffer; sr->ReleaseScreenBuffer = R2D_ReleaseScreenBuffer; sr->GetViewpoint = R2D_GetViewport; sr->SetViewpoint = R2D_SetViewport; sr->ScriptAction = R2D_ScriptAction; sr->user_priv = NULL; return sr;}#ifndef GPAC_STANDALONE_RENDER_2D/*interface create*/GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){ GF_VisualRenderer *sr; if (InterfaceType != GF_RENDERER_INTERFACE) return NULL; GF_SAFEALLOC(sr, GF_VisualRenderer); if (!sr) return NULL; GF_REGISTER_MODULE_INTERFACE(sr, GF_RENDERER_INTERFACE, "GPAC 2D Renderer", "gpac distribution"); sr->LoadRenderer = R2D_LoadRenderer; sr->UnloadRenderer = R2D_UnloadRenderer; sr->GraphicsReset = R2D_GraphicsReset; sr->NodeChanged = R2D_NodeChanged; sr->NodeInit = R2D_NodeInit; sr->DrawScene = R2D_DrawScene; sr->ExecuteEvent = R2D_ExecuteEvent; sr->RecomputeAR = R2D_RecomputeAR; sr->SceneReset = R2D_SceneReset; sr->RenderInline = R2D_RenderInline; sr->AllocTexture = R2D_AllocTexture; sr->ReleaseTexture = R2D_ReleaseTexture; sr->SetTextureData = R2D_SetTextureData; sr->TextureHWReset = R2D_TextureHWReset; sr->SetOption = R2D_SetOption; sr->GetOption = R2D_GetOption; sr->GetScreenBuffer = R2D_GetScreenBuffer; sr->ReleaseScreenBuffer = R2D_ReleaseScreenBuffer; sr->GetViewpoint = R2D_GetViewport; sr->SetViewpoint = R2D_SetViewport; sr->ScriptAction = R2D_ScriptAction; sr->user_priv = NULL; return (GF_BaseInterface *)sr;}/*interface destroy*/GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){ GF_VisualRenderer *rend = (GF_VisualRenderer *)ifce; if (rend->InterfaceType != GF_RENDERER_INTERFACE) return; if (rend->user_priv) R2D_UnloadRenderer(rend); free(rend);}/*interface query*/GF_EXPORTBool QueryInterface(u32 InterfaceType){ if (InterfaceType == GF_RENDERER_INTERFACE) return 1; return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -