various: pixel optimizations

Several things are accomplished in this commit, including:

- Use OIIO instead of our own functions for pixel format conversions
  (cleaner code/less for us to maintain)

- Fold all PixelService functions into the PixelFormat class
  (cleaner code)

- Moved OpenGL pixel definitions to OpenGL classes and out of the
  global classes.

- Add support for RGB buffers as well as RGBA (optimization)
This commit is contained in:
itsmattkc
2020-02-27 13:54:38 +11:00
parent 0624184b18
commit 02ce48d0c6
27 changed files with 491 additions and 564 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
#include "render/backend/audio/audiobackend.h"
#include "render/backend/opengl/openglbackend.h"
#include "render/colormanager.h"
#include "render/pixelservice.h"
#include "render/pixelformat.h"
Exporter::Exporter(ViewerOutput* viewer,
Encoder *encoder,
@@ -121,7 +121,7 @@ void Exporter::EncodeFrame()
// OCIO conversion requires a frame in 32F format
if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) {
frame = PixelService::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
frame = PixelFormat::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
}
// Color conversion must be done with unassociated alpha, and the pipeline is always associated
+4 -6
View File
@@ -9,7 +9,7 @@
#include "openglcolorprocessor.h"
#include "openglrenderfunctions.h"
#include "render/colormanager.h"
#include "render/pixelservice.h"
#include "render/pixelformat.h"
OpenGLProxy::OpenGLProxy(QObject *parent) :
QObject(parent),
@@ -90,7 +90,7 @@ void OpenGLProxy::FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeR
}
// Convert frame to float for OCIO
frame = PixelService::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
frame = PixelFormat::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
// Perform color transform
color_processor->ConvertFrame(frame);
@@ -384,8 +384,6 @@ void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer)
{
OpenGLTextureCache::ReferencePtr texture = tex_in.value<OpenGLTextureCache::ReferencePtr>();
PixelFormat::Info format_info = PixelService::GetPixelFormatInfo(video_params_.format());
QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
buffer_.Attach(texture->texture());
buffer_.Bind();
@@ -394,8 +392,8 @@ void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer)
0,
video_params_.effective_width(),
video_params_.effective_height(),
format_info.pixel_format,
format_info.gl_pixel_type,
OpenGLRenderFunctions::GetPixelFormat(video_params_.format()),
OpenGLRenderFunctions::GetPixelType(video_params_.format()),
buffer);
buffer_.Release();
@@ -71,6 +71,67 @@ void OpenGLRenderFunctions::PrepareToDraw(QOpenGLFunctions* f) {
f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GLint OpenGLRenderFunctions::GetInternalFormat(const PixelFormat::Format &format)
{
switch (format) {
case PixelFormat::PIX_FMT_RGB8:
return GL_RGB8;
case PixelFormat::PIX_FMT_RGBA8:
return GL_RGBA8;
case PixelFormat::PIX_FMT_RGB16U:
return GL_RGB16;
case PixelFormat::PIX_FMT_RGBA16U:
return GL_RGBA16;
case PixelFormat::PIX_FMT_RGB16F:
return GL_RGB16F;
case PixelFormat::PIX_FMT_RGBA16F:
return GL_RGBA16F;
case PixelFormat::PIX_FMT_RGB32F:
return GL_RGB32F;
case PixelFormat::PIX_FMT_RGBA32F:
return GL_RGBA32F;
case PixelFormat::PIX_FMT_INVALID:
case PixelFormat::PIX_FMT_COUNT:
break;
}
return GL_INVALID_VALUE;
}
GLenum OpenGLRenderFunctions::GetPixelFormat(const PixelFormat::Format &format)
{
if (PixelFormat::FormatHasAlphaChannel(format)) {
return GL_RGBA;
} else {
return GL_RGB;
}
}
GLenum OpenGLRenderFunctions::GetPixelType(const PixelFormat::Format &format)
{
switch (format) {
case PixelFormat::PIX_FMT_RGB8:
case PixelFormat::PIX_FMT_RGBA8:
return GL_UNSIGNED_BYTE;
case PixelFormat::PIX_FMT_RGB16U:
case PixelFormat::PIX_FMT_RGBA16U:
return GL_UNSIGNED_SHORT;
case PixelFormat::PIX_FMT_RGB16F:
case PixelFormat::PIX_FMT_RGBA16F:
return GL_HALF_FLOAT;
case PixelFormat::PIX_FMT_RGB32F:
case PixelFormat::PIX_FMT_RGBA32F:
return GL_FLOAT;
case PixelFormat::PIX_FMT_INVALID:
case PixelFormat::PIX_FMT_COUNT:
break;
}
return GL_INVALID_VALUE;
}
void OpenGLRenderFunctions::Blit(OpenGLShaderPtr pipeline, bool flipped, QMatrix4x4 matrix) {
// FIXME: is currentContext() reliable here?
QOpenGLFunctions* func = QOpenGLContext::currentContext()->functions();
@@ -26,6 +26,7 @@
#include <QOpenGLFunctions>
#include "openglshader.h"
#include "render/pixelformat.h"
class OpenGLRenderFunctions {
public:
@@ -50,6 +51,12 @@ public:
static void PrepareToDraw(QOpenGLFunctions* f);
static GLint GetInternalFormat(const PixelFormat::Format& format);
static GLenum GetPixelFormat(const PixelFormat::Format& format);
static GLenum GetPixelType(const PixelFormat::Format& format);
};
#endif // OPENGLFUNCTIONS_H
+7 -10
View File
@@ -23,7 +23,8 @@
#include <QDateTime>
#include <QDebug>
#include "render/pixelservice.h"
#include "openglrenderfunctions.h"
#include "render/pixelformat.h"
OpenGLTexture::OpenGLTexture() :
created_ctx_(nullptr),
@@ -120,16 +121,14 @@ void OpenGLTexture::Upload(const void *data)
Bind();
PixelFormat::Info info = PixelService::GetPixelFormatInfo(format_);
created_ctx_->functions()->glTexSubImage2D(GL_TEXTURE_2D,
0,
0,
0,
width_,
height_,
info.pixel_format,
info.gl_pixel_type,
OpenGLRenderFunctions::GetPixelFormat(format_),
OpenGLRenderFunctions::GetPixelType(format_),
data);
Release();
@@ -152,16 +151,14 @@ void OpenGLTexture::CreateInternal(QOpenGLContext* create_ctx, GLuint* tex, cons
f->glBindTexture(GL_TEXTURE_2D, *tex);
// Allocate storage for texture
const PixelFormat::Info& bit_depth = PixelService::GetPixelFormatInfo(format_);
f->glTexImage2D(GL_TEXTURE_2D,
0,
bit_depth.internal_format,
OpenGLRenderFunctions::GetInternalFormat(format_),
width_,
height_,
0,
bit_depth.pixel_format,
bit_depth.gl_pixel_type,
OpenGLRenderFunctions::GetPixelFormat(format_),
OpenGLRenderFunctions::GetPixelType(format_),
data);
// Set texture filtering to bilinear
+1 -1
View File
@@ -7,7 +7,7 @@
#include "openglcolorprocessor.h"
#include "openglrenderfunctions.h"
#include "render/colormanager.h"
#include "render/pixelservice.h"
#include "render/pixelformat.h"
OpenGLWorker::OpenGLWorker(VideoRenderFrameCache *frame_cache, DecoderCache* decoder_cache, QObject *parent) :
VideoRenderWorker(frame_cache, decoder_cache, parent)
+1 -1
View File
@@ -31,7 +31,7 @@
#include "config/config.h"
#include "render/diskmanager.h"
#include "render/diskmanager.h"
#include "render/pixelservice.h"
#include "render/pixelformat.h"
#include "videorenderworker.h"
VideoRenderBackend::VideoRenderBackend(QObject *parent) :
+8 -7
View File
@@ -1,17 +1,17 @@
#include "videorenderworker.h"
#include "common/define.h"
#include "common/functiontimer.h"
#include "node/block/transition/transition.h"
#include "node/node.h"
#include "project/project.h"
#include "render/pixelservice.h"
#include "render/pixelformat.h"
VideoRenderWorker::VideoRenderWorker(VideoRenderFrameCache *frame_cache, DecoderCache* decoder_cache, QObject *parent) :
RenderWorker(decoder_cache, parent),
frame_cache_(frame_cache),
operating_mode_(kHashRenderCache)
{
}
const VideoRenderingParams &VideoRenderWorker::video_params()
@@ -225,10 +225,11 @@ void VideoRenderWorker::CloseInternal()
void VideoRenderWorker::Download(const rational& time, QVariant texture, QString filename)
{
PixelFormat::Info format_info = PixelService::GetPixelFormatInfo(video_params().format());
// Set up OIIO::ImageSpec for compressing cached images on disk
OIIO::ImageSpec spec(video_params().effective_width(), video_params().effective_height(), kRGBAChannels, format_info.oiio_desc);
OIIO::ImageSpec spec(video_params().effective_width(),
video_params().effective_height(),
PixelFormat::ChannelCount(video_params().format()),
PixelFormat::GetOIIOTypeDesc(video_params().format()));
if (video_params_.format() != PixelFormat::PIX_FMT_RGBA8
&& video_params_.format() != PixelFormat::PIX_FMT_RGBA16U) {
@@ -249,7 +250,7 @@ void VideoRenderWorker::Download(const rational& time, QVariant texture, QString
if (out) {
out->open(working_fn_std, spec);
out->write_image(format_info.oiio_desc, download_buffer_.data());
out->write_image(PixelFormat::GetOIIOTypeDesc(video_params().format()), download_buffer_.data());
out->close();
#if OIIO_VERSION < 10903
@@ -276,7 +277,7 @@ void VideoRenderWorker::Download(const rational& time, QVariant texture, QString
void VideoRenderWorker::ResizeDownloadBuffer()
{
download_buffer_.resize(PixelService::GetBufferSize(video_params_.format(), video_params_.effective_width(), video_params_.effective_height()));
download_buffer_.resize(PixelFormat::GetBufferSize(video_params_.format(), video_params_.effective_width(), video_params_.effective_height()));
}
NodeValueTable VideoRenderWorker::RenderBlock(const TrackOutput *track, const TimeRange &range)