29QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context)
30 : QSGRenderContext(context)
33 , m_rhiAtlasManager(
nullptr)
34 , m_currentFrameCommandBuffer(
nullptr)
35 , m_currentFrameRenderPass(
nullptr)
36 , m_useDepthBufferFor2D(
true)
37 , m_glyphCacheResourceUpdates(
nullptr)
45void QSGDefaultRenderContext::initialize(
const QSGRenderContext::InitParams *params)
50 const InitParams *initParams =
static_cast<
const InitParams *>(params);
51 if (initParams->sType != INIT_PARAMS_MAGIC)
52 qFatal(
"QSGDefaultRenderContext: Invalid parameters passed to initialize()");
54 m_initParams = *initParams;
56 m_rhi = m_initParams.rhi;
57 m_maxTextureSize = m_rhi->resourceLimit(QRhi::TextureSizeMax);
58 if (!m_rhiAtlasManager)
59 m_rhiAtlasManager =
new QSGRhiAtlasTexture::Manager(
this, m_initParams.initialSurfacePixelSize, m_initParams.maybeSurface);
61 m_glyphCacheResourceUpdates =
nullptr;
63 m_sg->renderContextInitialized(
this);
77void QSGDefaultRenderContext::flushGlyphCaches()
79 auto it = m_staleGlyphCaches.begin();
80 while (it != m_staleGlyphCaches.end()) {
81 if (!(*it)->isActive()) {
82 qCDebug(lcGlyphCaches()) <<
"Deleting stale glyph cache:"
84 <<
"fontEngine:" << fontEngineOfRawFont((*it)->referenceFont())
85 << (*it)->referenceFont().familyName();
87 it = m_staleGlyphCaches.erase(it);
94 auto it = m_fontEnginesToClean.begin();
95 while (it != m_fontEnginesToClean.end()) {
96 if (it.value() == 0) {
97 it.key()->clearGlyphCache(
this);
98 if (!it.key()->ref.deref())
100 it = m_fontEnginesToClean.erase(it);
108void QSGDefaultRenderContext::invalidateGlyphCaches()
111 auto it = m_glyphCaches.begin();
112 while (it != m_glyphCaches.end()) {
113 if (!(*it)->isActive()) {
114 qCDebug(lcGlyphCaches()) <<
"Direct delete glyph cache:"
116 <<
"fontEngine:" << fontEngineOfRawFont(it.value()->referenceFont())
117 << it.value()->referenceFont().familyName()
118 << it.value()->referenceFont().styleName()
120 << it.key().familyName
121 << it.key().styleName
122 << it.key().faceId.filename;
125 qCDebug(lcGlyphCaches()) <<
"Stale glyph cache:"
127 <<
"fontEngine:" << fontEngineOfRawFont(it.value()->referenceFont())
128 << it.value()->referenceFont().familyName()
129 << it.value()->referenceFont().styleName()
131 << it.key().familyName
132 << it.key().styleName
133 << it.key().faceId.filename;
135 m_staleGlyphCaches.append(*it);
138 it = m_glyphCaches.erase(it);
142 qDeleteAll(m_curveGlyphAtlases);
143 m_curveGlyphAtlases.clear();
146void QSGDefaultRenderContext::invalidate()
151 qDeleteAll(m_texturesToDelete);
152 m_texturesToDelete.clear();
154 qDeleteAll(m_textures);
157 for (
auto it = m_depthStencilBuffers.cbegin(), end = m_depthStencilBuffers.cend(); it != end; ++it) {
158 QSharedPointer<QSGDepthStencilBuffer> buf = it.value().toStrongRef();
163 m_depthStencilBuffers.clear();
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 if (m_rhiAtlasManager) {
182 m_rhiAtlasManager->invalidate();
183 m_rhiAtlasManager->deleteLater();
184 m_rhiAtlasManager =
nullptr;
192 for (
auto it = m_fontEnginesToClean.constBegin(); it != m_fontEnginesToClean.constEnd(); ++it) {
193 it.key()->clearGlyphCache(
this);
194 if (!it.key()->ref.deref())
197 m_fontEnginesToClean.clear();
199 qDeleteAll(m_curveGlyphAtlases);
200 m_curveGlyphAtlases.clear();
202 qCDebug(lcGlyphCaches()) <<
"Deleting" << m_glyphCaches.size() <<
"live glyph caches";
204 qDeleteAll(m_glyphCaches);
205 m_glyphCaches.clear();
207 qCDebug(lcGlyphCaches()) <<
"Deleting" << m_staleGlyphCaches.size() <<
"stale glyph caches";
209 qDeleteAll(m_staleGlyphCaches);
210 m_staleGlyphCaches.clear();
212 resetGlyphCacheResources();
217 m_sg->renderContextInvalidated(
this);
222void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio,
223 QRhiCommandBuffer *cb,
224 const QQuickGraphicsConfiguration &config)
226 m_currentDevicePixelRatio = devicePixelRatio;
227 m_useDepthBufferFor2D = config.isDepthBufferEnabledFor2D();
232 m_currentFrameCommandBuffer = cb;
235void QSGDefaultRenderContext::beginNextFrame(QSGRenderer *renderer,
const QSGRenderTarget &renderTarget,
236 RenderPassCallback mainPassRecordingStart,
237 RenderPassCallback mainPassRecordingEnd,
238 void *callbackUserData)
240 renderer->setRenderTarget(renderTarget);
241 renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
243 m_currentFrameCommandBuffer = renderTarget.cb;
244 m_currentFrameRenderPass = renderTarget.rpDesc;
259QSGTexture *QSGDefaultRenderContext::createTexture(
const QImage &image, uint flags)
const
261 bool atlas = flags & CreateTexture_Atlas;
262 bool mipmap = flags & CreateTexture_Mipmap;
263 bool alpha = flags & CreateTexture_Alpha;
268 if (!mipmap && atlas && QThread::currentThread() == m_rhi->thread()) {
269 QSGTexture *t = m_rhiAtlasManager->create(image, alpha);
275 QSGPlainTexture *texture =
new QSGPlainTexture;
276 texture->setImage(image);
277 if (texture->hasAlphaChannel() && !alpha)
278 texture->setHasAlphaChannel(
false);
303void QSGDefaultRenderContext::preprocess()
305 for (
auto it = m_glyphCaches.begin(); it != m_glyphCaches.end(); ++it) {
306 it.value()->processPendingGlyphs();
307 it.value()->update();
310 for (
auto it = m_staleGlyphCaches.begin(); it != m_staleGlyphCaches.end(); ++it) {
311 (*it)->processPendingGlyphs();
316QSGCurveGlyphAtlas *QSGDefaultRenderContext::curveGlyphAtlas(
const QRawFont &font)
318 FontKey key = FontKey(font, 0);
319 QSGCurveGlyphAtlas *atlas = m_curveGlyphAtlases.value(key,
nullptr);
320 if (atlas ==
nullptr) {
321 atlas =
new QSGCurveGlyphAtlas(font);
322 m_curveGlyphAtlases.insert(key, atlas);
328QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(
const QRawFont &font,
int renderTypeQuality)
330 FontKey key(font, renderTypeQuality);
331 QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
332 if (!cache && font.isValid()) {
333 cache =
new QSGRhiDistanceFieldGlyphCache(
this, font, renderTypeQuality);
334 m_glyphCaches.insert(key, cache);
336 qCDebug(lcGlyphCaches()) <<
"Creating new glyph cache:"
338 <<
"fontEngine:" << fontEngineOfRawFont(cache->referenceFont())
339 << cache->referenceFont().familyName()
340 << cache->referenceFont().styleName()
344 << key.faceId.filename;
346 qCDebug(lcGlyphCaches()) <<
"Found existing glyph cache:"
348 <<
"fontEngine:" << fontEngineOfRawFont(cache->referenceFont())
349 << cache->referenceFont().familyName()
350 << cache->referenceFont().styleName()
354 << key.faceId.filename;
379void QSGDefaultRenderContext::resetGlyphCacheResources()
381 if (m_glyphCacheResourceUpdates) {
382 m_glyphCacheResourceUpdates->release();
383 m_glyphCacheResourceUpdates =
nullptr;
386 for (QRhiTexture *t : std::as_const(m_pendingGlyphCacheTextures))
389 m_pendingGlyphCacheTextures.clear();
401QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::getDepthStencilBuffer(
const QSize &size,
int sampleCount)
403 const auto key = std::pair(size, sampleCount);
404 auto it = m_depthStencilBuffers.constFind(key);
405 if (it != m_depthStencilBuffers.cend()) {
407 return it.value().toStrongRef();
410 QRhiRenderBuffer *ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, sampleCount);
412 qWarning(
"Failed to build depth-stencil buffer for layer");
416 QSharedPointer<QSGDepthStencilBuffer> buf(
new QSGDepthStencilBuffer(ds));
417 addDepthStencilBuffer(buf);
421void QSGDefaultRenderContext::addDepthStencilBuffer(
const QSharedPointer<QSGDepthStencilBuffer> &ds)
424 const auto key = std::pair(ds->ds->pixelSize(), ds->ds->sampleCount());
426 m_depthStencilBuffers.insert(key, ds.toWeakRef());
static QFontEngine * fontEngineOfRawFont(const QRawFont &font)