fixed more threading issues

This commit is contained in:
itsmattkc
2019-01-15 22:45:25 +11:00
parent e1ec2f6fbe
commit 08968706b0
12 changed files with 166 additions and 126 deletions
+9 -7
View File
@@ -83,6 +83,7 @@ void process_effect(QOpenGLContext* ctx,
GLTextureCoords& coords,
GLuint& composite_texture,
bool& fbo_switcher,
bool& texture_failed,
int data) {
if (e->is_enabled()) {
if (e->enable_coords) {
@@ -115,7 +116,8 @@ GLuint compose_sequence(Viewer* viewer,
QVector<Clip*>& nests,
bool video,
bool render_audio,
Effect** gizmos) {
Effect** gizmos,
bool& texture_failed) {
GLint current_fbo = 0;
if (video) {
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &current_fbo);
@@ -235,7 +237,7 @@ GLuint compose_sequence(Viewer* viewer,
c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8);
}
get_clip_frame(c, playhead);
get_clip_frame(c, playhead, texture_failed);
textureID = c->texture->textureId();
break;
case MEDIA_TYPE_SEQUENCE:
@@ -281,7 +283,7 @@ GLuint compose_sequence(Viewer* viewer,
// for nested sequences
if (c->media->get_type()== MEDIA_TYPE_SEQUENCE) {
nests.append(c);
textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos);
textureID = compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed);
nests.removeLast();
fbo_switcher = true;
}
@@ -319,7 +321,7 @@ GLuint compose_sequence(Viewer* viewer,
for (int j=0;j<c->effects.size();j++) {
Effect* e = c->effects.at(j);
process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, TA_NO_TRANSITION);
process_effect(ctx, c, e, timecode, coords, composite_texture, fbo_switcher, texture_failed, TA_NO_TRANSITION);
if (e->are_gizmos_enabled()) {
if (first_gizmo_effect == nullptr) first_gizmo_effect = e;
@@ -338,14 +340,14 @@ GLuint compose_sequence(Viewer* viewer,
if (c->get_opening_transition() != nullptr) {
int transition_progress = playhead - c->get_timeline_in_with_transition();
if (transition_progress < c->get_opening_transition()->get_length()) {
process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_OPENING_TRANSITION);
process_effect(ctx, c, c->get_opening_transition(), (double)transition_progress/(double)c->get_opening_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_OPENING_TRANSITION);
}
}
if (c->get_closing_transition() != nullptr) {
int transition_progress = playhead - (c->get_timeline_out_with_transition() - c->get_closing_transition()->get_length());
if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) {
process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_CLOSING_TRANSITION);
process_effect(ctx, c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, texture_failed, TA_CLOSING_TRANSITION);
}
}
// EFFECT CODE END
@@ -452,7 +454,7 @@ GLuint compose_sequence(Viewer* viewer,
if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) {
if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) {
nests.append(c);
compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos);
compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed);
nests.removeLast();
} else {
if (c->lock.tryLock()) {
+1 -1
View File
@@ -15,6 +15,6 @@ GLuint compose_sequence(Viewer* viewer,
QVector<Clip*>& nests,
bool video,
bool render_audio,
Effect **gizmos);
Effect **gizmos, bool &texture_failed);
#endif // RENDERFUNCTIONS_H
+72 -29
View File
@@ -10,13 +10,16 @@
#include "project/sequence.h"
RenderThread::RenderThread() :
share_ctx(nullptr),
ctx(nullptr),
frameBuffer(0),
texColorBuffer(0),
share_ctx(nullptr),
ctx(nullptr),
seq(nullptr),
tex_width(-1),
tex_height(-1),
queued(false)
queued(false),
texture_failed(false),
running(true)
{
surface.create();
}
@@ -28,26 +31,23 @@ RenderThread::~RenderThread() {
void RenderThread::run() {
mutex.lock();
bool running = true;
while (running) {
if (!queued) {
waitCond.wait(&mutex);
}
if (!running) {
break;
}
queued = false;
if (share_ctx != nullptr) {
if (ctx == nullptr) {
ctx = new QOpenGLContext();
ctx->setFormat(share_ctx->format());
ctx->setShareContext(share_ctx);
ctx->create();
ctx->makeCurrent(&surface);
}
if (share_ctx != nullptr) {
if (ctx != nullptr) {
ctx->makeCurrent(&surface);
// gen fbo
if (frameBuffer == 0) {
delete_fbo();
ctx->functions()->glGenFramebuffers(1, &frameBuffer);
}
@@ -55,13 +55,8 @@ void RenderThread::run() {
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer);
// gen texture
if (texColorBuffer == 0 || tex_width != seq->width || tex_height != seq->height) {\
if (texColorBuffer > 0) {
ctx->functions()->glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0
);
glDeleteTextures(1, &texColorBuffer);
}
if (texColorBuffer == 0 || tex_width != seq->width || tex_height != seq->height) {
delete_texture();
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glTexImage2D(
@@ -91,12 +86,7 @@ void RenderThread::run() {
}
}
if (ctx != nullptr) {
if (texColorBuffer > 0) glDeleteTextures(1, &texColorBuffer);
if (frameBuffer > 0) ctx->functions()->glDeleteFramebuffers(1, &frameBuffer);
ctx->doneCurrent();
delete ctx;
}
delete_ctx();
mutex.unlock();
}
@@ -118,7 +108,7 @@ void RenderThread::paint() {
Effect* gizmos; // does nothing yet
QVector<Clip*> nests;
compose_sequence(nullptr, ctx, seq, nests, true, false, &gizmos);
compose_sequence(nullptr, ctx, seq, nests, true, false, &gizmos, texture_failed);
glDisable(GL_DEPTH);
glDisable(GL_BLEND);
@@ -126,8 +116,61 @@ void RenderThread::paint() {
}
void RenderThread::start_render(QOpenGLContext *share, Sequence *s, int idivider) {
share_ctx = share;
if (s != seq && seq != nullptr) {
closeActiveClips(seq);
}
seq = s;
queued = true;
if (share != nullptr && (ctx == nullptr || ctx->shareContext() != share_ctx)) {
share_ctx = share;
delete_ctx();
ctx = new QOpenGLContext();
ctx->setFormat(share_ctx->format());
ctx->setShareContext(share_ctx);
ctx->create();
ctx->moveToThread(this);
}
if (seq != nullptr) {
queued = true;
waitCond.wakeAll();
}
}
bool RenderThread::did_texture_fail() {
return texture_failed;
}
void RenderThread::cancel() {
running = false;
waitCond.wakeAll();
wait();
}
void RenderThread::delete_texture() {
if (texColorBuffer > 0) {
ctx->functions()->glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0
);
glDeleteTextures(1, &texColorBuffer);
}
texColorBuffer = 0;
}
void RenderThread::delete_fbo() {
if (frameBuffer > 0) {
ctx->functions()->glDeleteFramebuffers(1, &frameBuffer);
}
frameBuffer = 0;
}
void RenderThread::delete_ctx() {
if (ctx != nullptr) {
delete_texture();
delete_fbo();
ctx->doneCurrent();
delete ctx;
}
ctx = nullptr;
}
+9
View File
@@ -21,9 +21,16 @@ public:
GLuint texColorBuffer;
void paint();
void start_render(QOpenGLContext* share, Sequence* s, int idivider = 0);
bool did_texture_fail();
void cancel();
signals:
void ready();
private:
// cleanup functions
void delete_texture();
void delete_fbo();
void delete_ctx();
QWaitCondition waitCond;
QOffscreenSurface surface;
QOpenGLContext* share_ctx;
@@ -33,6 +40,8 @@ private:
int tex_width;
int tex_height;
bool queued;
bool texture_failed;
bool running;
};
#endif // RENDERTHREAD_H
+54 -54
View File
@@ -12,85 +12,85 @@
// enforces aspect ratio
ViewerContainer::ViewerContainer(QWidget *parent) :
QScrollArea(parent),
fit(true),
child(nullptr)
QScrollArea(parent),
fit(true),
child(nullptr)
{
setFrameShadow(QFrame::Plain);
setFrameShape(QFrame::NoFrame);
setFrameShadow(QFrame::Plain);
setFrameShape(QFrame::NoFrame);
area = new QWidget(this);
area->move(0, 0);
setWidget(area);
area = new QWidget(this);
area->move(0, 0);
setWidget(area);
child = new ViewerWidget(area);
child->container = this;
child = new ViewerWidget(area);
child->container = this;
}
ViewerContainer::~ViewerContainer() {
delete area;
delete area;
}
void ViewerContainer::dragScrollPress(const QPoint &p) {
drag_start_x = p.x();
drag_start_y = p.y();
horiz_start = horizontalScrollBar()->value();
vert_start = verticalScrollBar()->value();
drag_start_x = p.x();
drag_start_y = p.y();
horiz_start = horizontalScrollBar()->value();
vert_start = verticalScrollBar()->value();
}
void ViewerContainer::dragScrollMove(const QPoint &p) {
int true_x = p.x() + (horiz_start - horizontalScrollBar()->value());
int true_y = p.y() + (vert_start - verticalScrollBar()->value());
int true_x = p.x() + (horiz_start - horizontalScrollBar()->value());
int true_y = p.y() + (vert_start - verticalScrollBar()->value());
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + (drag_start_x - true_x));
verticalScrollBar()->setValue(verticalScrollBar()->value() + (drag_start_y - true_y));
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + (drag_start_x - true_x));
verticalScrollBar()->setValue(verticalScrollBar()->value() + (drag_start_y - true_y));
drag_start_x = true_x;
drag_start_y = true_y;
drag_start_x = true_x;
drag_start_y = true_y;
}
void ViewerContainer::adjust() {
if (viewer->seq != nullptr) {
if (child->waveform) {
child->move(0, 0);
child->resize(size());
} else if (fit) {
double aspect_ratio = double(viewer->seq->width)/double(viewer->seq->height);
if (viewer->seq != nullptr) {
if (child->waveform) {
child->move(0, 0);
child->resize(size());
} else if (fit) {
double aspect_ratio = double(viewer->seq->width)/double(viewer->seq->height);
int widget_x = 0;
int widget_y = 0;
int widget_width = width();
int widget_height = height();
float widget_ar = (float) widget_width /(float) widget_height;
int widget_x = 0;
int widget_y = 0;
int widget_width = width();
int widget_height = height();
double widget_ar = double(widget_width) / double(widget_height);
bool widget_is_wider_than_sequence = widget_ar > aspect_ratio;
bool widget_is_wider_than_sequence = widget_ar > aspect_ratio;
if (widget_is_wider_than_sequence) {
widget_width = widget_height * aspect_ratio;
widget_x = (width() / 2) - (widget_width / 2);
} else {
widget_height = widget_width / aspect_ratio;
widget_y = (height() / 2) - (widget_height / 2);
}
if (widget_is_wider_than_sequence) {
widget_width = widget_height * aspect_ratio;
widget_x = (width() / 2) - (widget_width / 2);
} else {
widget_height = widget_width / aspect_ratio;
widget_y = (height() / 2) - (widget_height / 2);
}
child->move(widget_x, widget_y);
child->resize(widget_width, widget_height);
child->move(widget_x, widget_y);
child->resize(widget_width, widget_height);
zoom = double(widget_width) / double(viewer->seq->width);
} else {
int zoomed_width = double(viewer->seq->width)*zoom;
int zoomed_height = double(viewer->seq->height)*zoom;
int zoomed_x = 0;
int zoomed_y = 0;
zoom = double(widget_width) / double(viewer->seq->width);
} else {
int zoomed_width = double(viewer->seq->width)*zoom;
int zoomed_height = double(viewer->seq->height)*zoom;
int zoomed_x = 0;
int zoomed_y = 0;
if (zoomed_width < width()) zoomed_x = (width()>>1)-(zoomed_width>>1);
if (zoomed_height < height()) zoomed_y = (height()>>1)-(zoomed_height>>1);
if (zoomed_width < width()) zoomed_x = (width()>>1)-(zoomed_width>>1);
if (zoomed_height < height()) zoomed_y = (height()>>1)-(zoomed_height>>1);
child->move(zoomed_x, zoomed_y);
child->resize(zoomed_width, zoomed_height);
}
child->move(zoomed_x, zoomed_y);
child->resize(zoomed_width, zoomed_height);
}
}
area->resize(qMax(width(), child->width()), qMax(height(), child->height()));
area->resize(qMax(width(), child->width()), qMax(height(), child->height()));
}
void ViewerContainer::resizeEvent(QResizeEvent *event) {
+6 -14
View File
@@ -57,7 +57,6 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
dragging(false),
gizmos(nullptr),
selected_gizmo(nullptr),
just_repaint(false),
window(nullptr)
{
setMouseTracking(true);
@@ -73,6 +72,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
renderer = new RenderThread();
renderer->start(QThread::HighPriority);
connect(renderer, SIGNAL(ready()), this, SLOT(queue_repaint()));
connect(renderer, SIGNAL(finished()), renderer, SLOT(deleteLater()));
}
ViewerWidget::~ViewerWidget() {
@@ -80,15 +80,11 @@ ViewerWidget::~ViewerWidget() {
window->close();
delete window;
}
renderer->cancel();
}
void ViewerWidget::delete_function() {
// destroy all textures as well
if (viewer->seq != nullptr) {
makeCurrent();
closeActiveClips(viewer->seq);
doneCurrent();
}
renderer->start_render(context(), nullptr);
}
void ViewerWidget::set_waveform_scroll(int s) {
@@ -173,7 +169,6 @@ void ViewerWidget::save_frame() {
}
void ViewerWidget::queue_repaint() {
just_repaint = true;
update();
}
@@ -222,14 +217,10 @@ void ViewerWidget::retry() {
void ViewerWidget::initializeGL() {
initializeOpenGLFunctions();
connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(delete_function()), Qt::DirectConnection);
if (window != nullptr) {
delete window;
}
window = new ViewerWindow(context());
// retry_timer.start();
}
void ViewerWidget::frame_update() {
@@ -246,7 +237,8 @@ void ViewerWidget::frame_update() {
// render the audio
QVector<Clip*> nests;
compose_sequence(viewer, context(), viewer->seq, nests, false, render_audio, &gizmos);
bool texture_failed;
compose_sequence(viewer, context(), viewer->seq, nests, false, render_audio, &gizmos, texture_failed);
}
}
@@ -482,7 +474,7 @@ void ViewerWidget::paintGL() {
renderer->mutex.unlock();
if (texture_failed) {
if (renderer->did_texture_fail()) {
doneCurrent();
renderer->start_render(context(), viewer->seq);
}
+2 -4
View File
@@ -28,6 +28,8 @@ public:
ViewerWidget(QWidget *parent = 0);
~ViewerWidget();
void delete_function();
void paintGL();
void initializeGL();
Viewer* viewer;
@@ -45,11 +47,8 @@ public:
void frame_update();
public slots:
void delete_function();
void set_waveform_scroll(int s);
protected:
// void paintEvent(QPaintEvent *e);
// void resizeGL(int w, int h);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
@@ -68,7 +67,6 @@ private:
void move_gizmos(QMouseEvent *event, bool done);
RenderThread* renderer;
ViewerWindow* window;
bool just_repaint;
private slots:
void retry();
void show_context_menu();
-2
View File
@@ -33,8 +33,6 @@ void ViewerWindow::paintGL() {
double widget_ar = double(width()) / double(height());
if (widget_ar > ar) {
/*widget_width = widget_height * aspect_ratio;
widget_x = (width() / 2) - (widget_width / 2);*/
double width = 1.0 * ar / widget_ar;
left = (1.0 - width)*0.5;
right = left + width;