Bugfix in Recursive loopback of RenderView inside a SessionSource: fixed

loading and import into main session.
This commit is contained in:
brunoherbelin
2021-02-04 23:25:49 +01:00
parent d76dfa4a9d
commit 93b6bc9ca4
10 changed files with 145 additions and 43 deletions

View File

@@ -212,10 +212,20 @@ void Mixer::update()
// delete sources which failed update (one by one)
Source *failure = session()->failedSource();
if (failure != nullptr) {
MediaSource *failedFile = dynamic_cast<MediaSource *>(failure);
if (failedFile != nullptr) {
Settings::application.recentImport.remove( failedFile->path() );
// failed media: remove it from the list of imports
MediaSource *failedMedia = dynamic_cast<MediaSource *>(failure);
if (failedMedia != nullptr) {
Settings::application.recentImport.remove( failedMedia->path() );
}
// failed Render loopback: replace it with one matching the current session
RenderSource *failedRender = dynamic_cast<RenderSource *>(failure);
if (failedRender != nullptr) {
RenderSource *fixedRender = new RenderSource;
replaceSource(failedRender, fixedRender);
fixedRender->setSession(session_);
failure = nullptr; // prevent delete (already done in replace)
}
// delete the source
deleteSource(failure, false);
}
@@ -282,7 +292,8 @@ Source * Mixer::createSourceFile(const std::string &path)
Source * Mixer::createSourceRender()
{
// ready to create a source
RenderSource *s = new RenderSource(session_);
RenderSource *s = new RenderSource;
s->setSession(session_);
// propose a new name based on session name
s->setName(SystemToolkit::base_filename(session_->filename()));
@@ -411,6 +422,39 @@ void Mixer::insertSource(Source *s, View::Mode m)
}
}
void Mixer::replaceSource(Source *from, Source *to)
{
if ( from != nullptr && to != nullptr)
{
// rename
renameSource(to, from->name());
// remove source Nodes from all views
detach(from);
// copy all transforms
to->group(View::MIXING)->copyTransform( from->group(View::MIXING) );
to->group(View::GEOMETRY)->copyTransform( from->group(View::GEOMETRY) );
to->group(View::LAYER)->copyTransform( from->group(View::LAYER) );
to->group(View::MIXING)->copyTransform( from->group(View::MIXING) );
// TODO copy all filters
// add sources Nodes to all views
attach(to);
// add source
session_->addSource(to);
// delete source
session_->deleteSource(from);
}
}
void Mixer::deleteSource(Source *s, bool withundo)
{
if ( s != nullptr )

View File

@@ -109,6 +109,7 @@ protected:
SourceList candidate_sources_;
SourceList stash_;
void insertSource(Source *s, View::Mode m = View::INVALID);
void replaceSource(Source *from, Source *to);
void setCurrentSource(SourceList::iterator it);
SourceList::iterator current_source_;

View File

@@ -7,6 +7,7 @@
#include "GarbageVisitor.h"
#include "FrameGrabber.h"
#include "SessionCreator.h"
#include "SessionSource.h"
#include "Log.h"
@@ -15,7 +16,7 @@ Session::Session() : failedSource_(nullptr), active_(true), fading_target_(0.f)
filename_ = "";
config_[View::RENDERING] = new Group;
config_[View::RENDERING]->scale_ = FrameBuffer::getResolutionFromParameters(Settings::application.render.ratio, Settings::application.render.res);
config_[View::RENDERING]->scale_ = glm::vec3(0.f);
config_[View::GEOMETRY] = new Group;
config_[View::GEOMETRY]->scale_ = Settings::application.views[View::GEOMETRY].default_scale;
@@ -63,11 +64,21 @@ void Session::setActive (bool on)
// update all sources
void Session::update(float dt)
{
failedSource_ = nullptr;
// no update until render view is initialized
if ( render_.frame() == nullptr )
return;
// pre-render of all sources
failedSource_ = nullptr;
for( SourceList::iterator it = sources_.begin(); it != sources_.end(); it++){
// ensure the RenderSource is rendering this session
RenderSource *s = dynamic_cast<RenderSource *>( *it );
if ( s!= nullptr ){
if ( s->session() != this /*|| s->session()->frame()->resolution() != frame()->resolution()*/)
s->setSession(nullptr); // RenderSource will fail and be replaced
}
if ( (*it)->failed() ) {
failedSource_ = (*it);
}

View File

@@ -85,12 +85,12 @@ void SessionCreator::load(const std::string& filename)
// session file seems legit, create a session
session_ = new Session;
// load views config (includes resolution of session rendering)
loadConfig( xmlDoc_.FirstChildElement("Views") );
// ready to read sources
SessionLoader::load( xmlDoc_.FirstChildElement("Session") );
// load optionnal config
loadConfig( xmlDoc_.FirstChildElement("Views") );
// all good
session_->setFilename(filename);
}
@@ -145,7 +145,7 @@ void SessionLoader::load(XMLElement *sessionNode)
load_source = new SessionSource;
}
else if ( std::string(pType) == "RenderSource") {
load_source = new RenderSource(session_);
load_source = new RenderSource;
}
else if ( std::string(pType) == "PatternSource") {
load_source = new PatternSource;
@@ -245,7 +245,7 @@ Source *SessionLoader::cloneOrCreateSource(tinyxml2::XMLElement *sourceNode)
load_source = new SessionSource;
}
else if ( std::string(pType) == "RenderSource") {
load_source = new RenderSource(session_);
load_source = new RenderSource;
}
else if ( std::string(pType) == "PatternSource") {
load_source = new PatternSource;
@@ -534,6 +534,11 @@ void SessionLoader::visit (SessionSource& s)
}
void SessionLoader::visit (RenderSource& s)
{
s.setSession( session_ );
}
void SessionLoader::visit (PatternSource& s)
{
uint t = xmlCurrent_->UnsignedAttribute("pattern");

View File

@@ -48,6 +48,7 @@ public:
void visit (Source& s) override;
void visit (MediaSource& s) override;
void visit (SessionSource& s) override;
void visit (RenderSource& s) override;
void visit (PatternSource& s) override;
void visit (DeviceSource& s) override;
void visit (NetworkSource& s) override;

View File

@@ -95,6 +95,7 @@ Session *SessionSource::detach()
// make disabled
initialized_ = false;
// ask to delete me
failed_ = true;
@@ -165,7 +166,7 @@ void SessionSource::init()
texturesurface_->setTextureIndex( session_->frame()->texture() );
// create Frame buffer matching size of session
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution());
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution() );
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);
@@ -175,12 +176,13 @@ void SessionSource::init()
wait_for_sources_ = true;
else {
initialized_ = true;
Log::Info("New Session created.");
Log::Info("New Session created %d x %d.", session_->frame()->width(), session()->frame()->height());
}
}
}
if (initialized_){
if (initialized_)
{
// remove the loading icon
Node *loader = overlays_[View::TRANSITION]->back();
overlays_[View::TRANSITION]->detach(loader);
@@ -229,7 +231,8 @@ void SessionSource::accept(Visitor& v)
}
RenderSource::RenderSource(Session *session) : Source(), session_(session)
RenderSource::RenderSource() : Source(), session_(nullptr)
{
// set symbol
symbol_ = new Symbol(Symbol::RENDER, glm::vec3(0.75f, 0.75f, 0.01f));
@@ -239,20 +242,20 @@ RenderSource::RenderSource(Session *session) : Source(), session_(session)
bool RenderSource::failed() const
{
return session_ == nullptr;
return (initialized_ && session_ == nullptr);
}
uint RenderSource::texture() const
{
if (session_ == nullptr)
return Resource::getTextureBlack();
else
if (session_ && session_->frame())
return session_->frame()->texture();
else
return Resource::getTextureBlack(); // getTextureTransparent ?
}
void RenderSource::init()
{
if (session_ && session_->frame()->texture() != Resource::getTextureBlack()) {
if (session_ && session_->frame() && session_->frame()->texture() != Resource::getTextureBlack()) {
FrameBuffer *fb = session_->frame();
@@ -260,7 +263,7 @@ void RenderSource::init()
texturesurface_->setTextureIndex( fb->texture() );
// create Frame buffer matching size of output session
FrameBuffer *renderbuffer = new FrameBuffer( fb->resolution());
FrameBuffer *renderbuffer = new FrameBuffer( fb->resolution() );
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);

View File

@@ -43,13 +43,16 @@ protected:
class RenderSource : public Source
{
public:
RenderSource(Session *session);
RenderSource();
// implementation of source API
bool failed() const override;
bool failed () const override;
uint texture() const override;
void accept (Visitor& v) override;
inline Session *session () const { return session_; }
inline void setSession (Session *se) { session_ = se; }
glm::ivec2 icon() const override { return glm::ivec2(0, 2); }
protected:

View File

@@ -1,5 +1,6 @@
#include <algorithm>
#include <locale>
#include <tinyxml2.h>
#include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/matrix_transform.hpp>
@@ -14,6 +15,7 @@
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "SystemToolkit.h"
#include "SessionVisitor.h"
#include "Log.h"
#include "Mixer.h"
@@ -350,6 +352,13 @@ void Source::render()
void Source::attach(FrameBuffer *renderbuffer)
{
// invalid argument
// if (renderbuffer == nullptr)
// return;
// // replace renderbuffer_
// if (renderbuffer_)
// delete renderbuffer_;
renderbuffer_ = renderbuffer;
// if a symbol is available, add it to overlay
@@ -451,9 +460,9 @@ float sin_quad(float x, float y) {
}
float Source::depth()
float Source::depth() const
{
return groups_[View::RENDERING]->translation_.z;
return group(View::RENDERING)->translation_.z;
}
void Source::setDepth(float d)
@@ -462,7 +471,7 @@ void Source::setDepth(float d)
touch();
}
float Source::alpha()
float Source::alpha() const
{
return blendingShader()->color.a;
}
@@ -668,6 +677,27 @@ void Source::setMask(FrameBufferImage *img)
}
std::string Source::xml(Source *s)
{
std::string x = "";
tinyxml2::XMLDocument xmlDoc;
tinyxml2::XMLElement *selectionNode = xmlDoc.NewElement(APP_NAME);
selectionNode->SetAttribute("size", 1);
xmlDoc.InsertEndChild(selectionNode);
SessionVisitor sv(&xmlDoc, selectionNode);
s->accept(sv);
// get compact string
tinyxml2::XMLPrinter xmlPrint(0, true);
xmlDoc.Print( &xmlPrint );
x = xmlPrint.CStr();
return x;
}
bool Source::hasNode::operator()(const Source* elem) const
{
if (_n && elem)

View File

@@ -97,12 +97,12 @@ public:
virtual void update (float dt);
// update mode
virtual void setActive (bool on);
inline bool active () const { return active_; }
virtual void setActive (bool on);
// lock mode
virtual void setLocked (bool on);
inline bool locked () const { return locked_; }
virtual void setLocked (bool on);
// Workspace
typedef enum {
@@ -125,15 +125,16 @@ public:
virtual void accept (Visitor& v);
// operations on mask
void storeMask(FrameBufferImage *img = nullptr);
FrameBufferImage *getMask() const { return maskimage_; }
void setMask(FrameBufferImage *img);
inline FrameBufferImage *getMask () const { return maskimage_; }
void setMask (FrameBufferImage *img);
void storeMask (FrameBufferImage *img = nullptr);
float depth();
void setDepth(float d);
float depth () const;
void setDepth (float d);
float alpha () const;
void setAlpha (float a);
float alpha();
void setAlpha(float a);
struct hasNode: public std::unary_function<Source*, bool>
{
@@ -165,6 +166,9 @@ public:
virtual glm::ivec2 icon () const { return glm::ivec2(12, 11); }
// get the xml description text of a source
static std::string xml(Source *s);
protected:
// name
std::string name_;

View File

@@ -651,8 +651,6 @@ uint MixingView::textureMixingQuadratic()
RenderView::RenderView() : View(RENDERING), frame_buffer_(nullptr), fading_overlay_(nullptr)
{
// set resolution to settings default
setResolution();
}
RenderView::~RenderView()
@@ -710,12 +708,14 @@ void RenderView::draw()
{
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -SCENE_DEPTH, 1.f);
if (frame_buffer_) {
// draw in frame buffer
glm::mat4 P = glm::scale( projection, glm::vec3(1.f / frame_buffer_->aspectRatio(), 1.f, 1.f));
frame_buffer_->begin();
scene.root()->draw(glm::identity<glm::mat4>(), P);
fading_overlay_->draw(glm::identity<glm::mat4>(), projection);
frame_buffer_->end();
}
}
GeometryView::GeometryView() : View(GEOMETRY)