render: create less textures
This commit is contained in:
@@ -61,6 +61,9 @@ FFmpegDecoder::FFmpegDecoder() :
|
||||
input_fmt_(AV_PIX_FMT_NONE),
|
||||
native_internal_pix_fmt_(VideoParams::kFormatInvalid),
|
||||
native_output_pix_fmt_(VideoParams::kFormatInvalid),
|
||||
y_tex_(nullptr),
|
||||
u_tex_(nullptr),
|
||||
v_tex_(nullptr),
|
||||
working_frame_(nullptr),
|
||||
working_packet_(nullptr),
|
||||
cache_at_zero_(false),
|
||||
@@ -216,7 +219,12 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration
|
||||
plane_params.set_channel_count(1);
|
||||
plane_params.set_divider(1);
|
||||
plane_params.set_format(native_internal_pix_fmt_);
|
||||
TexturePtr y_plane = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size);
|
||||
|
||||
if (!y_tex_) {
|
||||
y_tex_ = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size);
|
||||
} else {
|
||||
y_tex_->Upload(f->data[0], f->linesize[0] / px_size);
|
||||
}
|
||||
|
||||
if (src_fmt == AV_PIX_FMT_YUV420P
|
||||
|| src_fmt == AV_PIX_FMT_YUV422P
|
||||
@@ -236,13 +244,22 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration
|
||||
plane_params.set_height(plane_params.height()/2);
|
||||
}
|
||||
|
||||
TexturePtr u_plane = renderer->CreateTexture(plane_params, f->data[1], f->linesize[1] / px_size);
|
||||
TexturePtr v_plane = renderer->CreateTexture(plane_params, f->data[2], f->linesize[2] / px_size);
|
||||
if (!u_tex_) {
|
||||
u_tex_ = renderer->CreateTexture(plane_params, f->data[1], f->linesize[1] / px_size);
|
||||
} else {
|
||||
u_tex_->Upload(f->data[1], f->linesize[1] / px_size);
|
||||
}
|
||||
|
||||
if (!v_tex_) {
|
||||
v_tex_ = renderer->CreateTexture(plane_params, f->data[2], f->linesize[2] / px_size);
|
||||
} else {
|
||||
v_tex_->Upload(f->data[2], f->linesize[2] / px_size);
|
||||
}
|
||||
|
||||
ShaderJob job;
|
||||
job.Insert(QStringLiteral("y_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(y_plane)));
|
||||
job.Insert(QStringLiteral("u_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(u_plane)));
|
||||
job.Insert(QStringLiteral("v_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(v_plane)));
|
||||
job.Insert(QStringLiteral("y_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(y_tex_)));
|
||||
job.Insert(QStringLiteral("u_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(u_tex_)));
|
||||
job.Insert(QStringLiteral("v_channel"), NodeValue(NodeValue::kTexture, QVariant::fromValue(v_tex_)));
|
||||
job.Insert(QStringLiteral("bits_per_pixel"), NodeValue(NodeValue::kInt, bits_per_pixel));
|
||||
job.Insert(QStringLiteral("jpeg_range"), NodeValue(NodeValue::kBoolean, jpeg_range));
|
||||
|
||||
@@ -296,6 +313,10 @@ void FFmpegDecoder::CloseInternal()
|
||||
input_fmt_ = AV_PIX_FMT_NONE;
|
||||
native_internal_pix_fmt_ = VideoParams::kFormatInvalid;
|
||||
native_output_pix_fmt_ = VideoParams::kFormatInvalid;
|
||||
|
||||
y_tex_ = nullptr;
|
||||
u_tex_ = nullptr;
|
||||
v_tex_ = nullptr;
|
||||
}
|
||||
|
||||
QString FFmpegDecoder::id() const
|
||||
|
||||
@@ -165,6 +165,10 @@ private:
|
||||
VideoParams::Format native_output_pix_fmt_;
|
||||
int native_channel_count_;
|
||||
|
||||
TexturePtr y_tex_;
|
||||
TexturePtr u_tex_;
|
||||
TexturePtr v_tex_;
|
||||
|
||||
AVFrame *working_frame_;
|
||||
AVPacket *working_packet_;
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ void OpenGLRenderer::Init(QOpenGLContext *existing_ctx)
|
||||
|
||||
bool OpenGLRenderer::Init()
|
||||
{
|
||||
QMutexLocker locker(&global_opengl_mutex);
|
||||
GL_PREAMBLE;
|
||||
|
||||
if (context_) {
|
||||
qCritical() << "Can't initialize already initialized OpenGLRenderer";
|
||||
@@ -187,16 +187,11 @@ void OpenGLRenderer::ClearDestination(Texture *texture, double r, double g, doub
|
||||
}
|
||||
}
|
||||
|
||||
QVariant OpenGLRenderer::CreateNativeTexture2D(int width, int height, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
GL_PREAMBLE;
|
||||
|
||||
return CreateNativeTexture2DInternal(width, height, format, channel_count, data, linesize);
|
||||
}
|
||||
|
||||
QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
GL_PREAMBLE;
|
||||
bool is_3d = depth > 1;
|
||||
|
||||
// Generate new texture
|
||||
GLuint texture;
|
||||
@@ -205,18 +200,27 @@ QVariant OpenGLRenderer::CreateNativeTexture3D(int width, int height, int depth,
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize);
|
||||
|
||||
GLenum target_current = is_3d ? GL_TEXTURE_BINDING_3D : GL_TEXTURE_BINDING_2D;
|
||||
GLenum target = is_3d ? GL_TEXTURE_3D : GL_TEXTURE_2D;
|
||||
|
||||
GLint current_tex;
|
||||
functions_->glGetIntegerv(GL_TEXTURE_BINDING_3D, ¤t_tex);
|
||||
functions_->glGetIntegerv(target_current, ¤t_tex);
|
||||
|
||||
functions_->glBindTexture(GL_TEXTURE_3D, texture);
|
||||
functions_->glBindTexture(target, texture);
|
||||
|
||||
context_->extraFunctions()->glTexImage3D(GL_TEXTURE_3D, 0, GetInternalFormat(format, channel_count),
|
||||
if (is_3d) {
|
||||
context_->extraFunctions()->glTexImage3D(target, 0, GetInternalFormat(format, channel_count),
|
||||
width, height, depth, 0, GetPixelFormat(channel_count),
|
||||
GetPixelType(format), data);
|
||||
} else {
|
||||
functions_->glTexImage2D(target, 0, GetInternalFormat(format, channel_count),
|
||||
width, height, 0, GetPixelFormat(channel_count),
|
||||
GetPixelType(format), data);
|
||||
}
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
functions_->glBindTexture(GL_TEXTURE_3D, current_tex);
|
||||
functions_->glBindTexture(target, current_tex);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -294,8 +298,10 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin
|
||||
GLuint t = texture->id().value<GLuint>();
|
||||
const VideoParams& p = texture->params();
|
||||
|
||||
GLenum tex_type = texture->type() == Texture::k2D ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
||||
GLenum tex_binding = texture->type() == Texture::k2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D;
|
||||
bool is_3d = texture->params().is_3d();
|
||||
|
||||
GLenum tex_type = !is_3d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
|
||||
GLenum tex_binding = !is_3d ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D;
|
||||
|
||||
// Store currently bound texture so it can be restored later
|
||||
GLint current_tex;
|
||||
@@ -308,7 +314,7 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin
|
||||
{
|
||||
PRINT_GL_ERRORS;
|
||||
|
||||
if (texture->type() == Texture::k2D) {
|
||||
if (!is_3d) {
|
||||
functions_->glTexSubImage2D(tex_type, 0, 0, 0,
|
||||
p.effective_width(), p.effective_height(),
|
||||
GetPixelFormat(p.channel_count()), GetPixelType(p.format()),
|
||||
@@ -502,7 +508,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
|
||||
functions_->glActiveTexture(GL_TEXTURE0 + i);
|
||||
|
||||
GLenum target = (texture && texture->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D;
|
||||
GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D : GL_TEXTURE_2D;
|
||||
functions_->glBindTexture(target, tex_id);
|
||||
|
||||
if (tex_id) {
|
||||
@@ -584,11 +590,11 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
TexturePtr output_tex, input_tex;
|
||||
if (real_iteration_count > 1) {
|
||||
// Create one texture to bounce off
|
||||
output_tex = CreateTextureFromNativeHandle(CreateNativeTexture2DInternal(destination_params), destination_params);
|
||||
output_tex = CreateTexture(destination_params);
|
||||
|
||||
if (real_iteration_count > 2) {
|
||||
// Create a second texture bounce off
|
||||
input_tex = CreateTextureFromNativeHandle(CreateNativeTexture2DInternal(destination_params), destination_params);
|
||||
input_tex = CreateTexture(destination_params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,7 +654,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
// 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->type() == Texture::k3D) ? GL_TEXTURE_3D : GL_TEXTURE_2D;
|
||||
GLenum target = (texture && texture->params().is_3d()) ? GL_TEXTURE_3D : GL_TEXTURE_2D;
|
||||
functions_->glActiveTexture(GL_TEXTURE0 + i);
|
||||
functions_->glBindTexture(target, 0);
|
||||
}
|
||||
@@ -788,38 +794,6 @@ void OpenGLRenderer::ClearDestinationInternal(double r, double g, double b, doub
|
||||
functions_->glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
QVariant OpenGLRenderer::CreateNativeTexture2DInternal(int width, int height, VideoParams::Format format, int channel_count, const void *data, int linesize)
|
||||
{
|
||||
GLuint texture;
|
||||
functions_->glGenTextures(1, &texture);
|
||||
texture_params_.insert(texture, {width, height, 1, format, channel_count});
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize);
|
||||
|
||||
GLint current_tex;
|
||||
functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex);
|
||||
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
{
|
||||
PRINT_GL_ERRORS;
|
||||
functions_->glTexImage2D(GL_TEXTURE_2D, 0, GetInternalFormat(format, channel_count),
|
||||
width, height, 0, GetPixelFormat(channel_count),
|
||||
GetPixelType(format), data);
|
||||
}
|
||||
|
||||
functions_->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, current_tex);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
QVariant OpenGLRenderer::CreateNativeTexture2DInternal(const VideoParams ¶ms, const void *data, int linesize)
|
||||
{
|
||||
return CreateNativeTexture2DInternal(params.effective_width(), params.effective_height(), params.format(), params.channel_count(), data, linesize);
|
||||
}
|
||||
|
||||
GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code)
|
||||
{
|
||||
static const QString shader_preamble =
|
||||
|
||||
@@ -47,18 +47,10 @@ public:
|
||||
|
||||
virtual void PostDestroy() override;
|
||||
|
||||
public slots:
|
||||
virtual void PostInit() override;
|
||||
|
||||
virtual void DestroyInternal() override;
|
||||
|
||||
virtual void ClearDestination(olive::Texture *texture = nullptr, double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
|
||||
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) override;
|
||||
|
||||
virtual QVariant CreateNativeShader(olive::ShaderCode code) override;
|
||||
|
||||
virtual void DestroyNativeShader(QVariant shader) override;
|
||||
@@ -71,13 +63,19 @@ public slots:
|
||||
|
||||
virtual Color GetPixelFromTexture(olive::Texture *texture, const QPointF &pt) override;
|
||||
|
||||
protected slots:
|
||||
protected:
|
||||
virtual void Blit(QVariant shader,
|
||||
olive::ShaderJob job,
|
||||
olive::Texture* destination,
|
||||
olive::VideoParams destination_params,
|
||||
bool clear_destination) override;
|
||||
|
||||
virtual QVariant CreateNativeTexture(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) override;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) override;
|
||||
|
||||
virtual void DestroyInternal() override;
|
||||
|
||||
private:
|
||||
static GLint GetInternalFormat(VideoParams::Format format, int channel_layout);
|
||||
|
||||
@@ -93,9 +91,6 @@ private:
|
||||
|
||||
void ClearDestinationInternal(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0);
|
||||
|
||||
QVariant CreateNativeTexture2DInternal(int width, int height, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0);
|
||||
QVariant CreateNativeTexture2DInternal(const VideoParams ¶ms, const void* data = nullptr, int linesize = 0);
|
||||
|
||||
GLuint CompileShader(GLenum type, const QString &code);
|
||||
|
||||
QOpenGLContext* context_;
|
||||
|
||||
+58
-26
@@ -20,36 +20,54 @@
|
||||
|
||||
#include "renderer.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
#include <QVector2D>
|
||||
|
||||
#include "common/ocioutils.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
Renderer::Renderer(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, Texture::Type type, const void *data, int linesize)
|
||||
{
|
||||
QVariant v;
|
||||
|
||||
if (type == Texture::k3D) {
|
||||
v = CreateNativeTexture3D(params.effective_width(), params.effective_height(),
|
||||
params.effective_depth(), params.format(), params.channel_count(), data, linesize);
|
||||
} else {
|
||||
v = CreateNativeTexture2D(params.effective_width(), params.effective_height(), params.format(),
|
||||
params.channel_count(), data, linesize);
|
||||
}
|
||||
|
||||
return CreateTextureFromNativeHandle(v, params, type);
|
||||
QTimer *texture_garbage_collector = new QTimer(this);
|
||||
texture_garbage_collector->setInterval(MAX_TEXTURE_LIFE);
|
||||
connect(texture_garbage_collector, &QTimer::timeout, this, &Renderer::ClearOldTextures);
|
||||
texture_garbage_collector->start();
|
||||
}
|
||||
|
||||
TexturePtr Renderer::CreateTexture(const VideoParams ¶ms, const void *data, int linesize)
|
||||
{
|
||||
return CreateTexture(params, Texture::k2D, data, linesize);
|
||||
QVariant v;
|
||||
|
||||
/*for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); it++) {
|
||||
if (it->width == params.effective_width()
|
||||
&& it->height == params.effective_height()
|
||||
&& it->depth == params.effective_depth()
|
||||
&& it->format == params.format()
|
||||
&& it->channel_count == params.channel_count()) {
|
||||
this->Flush();
|
||||
v = it->handle;
|
||||
texture_cache_.erase(it);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
v = CreateNativeTexture(params.effective_width(), params.effective_height(), params.effective_depth(),
|
||||
params.format(), params.channel_count(), data, linesize);
|
||||
|
||||
return CreateTextureFromNativeHandle(v, params);
|
||||
}
|
||||
|
||||
void Renderer::DestroyTexture(Texture *texture)
|
||||
{
|
||||
/*texture_cache_.push_back({texture->params().effective_width(),
|
||||
texture->params().effective_height(),
|
||||
texture->params().effective_depth(),
|
||||
texture->params().format(),
|
||||
texture->params().channel_count(),
|
||||
texture->id(),
|
||||
QDateTime::currentMSecsSinceEpoch()});*/
|
||||
DestroyNativeTexture(texture->id());
|
||||
}
|
||||
|
||||
TexturePtr Renderer::InterlaceTexture(TexturePtr top, TexturePtr bottom, const VideoParams ¶ms)
|
||||
@@ -83,6 +101,11 @@ QVariant Renderer::GetDefaultShader()
|
||||
|
||||
void Renderer::Destroy()
|
||||
{
|
||||
for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); it++) {
|
||||
DestroyNativeTexture(it->handle);
|
||||
}
|
||||
texture_cache_.clear();
|
||||
|
||||
if (!default_shader_.isNull()) {
|
||||
DestroyNativeShader(default_shader_);
|
||||
default_shader_.clear();
|
||||
@@ -98,13 +121,13 @@ void Renderer::Destroy()
|
||||
DestroyInternal();
|
||||
}
|
||||
|
||||
TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms, Texture::Type type)
|
||||
TexturePtr Renderer::CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms)
|
||||
{
|
||||
if (v.isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<Texture>(this, v, params, type);
|
||||
return std::make_shared<Texture>(this, v, params);
|
||||
}
|
||||
|
||||
bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::ColorContext *ctx)
|
||||
@@ -175,8 +198,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col
|
||||
}
|
||||
|
||||
// Allocate 3D LUT
|
||||
color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, VideoParams::kFormatFloat32, VideoParams::kRGBChannelCount),
|
||||
Texture::k3D, values);
|
||||
color_ctx.lut3d_textures[i].texture = CreateTexture(VideoParams(edge_len, edge_len, edge_len, VideoParams::kFormatFloat32, VideoParams::kRGBChannelCount), values);
|
||||
color_ctx.lut3d_textures[i].name = sampler_name;
|
||||
color_ctx.lut3d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
|
||||
}
|
||||
@@ -206,9 +228,7 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col
|
||||
}
|
||||
|
||||
// Allocate 1D LUT
|
||||
color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, VideoParams::kFormatFloat32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount),
|
||||
Texture::k2D,
|
||||
values);
|
||||
color_ctx.lut1d_textures[i].texture = CreateTexture(VideoParams(width, height, VideoParams::kFormatFloat32, (channel == OCIO::GpuShaderDesc::TEXTURE_RED_CHANNEL) ? 1 : VideoParams::kRGBChannelCount), values);
|
||||
color_ctx.lut1d_textures[i].name = sampler_name;
|
||||
color_ctx.lut1d_textures[i].interpolation = (interpolation == OCIO::INTERP_NEAREST) ? Texture::kNearest : Texture::kLinear;
|
||||
}
|
||||
@@ -219,6 +239,18 @@ bool Renderer::GetColorContext(const ColorTransformJob &color_job, Renderer::Col
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::ClearOldTextures()
|
||||
{
|
||||
for (auto it=texture_cache_.begin(); it!=texture_cache_.end(); ) {
|
||||
if (it->accessed < QDateTime::currentMSecsSinceEpoch() - MAX_TEXTURE_LIFE) {
|
||||
DestroyNativeTexture(it->handle);
|
||||
it = texture_cache_.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::BlitColorManaged(const ColorTransformJob &color_job, Texture *destination, const VideoParams ¶ms)
|
||||
{
|
||||
ColorContext color_ctx;
|
||||
|
||||
+27
-12
@@ -45,9 +45,10 @@ public:
|
||||
|
||||
virtual bool Init() = 0;
|
||||
|
||||
TexturePtr CreateTexture(const VideoParams& params, Texture::Type type, const void* data = nullptr, int linesize = 0);
|
||||
TexturePtr CreateTexture(const VideoParams& params, const void *data = nullptr, int linesize = 0);
|
||||
|
||||
void DestroyTexture(Texture *texture);
|
||||
|
||||
void BlitToTexture(QVariant shader,
|
||||
olive::ShaderJob job,
|
||||
olive::Texture* destination,
|
||||
@@ -82,18 +83,10 @@ public:
|
||||
|
||||
virtual void PostDestroy() = 0;
|
||||
|
||||
public slots:
|
||||
virtual void PostInit() = 0;
|
||||
|
||||
virtual void DestroyInternal() = 0;
|
||||
|
||||
virtual void ClearDestination(olive::Texture *texture = nullptr, double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) = 0;
|
||||
|
||||
virtual QVariant CreateNativeTexture2D(int width, int height, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
|
||||
virtual QVariant CreateNativeTexture3D(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) = 0;
|
||||
|
||||
virtual QVariant CreateNativeShader(olive::ShaderCode code) = 0;
|
||||
|
||||
virtual void DestroyNativeShader(QVariant shader) = 0;
|
||||
@@ -106,15 +99,18 @@ public slots:
|
||||
|
||||
virtual Color GetPixelFromTexture(olive::Texture *texture, const QPointF &pt) = 0;
|
||||
|
||||
protected slots:
|
||||
protected:
|
||||
virtual void Blit(QVariant shader,
|
||||
olive::ShaderJob job,
|
||||
olive::Texture* destination,
|
||||
olive::VideoParams destination_params,
|
||||
bool clear_destination) = 0;
|
||||
|
||||
protected:
|
||||
TexturePtr CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms, Texture::Type type = Texture::k2D);
|
||||
virtual QVariant CreateNativeTexture(int width, int height, int depth, olive::VideoParams::Format format, int channel_count, const void* data = nullptr, int linesize = 0) = 0;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) = 0;
|
||||
|
||||
virtual void DestroyInternal() = 0;
|
||||
|
||||
private:
|
||||
struct ColorContext {
|
||||
@@ -130,16 +126,35 @@ private:
|
||||
|
||||
};
|
||||
|
||||
TexturePtr CreateTextureFromNativeHandle(const QVariant &v, const VideoParams ¶ms);
|
||||
|
||||
bool GetColorContext(const ColorTransformJob &color_job, ColorContext* ctx);
|
||||
|
||||
QHash<QString, ColorContext> color_cache_;
|
||||
|
||||
struct CachedTexture
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
VideoParams::Format format;
|
||||
int channel_count;
|
||||
QVariant handle;
|
||||
qint64 accessed;
|
||||
};
|
||||
|
||||
const int MAX_TEXTURE_LIFE = 10000;
|
||||
std::list<CachedTexture> texture_cache_;
|
||||
|
||||
QMutex color_cache_mutex_;
|
||||
|
||||
QVariant default_shader_;
|
||||
|
||||
QVariant interlace_texture_;
|
||||
|
||||
private slots:
|
||||
void ClearOldTextures();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const Texture::Interpolation Texture::kDefaultInterpolation = Texture::kMipmappe
|
||||
Texture::~Texture()
|
||||
{
|
||||
if (renderer_) {
|
||||
renderer_->DestroyNativeTexture(id_);
|
||||
renderer_->DestroyTexture(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-17
@@ -32,11 +32,6 @@ class Renderer;
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
k2D,
|
||||
k3D
|
||||
};
|
||||
|
||||
enum Interpolation {
|
||||
kNearest,
|
||||
kLinear,
|
||||
@@ -50,19 +45,17 @@ public:
|
||||
*/
|
||||
Texture(const VideoParams& param) :
|
||||
renderer_(nullptr),
|
||||
params_(param),
|
||||
type_(k2D)
|
||||
params_(param)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a real texture linked to a renderer backend
|
||||
*/
|
||||
Texture(Renderer* renderer, const QVariant& native, const VideoParams& param, Type type) :
|
||||
Texture(Renderer* renderer, const QVariant& native, const VideoParams& param) :
|
||||
renderer_(renderer),
|
||||
params_(param),
|
||||
id_(native),
|
||||
type_(type)
|
||||
id_(native)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -117,11 +110,6 @@ public:
|
||||
return params_.pixel_aspect_ratio();
|
||||
}
|
||||
|
||||
Type type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
Renderer* renderer() const
|
||||
{
|
||||
return renderer_;
|
||||
@@ -134,8 +122,6 @@ private:
|
||||
|
||||
QVariant id_;
|
||||
|
||||
Type type_;
|
||||
|
||||
};
|
||||
|
||||
using TexturePtr = std::shared_ptr<Texture>;
|
||||
|
||||
@@ -121,6 +121,8 @@ public:
|
||||
calculate_effective_size();
|
||||
}
|
||||
|
||||
bool is_3d() const { return depth_ > 1; }
|
||||
|
||||
const rational& time_base() const
|
||||
{
|
||||
return time_base_;
|
||||
|
||||
Reference in New Issue
Block a user