aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2015-01-29 12:26:31 +0000
committerGunnar Sletta <gunnar@sletta.org>2015-02-03 13:58:00 +0000
commita49b0ad7866046c28fb38f0f70ddf626e12c3099 (patch)
treefd630807d84f151d9c086d21d47c7acb62214c0a /src
parentd302abb3d056a1ae0997ef03f442bfbd6547be0c (diff)
Release atlas texture's image instance once uploaded
Sitting on the instance makes it impossible for custom texture factories to release images to keep down memory. Also, ditch the extra QRect used to store the nonpadded atlas rect as this is easily reachable from the padded one. Change-Id: I4914753cc43a6f3173cfc9b210e02b2770ef33fd Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp64
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h12
2 files changed, 62 insertions, 14 deletions
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index cb82d721ca..cfff35904f 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -384,12 +384,14 @@ void Atlas::bind(QSGTexture::Filtering filtering)
Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare, 3);
+ Texture *t = m_pending_uploads.at(i);
if (m_externalFormat == GL_BGRA &&
!m_use_bgra_fallback) {
- uploadBgra(m_pending_uploads.at(i));
+ uploadBgra(t);
} else {
- upload(m_pending_uploads.at(i));
+ upload(t);
}
+ t->releaseImage();
qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "atlastexture uploaded in: " << qsg_renderer_timer.elapsed()
<< "ms (" << m_pending_uploads.at(i)->image().width() << "x"
@@ -423,15 +425,15 @@ Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image)
, m_image(image)
, m_atlas(atlas)
, m_nonatlas_texture(0)
+ , m_has_alpha(image.hasAlphaChannel())
{
- m_allocated_rect_without_padding = m_allocated_rect.adjusted(1, 1, -1, -1);
float w = atlas->size().width();
float h = atlas->size().height();
-
- m_texture_coords_rect = QRectF(m_allocated_rect_without_padding.x() / w,
- m_allocated_rect_without_padding.y() / h,
- m_allocated_rect_without_padding.width() / w,
- m_allocated_rect_without_padding.height() / h);
+ QRect nopad = atlasSubRectWithoutPadding();
+ m_texture_coords_rect = QRectF(nopad.x() / w,
+ nopad.y() / h,
+ nopad.width() / w,
+ nopad.height() / h);
}
Texture::~Texture()
@@ -448,12 +450,54 @@ void Texture::bind()
QSGTexture *Texture::removedFromAtlas() const
{
- if (!m_nonatlas_texture) {
+ if (m_nonatlas_texture) {
+ m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+ m_nonatlas_texture->setFiltering(filtering());
+ return m_nonatlas_texture;
+ }
+
+ if (!m_image.isNull()) {
m_nonatlas_texture = new QSGPlainTexture();
m_nonatlas_texture->setImage(m_image);
m_nonatlas_texture->setFiltering(filtering());
- m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+
+ } else {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ // bind the atlas texture as an fbo and extract the texture..
+
+ // First extract the currently bound fbo so we can restore it later.
+ GLint currentFbo;
+ f->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFbo);
+
+ // Create an FBO and bind the atlas texture into it.
+ GLuint fbo;
+ f->glGenFramebuffers(1, &fbo);
+ f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_atlas->textureId(), 0);
+
+ // Create the target texture, QSGPlainTexture below will deal with the texparams, so we don't
+ // need to worry about those here.
+ GLuint texture;
+ f->glGenTextures(1, &texture);
+ f->glBindTexture(GL_TEXTURE_2D, texture);
+ QRect r = atlasSubRectWithoutPadding();
+ // and copy atlas into our texture.
+ f->glCopyTexImage2D(GL_TEXTURE_2D, 0, m_atlas->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0);
+
+ m_nonatlas_texture = new QSGPlainTexture();
+ m_nonatlas_texture->setTextureId(texture);
+ m_nonatlas_texture->setOwnsTexture(true);
+ m_nonatlas_texture->setHasAlphaChannel(m_has_alpha);
+ m_nonatlas_texture->setTextureSize(r.size());
+
+ // cleanup: unbind our atlas from the fbo, rebind the old default and delete the fbo.
+ f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+ f->glBindFramebuffer(GL_FRAMEBUFFER, (GLuint) currentFbo);
+ f->glDeleteFramebuffers(1, &fbo);
}
+
+ m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+ m_nonatlas_texture->setFiltering(filtering());
return m_nonatlas_texture;
}
diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h
index 639bdc291e..29eced9eb4 100644
--- a/src/quick/scenegraph/util/qsgatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgatlastexture_p.h
@@ -87,6 +87,9 @@ public:
QSize size() const { return m_size; }
+ GLuint internalFormat() const { return m_internalFormat; }
+ GLuint externalFormat() const { return m_externalFormat; }
+
private:
QSGAreaAllocator m_allocator;
GLuint m_texture_id;
@@ -110,26 +113,26 @@ public:
~Texture();
int textureId() const { return m_atlas->textureId(); }
- QSize textureSize() const { return m_allocated_rect_without_padding.size(); }
- bool hasAlphaChannel() const { return m_image.hasAlphaChannel(); }
+ QSize textureSize() const { return atlasSubRectWithoutPadding().size(); }
+ bool hasAlphaChannel() const { return m_has_alpha; }
bool hasMipmaps() const { return false; }
bool isAtlasTexture() const { return true; }
QRectF normalizedTextureSubRect() const { return m_texture_coords_rect; }
QRect atlasSubRect() const { return m_allocated_rect; }
- QRect atlasSubRectWithoutPadding() const { return m_allocated_rect_without_padding; }
+ QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); }
bool isTexture() const { return true; }
QSGTexture *removedFromAtlas() const;
+ void releaseImage() { m_image = QImage(); }
const QImage &image() const { return m_image; }
void bind();
private:
- QRect m_allocated_rect_without_padding;
QRect m_allocated_rect;
QRectF m_texture_coords_rect;
@@ -139,6 +142,7 @@ private:
mutable QSGPlainTexture *m_nonatlas_texture;
+ uint m_has_alpha : 1;
};
}