Implement default methods for plugin parameter editing and progress, and integrate plugin rendering into the build system.

This commit is contained in:
Mike Solar
2025-12-24 21:07:17 +08:00
parent 88ba0e4841
commit 7c0f37b0a7
10 changed files with 332 additions and 290 deletions
+8
View File
@@ -22,6 +22,7 @@
#include "node/block/clip/clip.h"
#include "render/job/footagejob.h"
#include "render/rendermanager.h"
#include "render/job/pluginjob.h"
namespace olive
{
@@ -381,6 +382,10 @@ TexturePtr NodeTraverser::ProcessVideoCacheJob(const CacheJob *val)
return nullptr;
}
TexturePtr NodeTraverser::ProcessPluginJob(plugin::PluginJob *job)
{
// TODO
}
QVector2D NodeTraverser::GenerateResolution() const
{
return QVector2D(video_params_.square_pixel_width(),
@@ -490,6 +495,9 @@ void NodeTraverser::ResolveJobs(NodeValue &val)
val.set_value(tex);
}
else if (plugin::PluginJob* plugin_job=dynamic_cast<plugin::PluginJob*>(base_job)) {
ProcessPluginJob(plugin_job);
}
// Cache resolved value
resolved_texture_cache_.insert(job_tex.get(),
+2
View File
@@ -30,6 +30,7 @@
#include "render/job/colortransformjob.h"
#include "render/job/footagejob.h"
#include "value.h"
#include "render/job/pluginjob.h"
namespace olive
{
@@ -143,6 +144,7 @@ protected:
return SampleBuffer();
}
virtual TexturePtr ProcessPluginJob(plugin::PluginJob *job);
SampleBuffer CreateSampleBuffer(const AudioParams &params,
const rational &length)
{
+13 -5
View File
@@ -126,12 +126,18 @@ public:
/// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditBegin
///
/// Client host code needs to implement this
virtual OfxStatus editBegin(const std::string& name);
virtual OfxStatus editBegin(const std::string& name)
{
return kOfxStatOK;
};
/// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditEnd
///
/// Client host code needs to implement this
virtual OfxStatus editEnd();
virtual OfxStatus editEnd()
{
return kOfxStatOK;
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -141,14 +147,16 @@ public:
// overridden for Progress::ProgressI
/// Start doing progress.
virtual void progressStart(const std::string &message, const std::string &messageid);
virtual void progressStart(const std::string &message, const std::string &messageid)
{
};
/// finish yer progress
virtual void progressEnd();
virtual void progressEnd(){};
/// set the progress to some level of completion, returns
/// false if you should abandon processing, true to continue
virtual bool progressUpdate(double t);
virtual bool progressUpdate(double t){return true;};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -17,7 +17,7 @@
add_subdirectory(job)
add_subdirectory(ocioconf)
add_subdirectory(opengl)
add_subdirectory(plugin)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
render/audioplaybackcache.cpp
+272 -267
View File
@@ -397,305 +397,310 @@ struct TextureToBind {
Texture::Interpolation interpolation;
};
void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination,
void OpenGLRenderer::Blit(QVariant s, AcceleratedJob& a_job, Texture *destination,
VideoParams destination_params,
bool clear_destination)
{
GL_PREAMBLE;
try {
ShaderJob &s_job=dynamic_cast<ShaderJob &>(a_job);
ShaderJob job(s_job);
// If this node is iterative, we'll pick up which input here
QMap<QString, GLuint> texture_index_map;
QVector<TextureToBind> textures_to_bind;
// If this node is iterative, we'll pick up which input here
QMap<QString, GLuint> texture_index_map;
QVector<TextureToBind> textures_to_bind;
GLuint shader = s.value<GLuint>();
GLuint shader = s.value<GLuint>();
functions_->glUseProgram(shader);
functions_->glUseProgram(shader);
for (auto it = job.GetValues().constBegin();
it != job.GetValues().constEnd(); it++) {
// See if the shader has takes this parameter as an input
GLint variable_location = functions_->glGetUniformLocation(
shader, it.key().toUtf8().constData());
for (auto it = job.GetValues().constBegin();
it != job.GetValues().constEnd(); it++) {
// See if the shader has takes this parameter as an input
GLint variable_location = functions_->glGetUniformLocation(
shader, it.key().toUtf8().constData());
if (variable_location == -1) {
continue;
}
if (variable_location == -1) {
continue;
// This variable is used in the shader, let's set it
const NodeValue &value = it.value();
// Arrays are not currently supported in this system
if (value.array()) {
continue;
}
switch (value.type()) {
case NodeValue::kInt:
// kInt technically specifies a LongLong, but OpenGL doesn't support those. This may lead to
// over/underflows if the number is large enough, but the likelihood of that is quite low.
functions_->glUniform1i(variable_location, value.toInt());
break;
case NodeValue::kFloat:
// kFloat technically specifies a double but as above, OpenGL doesn't support those.
functions_->glUniform1f(variable_location, value.toDouble());
break;
case NodeValue::kVec2: {
QVector2D v = value.toVec2();
functions_->glUniform2fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kVec3: {
QVector3D v = value.toVec3();
functions_->glUniform3fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kVec4: {
QVector4D v = value.toVec4();
functions_->glUniform4fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kMatrix:
functions_->glUniformMatrix4fv(variable_location, 1, false,
value.toMatrix().constData());
break;
case NodeValue::kCombo:
functions_->glUniform1i(variable_location, value.toInt());
break;
case NodeValue::kColor: {
Color color = value.toColor();
functions_->glUniform4f(variable_location, color.red(),
color.green(), color.blue(), color.alpha());
break;
}
case NodeValue::kBoolean:
functions_->glUniform1i(variable_location, value.toBool());
break;
case NodeValue::kTexture: {
TexturePtr texture = value.toTexture();
// Set value to bound texture
functions_->glUniform1i(variable_location, textures_to_bind.size());
texture_index_map.insert(it.key(), textures_to_bind.size());
textures_to_bind.append(
{ texture, job.GetInterpolation(it.key()) });
// Set enable flag if shader wants it
GLuint tex_id = texture ? texture->id().value<GLuint>() : 0;
int enable_param_location = functions_->glGetUniformLocation(
shader,
QStringLiteral("%1_enabled").arg(it.key()).toUtf8().constData());
if (enable_param_location > -1) {
functions_->glUniform1i(enable_param_location, tex_id > 0);
}
break;
}
case NodeValue::kSamples:
case NodeValue::kText:
case NodeValue::kRational:
case NodeValue::kFont:
case NodeValue::kFile:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kSubtitleParams:
case NodeValue::kBezier:
case NodeValue::kBinary:
case NodeValue::kNone:
case NodeValue::kDataTypeCount:
break;
}
}
// This variable is used in the shader, let's set it
const NodeValue &value = it.value();
// Bind all textures
for (int i = 0; i < textures_to_bind.size(); i++) {
const TextureToBind &t = textures_to_bind.at(i);
TexturePtr texture = t.texture;
// Arrays are not currently supported in this system
if (value.array()) {
continue;
}
switch (value.type()) {
case NodeValue::kInt:
// kInt technically specifies a LongLong, but OpenGL doesn't support those. This may lead to
// over/underflows if the number is large enough, but the likelihood of that is quite low.
functions_->glUniform1i(variable_location, value.toInt());
break;
case NodeValue::kFloat:
// kFloat technically specifies a double but as above, OpenGL doesn't support those.
functions_->glUniform1f(variable_location, value.toDouble());
break;
case NodeValue::kVec2: {
QVector2D v = value.toVec2();
functions_->glUniform2fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kVec3: {
QVector3D v = value.toVec3();
functions_->glUniform3fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kVec4: {
QVector4D v = value.toVec4();
functions_->glUniform4fv(variable_location, 1,
reinterpret_cast<const GLfloat *>(&v));
break;
}
case NodeValue::kMatrix:
functions_->glUniformMatrix4fv(variable_location, 1, false,
value.toMatrix().constData());
break;
case NodeValue::kCombo:
functions_->glUniform1i(variable_location, value.toInt());
break;
case NodeValue::kColor: {
Color color = value.toColor();
functions_->glUniform4f(variable_location, color.red(),
color.green(), color.blue(), color.alpha());
break;
}
case NodeValue::kBoolean:
functions_->glUniform1i(variable_location, value.toBool());
break;
case NodeValue::kTexture: {
TexturePtr texture = value.toTexture();
// Set value to bound texture
functions_->glUniform1i(variable_location, textures_to_bind.size());
texture_index_map.insert(it.key(), textures_to_bind.size());
textures_to_bind.append(
{ texture, job.GetInterpolation(it.key()) });
// Set enable flag if shader wants it
GLuint tex_id = texture ? texture->id().value<GLuint>() : 0;
int enable_param_location = functions_->glGetUniformLocation(
shader,
QStringLiteral("%1_enabled").arg(it.key()).toUtf8().constData());
if (enable_param_location > -1) {
functions_->glUniform1i(enable_param_location, tex_id > 0);
}
break;
}
case NodeValue::kSamples:
case NodeValue::kText:
case NodeValue::kRational:
case NodeValue::kFont:
case NodeValue::kFile:
case NodeValue::kVideoParams:
case NodeValue::kAudioParams:
case NodeValue::kSubtitleParams:
case NodeValue::kBezier:
case NodeValue::kBinary:
case NodeValue::kNone:
case NodeValue::kDataTypeCount:
break;
}
}
// Bind all textures
for (int i = 0; i < textures_to_bind.size(); i++) {
const TextureToBind &t = textures_to_bind.at(i);
TexturePtr texture = t.texture;
functions_->glActiveTexture(GL_TEXTURE0 + i);
GLuint tex_id = texture ? texture->id().value<GLuint>() : 0;
GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D :
GL_TEXTURE_2D;
functions_->glBindTexture(target, tex_id);
functions_->glActiveTexture(GL_TEXTURE0 + i);
if (tex_id) {
PrepareInputTexture(target, t.interpolation);
GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D :
GL_TEXTURE_2D;
functions_->glBindTexture(target, tex_id);
if (tex_id) {
PrepareInputTexture(target, t.interpolation);
if (texture->channel_count() == 1 &&
destination_params.channel_count() != 1) {
// Interpret this texture as a grayscale texture
functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,
GL_RED);
functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,
GL_RED);
functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,
GL_RED);
if (texture->channel_count() == 1 &&
destination_params.channel_count() != 1) {
// Interpret this texture as a grayscale texture
functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,
GL_RED);
functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,
GL_RED);
functions_->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,
GL_RED);
}
}
}
}
// Ensure matrix is set, at least to identity
GLint mvpmat_location =
functions_->glGetUniformLocation(shader, "ove_mvpmat");
if (mvpmat_location > -1) {
functions_->glUniformMatrix4fv(
mvpmat_location, 1, false,
job.Get(QStringLiteral("ove_mvpmat")).toMatrix().constData());
}
// Ensure matrix is set, at least to identity
GLint mvpmat_location =
functions_->glGetUniformLocation(shader, "ove_mvpmat");
if (mvpmat_location > -1) {
functions_->glUniformMatrix4fv(
mvpmat_location, 1, false,
job.Get(QStringLiteral("ove_mvpmat")).toMatrix().constData());
}
// Set the viewport to the "physical" resolution of the destination
functions_->glViewport(0, 0, destination_params.effective_width(),
destination_params.effective_height());
// Set the viewport to the "physical" resolution of the destination
functions_->glViewport(0, 0, destination_params.effective_width(),
destination_params.effective_height());
// Bind vertex array object
QOpenGLVertexArrayObject vao_;
vao_.create();
vao_.bind();
// Bind vertex array object
QOpenGLVertexArrayObject vao_;
vao_.create();
vao_.bind();
// Set buffers
QOpenGLBuffer vert_vbo_;
vert_vbo_.create();
vert_vbo_.bind();
// If the job has vertex coordinate overrides use them instead of the defaults.
if (!job.GetVertexCoordinates().isEmpty()) {
Q_ASSERT(job.GetVertexCoordinates().size() == 18);
vert_vbo_.allocate(job.GetVertexCoordinates().constData(),
job.GetVertexCoordinates().size() * sizeof(float));
} else {
vert_vbo_.allocate(blit_vertices.constData(),
blit_vertices.size() * sizeof(GLfloat));
}
vert_vbo_.release();
QOpenGLBuffer frag_vbo_;
frag_vbo_.create();
frag_vbo_.bind();
frag_vbo_.allocate(blit_texcoords.constData(),
blit_texcoords.size() * sizeof(GLfloat));
frag_vbo_.release();
GLint vertex_location =
functions_->glGetAttribLocation(shader, "a_position");
if (vertex_location != -1) {
// Set buffers
QOpenGLBuffer vert_vbo_;
vert_vbo_.create();
vert_vbo_.bind();
functions_->glEnableVertexAttribArray(vertex_location);
functions_->glVertexAttribPointer(vertex_location, 3, GL_FLOAT,
GL_FALSE, 0, nullptr);
vert_vbo_.release();
}
GLint tex_location = functions_->glGetAttribLocation(shader, "a_texcoord");
if (tex_location != -1) {
frag_vbo_.bind();
functions_->glEnableVertexAttribArray(tex_location);
functions_->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE,
0, nullptr);
frag_vbo_.release();
}
// Some shaders optimize through multiple iterations which requires ping-ponging textures
// - If there are only two iterations, we can just create one backend texture and then the
// destination can be the second
// - If there are more than two iterations, we need to ping pong back and forth between two
// textures. We can still use the destination as the last iteration, but we'll need textures
// for the iterative process.
int real_iteration_count;
if (job.GetIterationCount() > 1 && !job.GetIterativeInput().isEmpty()) {
real_iteration_count = job.GetIterationCount();
} else {
real_iteration_count = 1;
}
TexturePtr output_tex, input_tex;
if (real_iteration_count > 1) {
// Create one texture to bounce off
output_tex = CreateTexture(destination_params);
if (real_iteration_count > 2) {
// Create a second texture bounce off
input_tex = CreateTexture(destination_params);
}
}
GLint iteration_location =
functions_->glGetUniformLocation(shader, "ove_iteration");
for (int iteration = 0; iteration < real_iteration_count; iteration++) {
// Set iteration number
if (iteration_location > -1) {
functions_->glUniform1i(iteration_location, iteration);
}
// Replace iterative input
if (iteration == real_iteration_count - 1) {
// This is the last iteration, draw to the destination
if (destination) {
// If we have a destination texture, draw to it
AttachTextureAsDestination(destination->id());
} else if (iteration > 0) {
// Otherwise, if we were iterating before, detach texture now
DetachTextureAsDestination();
}
// Clear the destination if the caller requested it
if (clear_destination) {
ClearDestinationInternal();
}
// If the job has vertex coordinate overrides use them instead of the defaults.
if (!job.GetVertexCoordinates().isEmpty()) {
Q_ASSERT(job.GetVertexCoordinates().size() == 18);
vert_vbo_.allocate(job.GetVertexCoordinates().constData(),
job.GetVertexCoordinates().size() * sizeof(float));
} else {
// Always draw to output_tex, which gets swapped with input_tex every iteration
AttachTextureAsDestination(output_tex->id());
vert_vbo_.allocate(blit_vertices.constData(),
blit_vertices.size() * sizeof(GLfloat));
}
vert_vbo_.release();
QOpenGLBuffer frag_vbo_;
frag_vbo_.create();
frag_vbo_.bind();
frag_vbo_.allocate(blit_texcoords.constData(),
blit_texcoords.size() * sizeof(GLfloat));
frag_vbo_.release();
GLint vertex_location =
functions_->glGetAttribLocation(shader, "a_position");
if (vertex_location != -1) {
vert_vbo_.bind();
functions_->glEnableVertexAttribArray(vertex_location);
functions_->glVertexAttribPointer(vertex_location, 3, GL_FLOAT,
GL_FALSE, 0, nullptr);
vert_vbo_.release();
}
if (iteration > 0) {
// If this is not the first iteration, replace the iterative texture with the one we
// last drew
const QString &iterative_input = job.GetIterativeInput();
functions_->glActiveTexture(
GL_TEXTURE0 + texture_index_map.value(iterative_input));
functions_->glBindTexture(GL_TEXTURE_2D,
input_tex->id().value<GLuint>());
// At this time, we only support iterating 2D textures
PrepareInputTexture(GL_TEXTURE_2D,
job.GetInterpolation(iterative_input));
GLint tex_location = functions_->glGetAttribLocation(shader, "a_texcoord");
if (tex_location != -1) {
frag_vbo_.bind();
functions_->glEnableVertexAttribArray(tex_location);
functions_->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE,
0, nullptr);
frag_vbo_.release();
}
// Swap so that the next iteration, the texture we draw now will be the input texture next
std::swap(output_tex, input_tex);
// Blit this texture through this shader
{
PRINT_GL_ERRORS;
functions_->glDrawArrays(GL_TRIANGLES, 0, blit_vertices.size() / 3);
// Some shaders optimize through multiple iterations which requires ping-ponging textures
// - If there are only two iterations, we can just create one backend texture and then the
// destination can be the second
// - If there are more than two iterations, we need to ping pong back and forth between two
// textures. We can still use the destination as the last iteration, but we'll need textures
// for the iterative process.
int real_iteration_count;
if (job.GetIterationCount() > 1 && !job.GetIterativeInput().isEmpty()) {
real_iteration_count = job.GetIterationCount();
} else {
real_iteration_count = 1;
}
TexturePtr output_tex, input_tex;
if (real_iteration_count > 1) {
// Create one texture to bounce off
output_tex = CreateTexture(destination_params);
if (real_iteration_count > 2) {
// Create a second texture bounce off
input_tex = CreateTexture(destination_params);
}
}
GLint iteration_location =
functions_->glGetUniformLocation(shader, "ove_iteration");
for (int iteration = 0; iteration < real_iteration_count; iteration++) {
// Set iteration number
if (iteration_location > -1) {
functions_->glUniform1i(iteration_location, iteration);
}
// Replace iterative input
if (iteration == real_iteration_count - 1) {
// This is the last iteration, draw to the destination
if (destination) {
// If we have a destination texture, draw to it
AttachTextureAsDestination(destination->id());
} else if (iteration > 0) {
// Otherwise, if we were iterating before, detach texture now
DetachTextureAsDestination();
}
// Clear the destination if the caller requested it
if (clear_destination) {
ClearDestinationInternal();
}
} else {
// Always draw to output_tex, which gets swapped with input_tex every iteration
AttachTextureAsDestination(output_tex->id());
}
if (iteration > 0) {
// If this is not the first iteration, replace the iterative texture with the one we
// last drew
const QString &iterative_input = job.GetIterativeInput();
functions_->glActiveTexture(
GL_TEXTURE0 + texture_index_map.value(iterative_input));
functions_->glBindTexture(GL_TEXTURE_2D,
input_tex->id().value<GLuint>());
// At this time, we only support iterating 2D textures
PrepareInputTexture(GL_TEXTURE_2D,
job.GetInterpolation(iterative_input));
}
// Swap so that the next iteration, the texture we draw now will be the input texture next
std::swap(output_tex, input_tex);
// Blit this texture through this shader
{
PRINT_GL_ERRORS;
functions_->glDrawArrays(GL_TRIANGLES, 0, blit_vertices.size() / 3);
}
}
if (destination) {
// Reset framebuffer to default if we were drawing to a texture
DetachTextureAsDestination();
}
// Release any textures we bound before
for (int i = textures_to_bind.size() - 1; i >= 0; i--) {
TexturePtr texture = textures_to_bind.at(i).texture;
GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D :
GL_TEXTURE_2D;
functions_->glActiveTexture(GL_TEXTURE0 + i);
functions_->glBindTexture(target, 0);
}
// Release shader
functions_->glUseProgram(0);
// Release vertex array object
frag_vbo_.destroy();
vert_vbo_.destroy();
vao_.release();
vao_.destroy();
}
catch (std::bad_cast e){}
if (destination) {
// Reset framebuffer to default if we were drawing to a texture
DetachTextureAsDestination();
}
// Release any textures we bound before
for (int i = textures_to_bind.size() - 1; i >= 0; i--) {
TexturePtr texture = textures_to_bind.at(i).texture;
GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D :
GL_TEXTURE_2D;
functions_->glActiveTexture(GL_TEXTURE0 + i);
functions_->glBindTexture(target, 0);
}
// Release shader
functions_->glUseProgram(0);
// Release vertex array object
frag_vbo_.destroy();
vert_vbo_.destroy();
vao_.release();
vao_.destroy();
}
GLint OpenGLRenderer::GetInternalFormat(PixelFormat format, int channel_layout)
+1 -1
View File
@@ -69,7 +69,7 @@ public:
const QPointF &pt) override;
protected:
virtual void Blit(QVariant shader, olive::ShaderJob job,
virtual void Blit(QVariant shader, olive::AcceleratedJob& job,
olive::Texture *destination,
olive::VideoParams destination_params,
bool clear_destination) override;
+6 -1
View File
@@ -1 +1,6 @@
target_sources(libolive-editor PRIVATE pluginrenderer.cpp pluginrenderer.h)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
render/plugin/pluginrenderer.cpp
render/plugin/pluginrenderer.h
PARENT_SCOPE
)
+6 -4
View File
@@ -20,13 +20,15 @@
//
// Created by mikesolar on 25-10-19.
//
#define GL_PREAMBLE //QMutexLocker __l(&global_opengl_mutex);
#include "pluginrenderer.h"
#include "pluginSupport/OlivePluginInstance.h"
void olive::plugin::PluginRenderer::Blit(QVariant shader, ShaderJob job,
Texture *destination,
VideoParams destination_params,
void olive::plugin::PluginRenderer::Blit(QVariant shader,
olive::AcceleratedJob &job,
olive::Texture *destination,
olive::VideoParams destination_params,
bool clear_destination)
{
+18 -7
View File
@@ -23,20 +23,31 @@
#ifndef PLUGINRENDERER_H
#define PLUGINRENDERER_H
#include <QOpenGLExtraFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLFunctions>
#include <QOpenGLShader>
#include <QOpenGLVertexArrayObject>
#include <QThread>
#include <QOffscreenSurface>
#include "render/renderer.h"
#include "render/job/pluginjob.h"
#include "render/opengl/openglrenderer.h"
namespace olive
{
namespace plugin{
class PluginRenderer : public olive::Renderer{
class PluginRenderer : public olive::OpenGLRenderer{
Q_OBJECT
public:
PluginRenderer(QObject *parent=nullptr):Renderer(parent){};
PluginRenderer(QObject *parent=nullptr):OpenGLRenderer(parent){};
virtual ~PluginRenderer() override{};
protected:
void Blit(QVariant shader,
ShaderJob job,
Texture *destination,
VideoParams destination_params,
bool clear_destination) override;
virtual void Blit(QVariant shader, olive::AcceleratedJob& job,
olive::Texture *destination,
olive::VideoParams destination_params,
bool clear_destination) override;
};
}
}
+5 -4
View File
@@ -29,6 +29,7 @@
#include "render/job/colortransformjob.h"
#include "render/videoparams.h"
#include "texture.h"
#include "job/pluginjob.h"
namespace olive
{
@@ -47,15 +48,16 @@ public:
void DestroyTexture(Texture *texture);
void BlitToTexture(QVariant shader, olive::ShaderJob job,
virtual void BlitToTexture(QVariant shader, olive::AcceleratedJob& job,
olive::Texture *destination,
bool clear_destination = true)
{
Blit(shader, job, destination, destination->params(),
clear_destination);
}
void Blit(QVariant shader, olive::ShaderJob job, olive::VideoParams params,
void Blit(QVariant shader, olive::AcceleratedJob& job, olive::VideoParams params,
bool clear_destination = true)
{
Blit(shader, job, nullptr, params, clear_destination);
@@ -106,11 +108,10 @@ public:
const QPointF &pt) = 0;
protected:
virtual void Blit(QVariant shader, olive::ShaderJob job,
virtual void Blit(QVariant shader, olive::AcceleratedJob& job,
olive::Texture *destination,
olive::VideoParams destination_params,
bool clear_destination) = 0;
virtual QVariant CreateNativeTexture(int width, int height, int depth,
PixelFormat format, int channel_count,
const void *data = nullptr,