aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
};
}