Optimize uploading of textures.

This commit is contained in:
John Preston 2021-05-29 23:22:16 +04:00
parent 0771fc14db
commit 6a967948de
3 changed files with 83 additions and 38 deletions

View file

@ -25,7 +25,7 @@ using namespace Ui::GL;
constexpr auto kScaleForBlurTextureIndex = 3; constexpr auto kScaleForBlurTextureIndex = 3;
constexpr auto kFirstBlurPassTextureIndex = 4; constexpr auto kFirstBlurPassTextureIndex = 4;
constexpr auto kBlurTextureSizeFactor = 1.7; constexpr auto kBlurTextureSizeFactor = 1.7;
constexpr auto kBlurOpacity = 0.5; constexpr auto kBlurOpacity = 0.7;
ShaderPart FragmentBlurTexture(bool vertical, char prefix = 'v') { ShaderPart FragmentBlurTexture(bool vertical, char prefix = 'v') {
const auto offsets = (vertical ? QString("0, 1") : QString("1, 0")); const auto offsets = (vertical ? QString("0, 1") : QString("1, 0"));
@ -693,8 +693,15 @@ void Viewport::RendererGL::prepareObjects(
tileData.textures.ensureCreated(f); tileData.textures.ensureCreated(f);
tileData.framebuffers.ensureCreated(f); tileData.framebuffers.ensureCreated(f);
const auto create = [&](int index) { if (tileData.textureBlurSize == blurSize) {
tileData.textures.bind(f, tileData.textureIndex * 5 + index); return;
}
tileData.textureBlurSize = blurSize;
const auto create = [&](int framebufferIndex, int index) {
index += tileData.textureIndex * 5;
tileData.textures.bind(f, index);
f.glTexImage2D( f.glTexImage2D(
GL_TEXTURE_2D, GL_TEXTURE_2D,
0, 0,
@ -705,9 +712,17 @@ void Viewport::RendererGL::prepareObjects(
GL_RGB, GL_RGB,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
nullptr); nullptr);
tileData.framebuffers.bind(f, framebufferIndex);
f.glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
tileData.textures.id(index),
0);
}; };
create(kScaleForBlurTextureIndex); create(0, kScaleForBlurTextureIndex);
create(kFirstBlurPassTextureIndex); create(1, kFirstBlurPassTextureIndex);
} }
void Viewport::RendererGL::bindFrame( void Viewport::RendererGL::bindFrame(
@ -721,19 +736,33 @@ void Viewport::RendererGL::bindFrame(
GLint internalformat, GLint internalformat,
GLint format, GLint format,
QSize size, QSize size,
QSize hasSize,
int stride, int stride,
const void *data) { const void *data) {
f.glPixelStorei(GL_UNPACK_ROW_LENGTH, stride); f.glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
f.glTexImage2D( if (hasSize != size) {
GL_TEXTURE_2D, f.glTexImage2D(
0, GL_TEXTURE_2D,
internalformat, 0,
size.width(), internalformat,
size.height(), size.width(),
0, size.height(),
format, 0,
GL_UNSIGNED_BYTE, format,
data); GL_UNSIGNED_BYTE,
data);
} else {
f.glTexSubImage2D(
GL_TEXTURE_2D,
0,
0,
0,
size.width(),
size.height(),
format,
GL_UNSIGNED_BYTE,
data);
}
f.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); f.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}; };
//if (upload) { //if (upload) {
@ -748,28 +777,54 @@ void Viewport::RendererGL::bindFrame(
const auto &image = data.original; const auto &image = data.original;
const auto stride = image.bytesPerLine() / 4; const auto stride = image.bytesPerLine() / 4;
const auto data = image.constBits(); const auto data = image.constBits();
uploadOne(GL_RGB, GL_RGBA, image.size(), stride, data); uploadOne(
GL_RGBA,
GL_RGBA,
image.size(),
tileData.rgbaSize,
stride,
data);
tileData.rgbaSize = image.size();
} }
program.argb32->setUniformValue("s_texture", GLint(0)); program.argb32->setUniformValue("s_texture", GLint(0));
} else { } else {
const auto yuv = data.yuv420; const auto yuv = data.yuv420;
const auto otherSize = yuv->chromaSize;
f.glUseProgram(program.yuv420->programId()); f.glUseProgram(program.yuv420->programId());
f.glActiveTexture(GL_TEXTURE0); f.glActiveTexture(GL_TEXTURE0);
tileData.textures.bind(f, tileData.textureIndex * 5 + 0); tileData.textures.bind(f, tileData.textureIndex * 5 + 0);
if (upload) { if (upload) {
f.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); f.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
uploadOne(GL_RED, GL_RED, yuv->size, yuv->y.stride, yuv->y.data); uploadOne(
GL_RED,
GL_RED,
yuv->size,
tileData.textureSize,
yuv->y.stride,
yuv->y.data);
tileData.textureSize = yuv->size;
} }
f.glActiveTexture(GL_TEXTURE1); f.glActiveTexture(GL_TEXTURE1);
tileData.textures.bind(f, tileData.textureIndex * 5 + 1); tileData.textures.bind(f, tileData.textureIndex * 5 + 1);
if (upload) { if (upload) {
uploadOne(GL_RED, GL_RED, otherSize, yuv->u.stride, yuv->u.data); uploadOne(
GL_RED,
GL_RED,
yuv->chromaSize,
tileData.textureChromaSize,
yuv->u.stride,
yuv->u.data);
} }
f.glActiveTexture(GL_TEXTURE2); f.glActiveTexture(GL_TEXTURE2);
tileData.textures.bind(f, tileData.textureIndex * 5 + 2); tileData.textures.bind(f, tileData.textureIndex * 5 + 2);
if (upload) { if (upload) {
uploadOne(GL_RED, GL_RED, otherSize, yuv->v.stride, yuv->v.data); uploadOne(
GL_RED,
GL_RED,
yuv->chromaSize,
tileData.textureChromaSize,
yuv->v.stride,
yuv->v.data);
tileData.textureChromaSize = yuv->chromaSize;
f.glPixelStorei(GL_UNPACK_ALIGNMENT, 4); f.glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
} }
program.yuv420->setUniformValue("y_texture", GLint(0)); program.yuv420->setUniformValue("y_texture", GLint(0));
@ -782,13 +837,6 @@ void Viewport::RendererGL::drawDownscalePass(
QOpenGLFunctions &f, QOpenGLFunctions &f,
TileData &tileData) { TileData &tileData) {
tileData.framebuffers.bind(f, 0); tileData.framebuffers.bind(f, 0);
f.glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
tileData.textures.id(
tileData.textureIndex * 5 + kScaleForBlurTextureIndex),
0);
const auto program = _rgbaFrame const auto program = _rgbaFrame
? &*_downscaleProgram.argb32 ? &*_downscaleProgram.argb32
@ -802,13 +850,6 @@ void Viewport::RendererGL::drawFirstBlurPass(
TileData &tileData, TileData &tileData,
QSize blurSize) { QSize blurSize) {
tileData.framebuffers.bind(f, 1); tileData.framebuffers.bind(f, 1);
f.glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
tileData.textures.id(
tileData.textureIndex * 5 + kFirstBlurPassTextureIndex),
0);
f.glUseProgram(_blurProgram->programId()); f.glUseProgram(_blurProgram->programId());
f.glActiveTexture(GL_TEXTURE0); f.glActiveTexture(GL_TEXTURE0);

View file

@ -48,14 +48,18 @@ public:
private: private:
struct TileData { struct TileData {
quintptr id = 0; quintptr id = 0;
not_null<PeerData*> peer;
Ui::GL::Textures<5> textures; Ui::GL::Textures<5> textures;
Ui::GL::Framebuffers<2> framebuffers; Ui::GL::Framebuffers<2> framebuffers;
mutable int textureIndex = 0;
mutable int trackIndex = -1;
Ui::Animations::Simple outlined; Ui::Animations::Simple outlined;
QRect nameRect; QRect nameRect;
not_null<PeerData*> peer;
int nameVersion = 0; int nameVersion = 0;
mutable int textureIndex = 0;
mutable int trackIndex = -1;
mutable QSize rgbaSize;
mutable QSize textureSize;
mutable QSize textureChromaSize;
mutable QSize textureBlurSize;
bool stale = false; bool stale = false;
bool outline = false; bool outline = false;
}; };

@ -1 +1 @@
Subproject commit 42a2041ca7b6c67716c6918c0fab49d4a1e298b2 Subproject commit 26ed210ad24f9a25c8f12056489bfd0ede8eac00