From 0c447f4055811619e2e6c930c2664ae02fe84fe0 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sun, 4 Aug 2019 23:12:30 +0200 Subject: [PATCH] gs-effect: Use std::shared_ptr and track effect lifetime This fixes the case where the effect vanishes, but we still hold an invalid pointer to a parameter of that effect. With the new code, the effect will not vanish as long as an effect pointer exists. However, all effects must be created either through std::shared_ptr or std::make_shared. If they were not made through one of those means, the code will crash on the ->shared_from_this() call. --- source/filters/filter-blur.cpp | 28 +++---- source/filters/filter-color-grade.cpp | 18 ++--- source/filters/filter-displacement.cpp | 6 +- source/filters/filter-dynamic-mask.cpp | 10 +-- source/filters/filter-sdf-effects.cpp | 80 +++++++++---------- source/gfx/blur/gfx-blur-box-linear.cpp | 24 +++--- source/gfx/blur/gfx-blur-box.cpp | 50 ++++++------ source/gfx/blur/gfx-blur-dual-filtering.cpp | 16 ++-- source/gfx/blur/gfx-blur-gaussian-linear.cpp | 24 +++--- source/gfx/blur/gfx-blur-gaussian.cpp | 50 ++++++------ source/obs/gs/gs-effect.cpp | 82 ++++++++++---------- source/obs/gs/gs-effect.hpp | 29 +++---- source/obs/gs/gs-mipmapper.cpp | 8 +- 13 files changed, 215 insertions(+), 210 deletions(-) diff --git a/source/filters/filter-blur.cpp b/source/filters/filter-blur.cpp index 5c481d6a..9ecd49bf 100644 --- a/source/filters/filter-blur.cpp +++ b/source/filters/filter-blur.cpp @@ -337,31 +337,31 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptrhas_parameter("image_orig")) { - effect->get_parameter("image_orig").set_texture(original_texture); + effect->get_parameter("image_orig")->set_texture(original_texture); } if (effect->has_parameter("image_blur")) { - effect->get_parameter("image_blur").set_texture(blurred_texture); + effect->get_parameter("image_blur")->set_texture(blurred_texture); } // Region if (_mask.type == mask_type::Region) { if (effect->has_parameter("mask_region_left")) { - effect->get_parameter("mask_region_left").set_float(_mask.region.left); + effect->get_parameter("mask_region_left")->set_float(_mask.region.left); } if (effect->has_parameter("mask_region_right")) { - effect->get_parameter("mask_region_right").set_float(_mask.region.right); + effect->get_parameter("mask_region_right")->set_float(_mask.region.right); } if (effect->has_parameter("mask_region_top")) { - effect->get_parameter("mask_region_top").set_float(_mask.region.top); + effect->get_parameter("mask_region_top")->set_float(_mask.region.top); } if (effect->has_parameter("mask_region_bottom")) { - effect->get_parameter("mask_region_bottom").set_float(_mask.region.bottom); + effect->get_parameter("mask_region_bottom")->set_float(_mask.region.bottom); } if (effect->has_parameter("mask_region_feather")) { - effect->get_parameter("mask_region_feather").set_float(_mask.region.feather); + effect->get_parameter("mask_region_feather")->set_float(_mask.region.feather); } if (effect->has_parameter("mask_region_feather_shift")) { - effect->get_parameter("mask_region_feather_shift").set_float(_mask.region.feather_shift); + effect->get_parameter("mask_region_feather_shift")->set_float(_mask.region.feather_shift); } } @@ -369,9 +369,9 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptrhas_parameter("mask_image")) { if (_mask.image.texture) { - effect->get_parameter("mask_image").set_texture(_mask.image.texture); + effect->get_parameter("mask_image")->set_texture(_mask.image.texture); } else { - effect->get_parameter("mask_image").set_texture(nullptr); + effect->get_parameter("mask_image")->set_texture(nullptr); } } } @@ -380,19 +380,19 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptrhas_parameter("mask_image")) { if (_mask.source.texture) { - effect->get_parameter("mask_image").set_texture(_mask.source.texture); + effect->get_parameter("mask_image")->set_texture(_mask.source.texture); } else { - effect->get_parameter("mask_image").set_texture(nullptr); + effect->get_parameter("mask_image")->set_texture(nullptr); } } } // Shared if (effect->has_parameter("mask_color")) { - effect->get_parameter("mask_color").set_float4(_mask.color.r, _mask.color.g, _mask.color.b, _mask.color.a); + effect->get_parameter("mask_color")->set_float4(_mask.color.r, _mask.color.g, _mask.color.b, _mask.color.a); } if (effect->has_parameter("mask_multiplier")) { - effect->get_parameter("mask_multiplier").set_float(_mask.multiplier); + effect->get_parameter("mask_multiplier")->set_float(_mask.multiplier); } return true; diff --git a/source/filters/filter-color-grade.cpp b/source/filters/filter-color-grade.cpp index 1285e726..37062372 100644 --- a/source/filters/filter-color-grade.cpp +++ b/source/filters/filter-color-grade.cpp @@ -517,23 +517,23 @@ void filter::color_grade::color_grade_instance::video_render(gs_effect_t*) gs_ortho(0, static_cast(width), 0, static_cast(height), -1., 1.); if (_effect->has_parameter("image")) - _effect->get_parameter("image").set_texture(_tex_source); + _effect->get_parameter("image")->set_texture(_tex_source); if (_effect->has_parameter("pLift")) - _effect->get_parameter("pLift").set_float4(_lift); + _effect->get_parameter("pLift")->set_float4(_lift); if (_effect->has_parameter("pGamma")) - _effect->get_parameter("pGamma").set_float4(_gamma); + _effect->get_parameter("pGamma")->set_float4(_gamma); if (_effect->has_parameter("pGain")) - _effect->get_parameter("pGain").set_float4(_gain); + _effect->get_parameter("pGain")->set_float4(_gain); if (_effect->has_parameter("pOffset")) - _effect->get_parameter("pOffset").set_float4(_offset); + _effect->get_parameter("pOffset")->set_float4(_offset); if (_effect->has_parameter("pTintLow")) - _effect->get_parameter("pTintLow").set_float3(_tint_low); + _effect->get_parameter("pTintLow")->set_float3(_tint_low); if (_effect->has_parameter("pTintMid")) - _effect->get_parameter("pTintMid").set_float3(_tint_mid); + _effect->get_parameter("pTintMid")->set_float3(_tint_mid); if (_effect->has_parameter("pTintHig")) - _effect->get_parameter("pTintHig").set_float3(_tint_hig); + _effect->get_parameter("pTintHig")->set_float3(_tint_hig); if (_effect->has_parameter("pCorrection")) - _effect->get_parameter("pCorrection").set_float4(_correction); + _effect->get_parameter("pCorrection")->set_float4(_correction); while (gs_effect_loop(_effect->get_object(), "Draw")) { gs_draw_sprite(nullptr, 0, width, height); diff --git a/source/filters/filter-displacement.cpp b/source/filters/filter-displacement.cpp index 43b0123f..f327f7ed 100644 --- a/source/filters/filter-displacement.cpp +++ b/source/filters/filter-displacement.cpp @@ -279,13 +279,13 @@ void filter::displacement::displacement_instance::video_render(gs_effect_t*) if (_effect->has_parameter("texelScale")) { _effect->get_parameter("texelScale") - .set_float2(interp((1.0f / baseW), 1.0f, _distance), interp((1.0f / baseH), 1.0f, _distance)); + ->set_float2(interp((1.0f / baseW), 1.0f, _distance), interp((1.0f / baseH), 1.0f, _distance)); } if (_effect->has_parameter("displacementScale")) { - _effect->get_parameter("displacementScale").set_float2(_displacement_scale); + _effect->get_parameter("displacementScale")->set_float2(_displacement_scale); } if (_effect->has_parameter("displacementMap")) { - _effect->get_parameter("displacementMap").set_texture(_file_texture); + _effect->get_parameter("displacementMap")->set_texture(_file_texture); } obs_source_process_filter_end(_self, _effect->get_object(), baseW, baseH); diff --git a/source/filters/filter-dynamic-mask.cpp b/source/filters/filter-dynamic-mask.cpp index 6e47f24b..d82a5d1e 100644 --- a/source/filters/filter-dynamic-mask.cpp +++ b/source/filters/filter-dynamic-mask.cpp @@ -451,12 +451,12 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP); gs_ortho(0, (float)width, 0, (float)height, -1., 1.); - this->_effect->get_parameter("pMaskInputA").set_texture(this->_filter_texture); - this->_effect->get_parameter("pMaskInputB").set_texture(this->_input_texture); + this->_effect->get_parameter("pMaskInputA")->set_texture(this->_filter_texture); + this->_effect->get_parameter("pMaskInputB")->set_texture(this->_input_texture); - this->_effect->get_parameter("pMaskBase").set_float4(this->_precalc.base); - this->_effect->get_parameter("pMaskMatrix").set_matrix(this->_precalc.matrix); - this->_effect->get_parameter("pMaskMultiplier").set_float4(this->_precalc.scale); + this->_effect->get_parameter("pMaskBase")->set_float4(this->_precalc.base); + this->_effect->get_parameter("pMaskMatrix")->set_matrix(this->_precalc.matrix); + this->_effect->get_parameter("pMaskMultiplier")->set_float4(this->_precalc.scale); while (gs_effect_loop(this->_effect->get_object(), "Mask")) { gs_draw_sprite(0, 0, width, height); diff --git a/source/filters/filter-sdf-effects.cpp b/source/filters/filter-sdf-effects.cpp index 2863cc21..08266b59 100644 --- a/source/filters/filter-sdf-effects.cpp +++ b/source/filters/filter-sdf-effects.cpp @@ -725,10 +725,10 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect gs_ortho(0, (float)sdfW, 0, (float)sdfH, -1, 1); gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0); - sdf_effect->get_parameter("_image").set_texture(this->_source_texture); - sdf_effect->get_parameter("_size").set_float2(float_t(sdfW), float_t(sdfH)); - sdf_effect->get_parameter("_sdf").set_texture(this->_sdf_texture); - sdf_effect->get_parameter("_threshold").set_float(this->_sdf_threshold); + sdf_effect->get_parameter("_image")->set_texture(this->_source_texture); + sdf_effect->get_parameter("_size")->set_float2(float_t(sdfW), float_t(sdfH)); + sdf_effect->get_parameter("_sdf")->set_texture(this->_sdf_texture); + sdf_effect->get_parameter("_threshold")->set_float(this->_sdf_threshold); while (gs_effect_loop(sdf_effect->get_object(), "Draw")) { gs_draw_sprite(this->_sdf_texture->get_object(), 0, uint32_t(sdfW), uint32_t(sdfH)); @@ -793,66 +793,66 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect gs_enable_blending(true); gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE); if (this->_outer_shadow) { - consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); - consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); - consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); - consumer_effect->get_parameter("pShadowColor").set_float4(this->_outer_shadow_color); - consumer_effect->get_parameter("pShadowMin").set_float(this->_outer_shadow_range_min); - consumer_effect->get_parameter("pShadowMax").set_float(this->_outer_shadow_range_max); + consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture); + consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold); + consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object()); + consumer_effect->get_parameter("pShadowColor")->set_float4(this->_outer_shadow_color); + consumer_effect->get_parameter("pShadowMin")->set_float(this->_outer_shadow_range_min); + consumer_effect->get_parameter("pShadowMax")->set_float(this->_outer_shadow_range_max); consumer_effect->get_parameter("pShadowOffset") - .set_float2(this->_outer_shadow_offset_x / float_t(baseW), + ->set_float2(this->_outer_shadow_offset_x / float_t(baseW), this->_outer_shadow_offset_y / float_t(baseH)); while (gs_effect_loop(consumer_effect->get_object(), "ShadowOuter")) { gs_draw_sprite(0, 0, 1, 1); } } if (this->_inner_shadow) { - consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); - consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); - consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); - consumer_effect->get_parameter("pShadowColor").set_float4(this->_inner_shadow_color); - consumer_effect->get_parameter("pShadowMin").set_float(this->_inner_shadow_range_min); - consumer_effect->get_parameter("pShadowMax").set_float(this->_inner_shadow_range_max); + consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture); + consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold); + consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object()); + consumer_effect->get_parameter("pShadowColor")->set_float4(this->_inner_shadow_color); + consumer_effect->get_parameter("pShadowMin")->set_float(this->_inner_shadow_range_min); + consumer_effect->get_parameter("pShadowMax")->set_float(this->_inner_shadow_range_max); consumer_effect->get_parameter("pShadowOffset") - .set_float2(this->_inner_shadow_offset_x / float_t(baseW), + ->set_float2(this->_inner_shadow_offset_x / float_t(baseW), this->_inner_shadow_offset_y / float_t(baseH)); while (gs_effect_loop(consumer_effect->get_object(), "ShadowInner")) { gs_draw_sprite(0, 0, 1, 1); } } if (this->_outer_glow) { - consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); - consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); - consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); - consumer_effect->get_parameter("pGlowColor").set_float4(this->_outer_glow_color); - consumer_effect->get_parameter("pGlowWidth").set_float(this->_outer_glow_width); - consumer_effect->get_parameter("pGlowSharpness").set_float(this->_outer_glow_sharpness); - consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->_outer_glow_sharpness_inv); + consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture); + consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold); + consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object()); + consumer_effect->get_parameter("pGlowColor")->set_float4(this->_outer_glow_color); + consumer_effect->get_parameter("pGlowWidth")->set_float(this->_outer_glow_width); + consumer_effect->get_parameter("pGlowSharpness")->set_float(this->_outer_glow_sharpness); + consumer_effect->get_parameter("pGlowSharpnessInverse")->set_float(this->_outer_glow_sharpness_inv); while (gs_effect_loop(consumer_effect->get_object(), "GlowOuter")) { gs_draw_sprite(0, 0, 1, 1); } } if (this->_inner_glow) { - consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); - consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); - consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); - consumer_effect->get_parameter("pGlowColor").set_float4(this->_inner_glow_color); - consumer_effect->get_parameter("pGlowWidth").set_float(this->_inner_glow_width); - consumer_effect->get_parameter("pGlowSharpness").set_float(this->_inner_glow_sharpness); - consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->_inner_glow_sharpness_inv); + consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture); + consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold); + consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object()); + consumer_effect->get_parameter("pGlowColor")->set_float4(this->_inner_glow_color); + consumer_effect->get_parameter("pGlowWidth")->set_float(this->_inner_glow_width); + consumer_effect->get_parameter("pGlowSharpness")->set_float(this->_inner_glow_sharpness); + consumer_effect->get_parameter("pGlowSharpnessInverse")->set_float(this->_inner_glow_sharpness_inv); while (gs_effect_loop(consumer_effect->get_object(), "GlowInner")) { gs_draw_sprite(0, 0, 1, 1); } } if (this->_outline) { - consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); - consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); - consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); - consumer_effect->get_parameter("pOutlineColor").set_float4(this->_outline_color); - consumer_effect->get_parameter("pOutlineWidth").set_float(this->_outline_width); - consumer_effect->get_parameter("pOutlineOffset").set_float(this->_outline_offset); - consumer_effect->get_parameter("pOutlineSharpness").set_float(this->_outline_sharpness); - consumer_effect->get_parameter("pOutlineSharpnessInverse").set_float(this->_outline_sharpness_inv); + consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture); + consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold); + consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object()); + consumer_effect->get_parameter("pOutlineColor")->set_float4(this->_outline_color); + consumer_effect->get_parameter("pOutlineWidth")->set_float(this->_outline_width); + consumer_effect->get_parameter("pOutlineOffset")->set_float(this->_outline_offset); + consumer_effect->get_parameter("pOutlineSharpness")->set_float(this->_outline_sharpness); + consumer_effect->get_parameter("pOutlineSharpnessInverse")->set_float(this->_outline_sharpness_inv); while (gs_effect_loop(consumer_effect->get_object(), "Outline")) { gs_draw_sprite(0, 0, 1, 1); } diff --git a/source/gfx/blur/gfx-blur-box-linear.cpp b/source/gfx/blur/gfx-blur-box-linear.cpp index 99374644..3b094b6c 100644 --- a/source/gfx/blur/gfx-blur-box-linear.cpp +++ b/source/gfx/blur/gfx-blur-box-linear.cpp @@ -265,11 +265,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render() std::shared_ptr<::gs::effect> effect = _data->get_effect(); if (effect) { // Pass 1 - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); { auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); @@ -280,8 +280,8 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render() } // Pass 2 - effect->get_parameter("pImage").set_texture(_rendertarget2->get_texture()); - effect->get_parameter("pImageTexel").set_float2(0., float_t(1.f / height)); + effect->get_parameter("pImage")->set_texture(_rendertarget2->get_texture()); + effect->get_parameter("pImageTexel")->set_float2(0., float_t(1.f / height)); { auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); @@ -341,12 +341,12 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render() // One Pass Blur std::shared_ptr<::gs::effect> effect = _data->get_effect(); if (effect) { - effect->get_parameter("pImage").set_texture(_input_texture); + effect->get_parameter("pImage")->set_texture(_input_texture); effect->get_parameter("pImageTexel") - .set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle))); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); + ->set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle))); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); { auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); diff --git a/source/gfx/blur/gfx-blur-box.cpp b/source/gfx/blur/gfx-blur-box.cpp index 6be84b2b..6b2a832f 100644 --- a/source/gfx/blur/gfx-blur-box.cpp +++ b/source/gfx/blur/gfx-blur-box.cpp @@ -273,11 +273,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render() std::shared_ptr<::gs::effect> effect = _data->get_effect(); if (effect) { // Pass 1 - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); { auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); @@ -288,8 +288,8 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render() } // Pass 2 - effect->get_parameter("pImage").set_texture(_rendertarget2->get_texture()); - effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height)); + effect->get_parameter("pImage")->set_texture(_rendertarget2->get_texture()); + effect->get_parameter("pImageTexel")->set_float2(0.f, float_t(1.f / height)); { auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); @@ -349,12 +349,12 @@ std::shared_ptr<::gs::texture> gfx::blur::box_directional::render() // One Pass Blur std::shared_ptr<::gs::effect> effect = _data->get_effect(); if (effect) { - effect->get_parameter("pImage").set_texture(_input_texture); + effect->get_parameter("pImage")->set_texture(_input_texture); effect->get_parameter("pImageTexel") - .set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle))); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); + ->set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle))); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); { auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); @@ -419,13 +419,13 @@ std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render() // One Pass Blur std::shared_ptr<::gs::effect> effect = _data->get_effect(); if (effect) { - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); - effect->get_parameter("pAngle").set_float(float_t(_angle / _size)); - effect->get_parameter("pCenter").set_float2(float_t(_center.first), float_t(_center.second)); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height)); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); + effect->get_parameter("pAngle")->set_float(float_t(_angle / _size)); + effect->get_parameter("pCenter")->set_float2(float_t(_center.first), float_t(_center.second)); { auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); @@ -480,12 +480,12 @@ std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render() // One Pass Blur std::shared_ptr<::gs::effect> effect = _data->get_effect(); if (effect) { - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); - effect->get_parameter("pCenter").set_float2(float_t(_center.first), float_t(_center.second)); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height)); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); + effect->get_parameter("pCenter")->set_float2(float_t(_center.first), float_t(_center.second)); { auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); diff --git a/source/gfx/blur/gfx-blur-dual-filtering.cpp b/source/gfx/blur/gfx-blur-dual-filtering.cpp index 6b150e52..788d4d97 100644 --- a/source/gfx/blur/gfx-blur-dual-filtering.cpp +++ b/source/gfx/blur/gfx-blur-dual-filtering.cpp @@ -263,10 +263,10 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render() } // Apply - effect->get_parameter("pImage").set_texture(tex_cur); - effect->get_parameter("pImageSize").set_float2(float_t(width), float_t(height)); - effect->get_parameter("pImageTexel").set_float2(1.0f / width, 1.0f / height); - effect->get_parameter("pImageHalfTexel").set_float2(0.5f / width, 0.5f / height); + effect->get_parameter("pImage")->set_texture(tex_cur); + effect->get_parameter("pImageSize")->set_float2(float_t(width), float_t(height)); + effect->get_parameter("pImageTexel")->set_float2(1.0f / width, 1.0f / height); + effect->get_parameter("pImageHalfTexel")->set_float2(0.5f / width, 0.5f / height); { auto op = _rendertargets[n]->render(width, height); @@ -287,10 +287,10 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render() uint32_t height = tex_cur->get_height(); // Apply - effect->get_parameter("pImage").set_texture(tex_cur); - effect->get_parameter("pImageSize").set_float2(float_t(width), float_t(height)); - effect->get_parameter("pImageTexel").set_float2(1.0f / width, 1.0f / height); - effect->get_parameter("pImageHalfTexel").set_float2(0.5f / width, 0.5f / height); + effect->get_parameter("pImage")->set_texture(tex_cur); + effect->get_parameter("pImageSize")->set_float2(float_t(width), float_t(height)); + effect->get_parameter("pImageTexel")->set_float2(1.0f / width, 1.0f / height); + effect->get_parameter("pImageHalfTexel")->set_float2(0.5f / width, 0.5f / height); // Increase Size width *= 2; diff --git a/source/gfx/blur/gfx-blur-gaussian-linear.cpp b/source/gfx/blur/gfx-blur-gaussian-linear.cpp index 8a352fdc..0ca06f38 100644 --- a/source/gfx/blur/gfx-blur-gaussian-linear.cpp +++ b/source/gfx/blur/gfx-blur-gaussian-linear.cpp @@ -316,14 +316,14 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render() gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE); // First Pass if (_step_scale.first > std::numeric_limits::epsilon()) { - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f); { auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); @@ -334,12 +334,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render() } std::swap(_rendertarget, _rendertarget2); - effect->get_parameter("pImage").set_texture(_rendertarget->get_texture()); + effect->get_parameter("pImage")->set_texture(_rendertarget->get_texture()); } // Second Pass if (_step_scale.second > std::numeric_limits::epsilon()) { - effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height)); + effect->get_parameter("pImageTexel")->set_float2(0.f, float_t(1.f / height)); { auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); @@ -409,12 +409,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render() gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); - effect->get_parameter("pImage").set_texture(_input_texture); + effect->get_parameter("pImage")->set_texture(_input_texture); effect->get_parameter("pImageTexel") - .set_float2(float_t(1.f / width * cos(_angle)), float_t(1.f / height * sin(_angle))); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); + ->set_float2(float_t(1.f / width * cos(_angle)), float_t(1.f / height * sin(_angle))); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE); // First Pass { diff --git a/source/gfx/blur/gfx-blur-gaussian.cpp b/source/gfx/blur/gfx-blur-gaussian.cpp index 12c7167e..b1f1dc5e 100644 --- a/source/gfx/blur/gfx-blur-gaussian.cpp +++ b/source/gfx/blur/gfx-blur-gaussian.cpp @@ -323,14 +323,14 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render() gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE); // First Pass if (_step_scale.first > std::numeric_limits::epsilon()) { - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f); { auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); @@ -341,12 +341,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render() } std::swap(_rendertarget, _rendertarget2); - effect->get_parameter("pImage").set_texture(_rendertarget->get_texture()); + effect->get_parameter("pImage")->set_texture(_rendertarget->get_texture()); } // Second Pass if (_step_scale.second > std::numeric_limits::epsilon()) { - effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height)); + effect->get_parameter("pImageTexel")->set_float2(0.f, float_t(1.f / height)); { auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); @@ -417,12 +417,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render() gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); - effect->get_parameter("pImage").set_texture(_input_texture); + effect->get_parameter("pImage")->set_texture(_input_texture); effect->get_parameter("pImageTexel") - .set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle))); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); + ->set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle))); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE); // First Pass { @@ -471,13 +471,13 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render() gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pAngle").set_float(float_t(m_angle / _size)); - effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second)); - effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height)); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pAngle")->set_float(float_t(m_angle / _size)); + effect->get_parameter("pCenter")->set_float2(float_t(m_center.first), float_t(m_center.second)); + effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE); // First Pass { @@ -548,12 +548,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render() gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); - effect->get_parameter("pImage").set_texture(_input_texture); - effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); - effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); - effect->get_parameter("pSize").set_float(float_t(_size)); - effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second)); - effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); + effect->get_parameter("pImage")->set_texture(_input_texture); + effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height)); + effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); + effect->get_parameter("pSize")->set_float(float_t(_size)); + effect->get_parameter("pCenter")->set_float2(float_t(m_center.first), float_t(m_center.second)); + effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE); // First Pass { diff --git a/source/obs/gs/gs-effect.cpp b/source/obs/gs/gs-effect.cpp index 9024415e..47b6dc55 100644 --- a/source/obs/gs/gs-effect.cpp +++ b/source/obs/gs/gs-effect.cpp @@ -115,51 +115,55 @@ size_t gs::effect::count_parameters() return (size_t)gs_effect_get_num_params(_effect); } -std::list gs::effect::get_parameters() +std::list> gs::effect::get_parameters() { - size_t num = gs_effect_get_num_params(_effect); - std::list ps; + size_t num = gs_effect_get_num_params(_effect); + std::list> ps; for (size_t idx = 0; idx < num; idx++) { ps.emplace_back(get_parameter(idx)); } return ps; } -gs::effect_parameter gs::effect::get_parameter(size_t idx) +std::shared_ptr gs::effect::get_parameter(size_t idx) { gs_eparam_t* param = gs_effect_get_param_by_idx(_effect, idx); if (!param) - throw std::invalid_argument("parameter with index not found"); - return effect_parameter(param); + return nullptr; + return std::make_shared(this->shared_from_this(), param); +} + +std::shared_ptr gs::effect::get_parameter(std::string name) +{ + gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); + if (!param) + return nullptr; + return std::make_shared(this->shared_from_this(), param); } bool gs::effect::has_parameter(std::string name) { - gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); - return (param != nullptr); + auto eprm = get_parameter(name); + if (eprm) + return true; + return false; } bool gs::effect::has_parameter(std::string name, effect_parameter::type type) { - gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); - if (param == nullptr) - return false; - gs::effect_parameter eprm(param); - return eprm.get_type() == type; + auto eprm = get_parameter(name); + if (eprm) + return eprm->get_type() == type; + return false; } -gs::effect_parameter gs::effect::get_parameter(std::string name) +gs::effect_parameter::effect_parameter(std::shared_ptr effect, gs_eparam_t* param) + : _effect(effect), _param(param) { - gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); + if (effect) + throw std::invalid_argument("effect"); if (!param) - throw std::invalid_argument("parameter with name not found"); - return effect_parameter(param); -} - -gs::effect_parameter::effect_parameter(gs_eparam_t* param) : _param(param) -{ - if (!param) - throw std::invalid_argument("param is null"); + throw std::invalid_argument("param"); gs_effect_get_param_info(_param, &_param_info); } @@ -712,7 +716,7 @@ void gs::effect_parameter::get_string(std::string& v) if (get_type() != type::Matrix) throw std::bad_cast(); size_t ptr_len = gs_effect_get_val_size(_param); - uint8_t* ptr = static_cast(gs_effect_get_val(_param)); + uint8_t* ptr = static_cast(gs_effect_get_val(_param)); if (ptr) { v = std::string(ptr, ptr + ptr_len); bfree(ptr); @@ -740,36 +744,34 @@ size_t gs::effect_parameter::count_annotations() return gs_param_get_num_annotations(_param); } -gs::effect_parameter gs::effect_parameter::get_annotation(size_t idx) +std::shared_ptr gs::effect_parameter::get_annotation(size_t idx) { gs_eparam_t* param = gs_param_get_annotation_by_idx(_param, idx); if (!param) - throw std::invalid_argument("annotation with index not found"); - return effect_parameter(param); + return nullptr; + return std::make_shared(_effect, param); } -gs::effect_parameter gs::effect_parameter::get_annotation(std::string name) +std::shared_ptr gs::effect_parameter::get_annotation(std::string name) { gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); if (!param) - throw std::invalid_argument("annotation with name not found"); - return effect_parameter(param); + return nullptr; + return std::make_shared(_effect, param); } bool gs::effect_parameter::has_annotation(std::string name) { - gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); - if (!param) - return false; - return true; + auto eprm = get_annotation(name); + if (eprm) + return true; + return false; } bool gs::effect_parameter::has_annotation(std::string name, effect_parameter::type type) { - try { - auto eprm = get_annotation(name); - return eprm.get_type() == type; - } catch (...) { - return false; - } + auto eprm = get_annotation(name); + if (eprm) + return eprm->get_type() == type; + return false; } diff --git a/source/obs/gs/gs-effect.hpp b/source/obs/gs/gs-effect.hpp index f4fe9421..90503ab5 100644 --- a/source/obs/gs/gs-effect.hpp +++ b/source/obs/gs/gs-effect.hpp @@ -40,7 +40,10 @@ #endif namespace gs { + class effect; + class effect_parameter { + std::shared_ptr<::gs::effect> _effect; gs_eparam_t* _param; gs_effect_param_info _param_info; @@ -62,7 +65,7 @@ namespace gs { }; public: - effect_parameter(gs_eparam_t* param); + effect_parameter(std::shared_ptr effect, gs_eparam_t* param); std::string get_name(); type get_type(); @@ -132,14 +135,14 @@ namespace gs { void get_string(std::string& v); void get_default_string(std::string& v); - size_t count_annotations(); - effect_parameter get_annotation(size_t idx); - effect_parameter get_annotation(std::string name); - bool has_annotation(std::string name); - bool has_annotation(std::string name, effect_parameter::type type); + size_t count_annotations(); + std::shared_ptr get_annotation(size_t idx); + std::shared_ptr get_annotation(std::string name); + bool has_annotation(std::string name); + bool has_annotation(std::string name, effect_parameter::type type); }; - class effect { + class effect : std::enable_shared_from_this<::gs::effect> { protected: gs_effect_t* _effect; @@ -151,11 +154,11 @@ namespace gs { gs_effect_t* get_object(); - size_t count_parameters(); - std::list get_parameters(); - effect_parameter get_parameter(size_t idx); - effect_parameter get_parameter(std::string name); - bool has_parameter(std::string name); - bool has_parameter(std::string name, effect_parameter::type type); + size_t count_parameters(); + std::list> get_parameters(); + std::shared_ptr get_parameter(size_t idx); + std::shared_ptr get_parameter(std::string name); + bool has_parameter(std::string name); + bool has_parameter(std::string name, effect_parameter::type type); }; } // namespace gs diff --git a/source/obs/gs/gs-mipmapper.cpp b/source/obs/gs/gs-mipmapper.cpp index a4b3952a..69f95810 100644 --- a/source/obs/gs/gs-mipmapper.cpp +++ b/source/obs/gs/gs-mipmapper.cpp @@ -252,10 +252,10 @@ void gs::mipmapper::rebuild(std::shared_ptr source, std::shared_ptr vec4_zero(&black); gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0); - _effect->get_parameter("image").set_texture(target); - _effect->get_parameter("level").set_int(int32_t(mip - 1)); - _effect->get_parameter("imageTexel").set_float2(texel_width, texel_height); - _effect->get_parameter("strength").set_float(strength); + _effect->get_parameter("image")->set_texture(target); + _effect->get_parameter("level")->set_int(int32_t(mip - 1)); + _effect->get_parameter("imageTexel")->set_float2(texel_width, texel_height); + _effect->get_parameter("strength")->set_float(strength); while (gs_effect_loop(_effect->get_object(), technique.c_str())) { gs_draw(gs_draw_mode::GS_TRIS, 0, _vb->size());