renderer: reinstated new and improved texture cache
This commit is contained in:
@@ -61,9 +61,6 @@ 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),
|
||||
@@ -219,12 +216,7 @@ 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_);
|
||||
|
||||
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);
|
||||
}
|
||||
TexturePtr y_plane = renderer->CreateTexture(plane_params, f->data[0], f->linesize[0] / px_size);
|
||||
|
||||
if (src_fmt == AV_PIX_FMT_YUV420P
|
||||
|| src_fmt == AV_PIX_FMT_YUV422P
|
||||
@@ -244,22 +236,13 @@ TexturePtr FFmpegDecoder::RetrieveVideoInternal(Renderer *renderer, const ration
|
||||
plane_params.set_height(plane_params.height()/2);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
ShaderJob job;
|
||||
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("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("bits_per_pixel"), NodeValue(NodeValue::kInt, bits_per_pixel));
|
||||
job.Insert(QStringLiteral("jpeg_range"), NodeValue(NodeValue::kBoolean, jpeg_range));
|
||||
|
||||
@@ -313,10 +296,6 @@ 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,10 +165,6 @@ 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_;
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ void OpenGLRenderer::ClearDestination(Texture *texture, double r, double g, doub
|
||||
GL_PREAMBLE;
|
||||
|
||||
if (texture) {
|
||||
AttachTextureAsDestination(texture);
|
||||
AttachTextureAsDestination(texture->id());
|
||||
}
|
||||
|
||||
ClearDestinationInternal(r, g, b, a);
|
||||
@@ -225,7 +225,7 @@ QVariant OpenGLRenderer::CreateNativeTexture(int width, int height, int depth, V
|
||||
return texture;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::AttachTextureAsDestination(Texture* texture)
|
||||
void OpenGLRenderer::AttachTextureAsDestination(const QVariant &texture)
|
||||
{
|
||||
PRINT_GL_ERRORS;
|
||||
|
||||
@@ -233,7 +233,7 @@ void OpenGLRenderer::AttachTextureAsDestination(Texture* texture)
|
||||
functions_->glFramebufferTexture2D(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
texture->id().value<GLuint>(),
|
||||
texture.value<GLuint>(),
|
||||
0);
|
||||
}
|
||||
|
||||
@@ -291,14 +291,13 @@ void OpenGLRenderer::DestroyNativeShader(QVariant shader)
|
||||
functions_->glDeleteProgram(program);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int linesize)
|
||||
void OpenGLRenderer::UploadToTexture(const QVariant &handle, const VideoParams &p, const void *data, int linesize)
|
||||
{
|
||||
GL_PREAMBLE;
|
||||
|
||||
GLuint t = texture->id().value<GLuint>();
|
||||
const VideoParams& p = texture->params();
|
||||
GLuint t = handle.value<GLuint>();
|
||||
|
||||
bool is_3d = texture->params().is_3d();
|
||||
bool is_3d = p.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;
|
||||
@@ -332,16 +331,14 @@ void OpenGLRenderer::UploadToTexture(Texture *texture, const void *data, int lin
|
||||
functions_->glBindTexture(tex_type, current_tex);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int linesize)
|
||||
void OpenGLRenderer::DownloadFromTexture(const QVariant &id, const VideoParams &p, void *data, int linesize)
|
||||
{
|
||||
GL_PREAMBLE;
|
||||
|
||||
const VideoParams& p = texture->params();
|
||||
|
||||
GLint current_tex;
|
||||
functions_->glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_tex);
|
||||
|
||||
AttachTextureAsDestination(texture);
|
||||
AttachTextureAsDestination(id);
|
||||
|
||||
functions_->glPixelStorei(GL_PACK_ROW_LENGTH, linesize);
|
||||
|
||||
@@ -372,7 +369,7 @@ void OpenGLRenderer::Flush()
|
||||
|
||||
Color OpenGLRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
|
||||
{
|
||||
AttachTextureAsDestination(texture);
|
||||
AttachTextureAsDestination(texture->id());
|
||||
|
||||
QByteArray data(VideoParams::GetBytesPerPixel(texture->format(), texture->channel_count()), Qt::Uninitialized);
|
||||
|
||||
@@ -610,7 +607,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
// This is the last iteration, draw to the destination
|
||||
if (destination) {
|
||||
// If we have a destination texture, draw to it
|
||||
AttachTextureAsDestination(destination);
|
||||
AttachTextureAsDestination(destination->id());
|
||||
} else if (iteration > 0) {
|
||||
// Otherwise, if we were iterating before, detach texture now
|
||||
DetachTextureAsDestination();
|
||||
@@ -622,7 +619,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
}
|
||||
} else {
|
||||
// Always draw to output_tex, which gets swapped with input_tex every iteration
|
||||
AttachTextureAsDestination(output_tex.get());
|
||||
AttachTextureAsDestination(output_tex->id());
|
||||
}
|
||||
|
||||
if (iteration > 0) {
|
||||
|
||||
@@ -55,9 +55,9 @@ public:
|
||||
|
||||
virtual void DestroyNativeShader(QVariant shader) override;
|
||||
|
||||
virtual void UploadToTexture(olive::Texture* texture, const void* data, int linesize) override;
|
||||
virtual void UploadToTexture(const QVariant &handle, const VideoParams ¶ms, const void* data, int linesize) override;
|
||||
|
||||
virtual void DownloadFromTexture(olive::Texture* texture, void* data, int linesize) override;
|
||||
virtual void DownloadFromTexture(const QVariant &handle, const VideoParams ¶ms, void* data, int linesize) override;
|
||||
|
||||
virtual void Flush() override;
|
||||
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
|
||||
static GLenum GetPixelFormat(int channel_count);
|
||||
|
||||
void AttachTextureAsDestination(olive::Texture* texture);
|
||||
void AttachTextureAsDestination(const QVariant &texture);
|
||||
|
||||
void DetachTextureAsDestination();
|
||||
|
||||
|
||||
+32
-25
@@ -29,45 +29,52 @@ namespace olive {
|
||||
Renderer::Renderer(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (USE_TEXTURE_CACHE) {
|
||||
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);
|
||||
if (v.isNull()) {
|
||||
v = CreateNativeTexture(params.effective_width(), params.effective_height(), params.effective_depth(),
|
||||
params.format(), params.channel_count(), data, linesize);
|
||||
} else {
|
||||
UploadToTexture(v, params, 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());
|
||||
if (USE_TEXTURE_CACHE) {
|
||||
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()});
|
||||
|
||||
ClearOldTextures();
|
||||
} else {
|
||||
DestroyNativeTexture(texture->id());
|
||||
}
|
||||
}
|
||||
|
||||
TexturePtr Renderer::InterlaceTexture(TexturePtr top, TexturePtr bottom, const VideoParams ¶ms)
|
||||
|
||||
@@ -91,9 +91,9 @@ public:
|
||||
|
||||
virtual void DestroyNativeShader(QVariant shader) = 0;
|
||||
|
||||
virtual void UploadToTexture(olive::Texture* texture, const void* data, int linesize) = 0;
|
||||
virtual void UploadToTexture(const QVariant &handle, const VideoParams ¶ms, const void* data, int linesize) = 0;
|
||||
|
||||
virtual void DownloadFromTexture(olive::Texture* texture, void* data, int linesize) = 0;
|
||||
virtual void DownloadFromTexture(const QVariant &handle, const VideoParams ¶ms, void* data, int linesize) = 0;
|
||||
|
||||
virtual void Flush() = 0;
|
||||
|
||||
@@ -130,6 +130,8 @@ private:
|
||||
|
||||
bool GetColorContext(const ColorTransformJob &color_job, ColorContext* ctx);
|
||||
|
||||
void ClearOldTextures();
|
||||
|
||||
QHash<QString, ColorContext> color_cache_;
|
||||
|
||||
struct CachedTexture
|
||||
@@ -143,7 +145,8 @@ private:
|
||||
qint64 accessed;
|
||||
};
|
||||
|
||||
const int MAX_TEXTURE_LIFE = 10000;
|
||||
static const int MAX_TEXTURE_LIFE = 5000;
|
||||
static const bool USE_TEXTURE_CACHE = true;
|
||||
std::list<CachedTexture> texture_cache_;
|
||||
|
||||
QMutex color_cache_mutex_;
|
||||
@@ -152,9 +155,6 @@ private:
|
||||
|
||||
QVariant interlace_texture_;
|
||||
|
||||
private slots:
|
||||
void ClearOldTextures();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ Texture::~Texture()
|
||||
void Texture::Upload(void *data, int linesize)
|
||||
{
|
||||
if (renderer_) {
|
||||
renderer_->UploadToTexture(this, data, linesize);
|
||||
renderer_->UploadToTexture(this->id(), this->params(), data, linesize);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::Download(void *data, int linesize)
|
||||
{
|
||||
if (renderer_) {
|
||||
renderer_->DownloadFromTexture(this, data, linesize);
|
||||
renderer_->DownloadFromTexture(this->id(), this->params(), data, linesize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user