31QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context)
32 : QSGRenderContext(context)
35 , m_rhiAtlasManager(
nullptr)
36 , m_currentFrameCommandBuffer(
nullptr)
37 , m_currentFrameRenderPass(
nullptr)
38 , m_useDepthBufferFor2D(
true)
39 , m_glyphCacheResourceUpdates(
nullptr)
47void QSGDefaultRenderContext::initialize(
const QSGRenderContext::InitParams *params)
52 const InitParams *initParams =
static_cast<
const InitParams *>(params);
53 if (initParams->sType != INIT_PARAMS_MAGIC)
54 qFatal(
"QSGDefaultRenderContext: Invalid parameters passed to initialize()");
56 m_initParams = *initParams;
58 m_rhi = m_initParams.rhi;
59 m_maxTextureSize = m_rhi->resourceLimit(QRhi::TextureSizeMax);
60 if (!m_rhiAtlasManager)
61 m_rhiAtlasManager =
new QSGRhiAtlasTexture::Manager(
this, m_initParams.initialSurfacePixelSize, m_initParams.maybeSurface);
63 m_glyphCacheResourceUpdates =
nullptr;
65 m_sg->renderContextInitialized(
this);
79void QSGDefaultRenderContext::flushGlyphCaches()
81 auto it = m_staleGlyphCaches.begin();
82 while (it != m_staleGlyphCaches.end()) {
83 if (!(*it)->isActive()) {
84 qCDebug(lcGlyphCaches()) <<
"Deleting stale glyph cache:"
86 <<
"fontEngine:" << fontEngineOfRawFont((*it)->referenceFont())
87 << (*it)->referenceFont().familyName();
89 it = m_staleGlyphCaches.erase(it);
96 auto it = m_fontEnginesToClean.begin();
97 while (it != m_fontEnginesToClean.end()) {
98 if (it.value() == 0) {
99 it.key()->clearGlyphCache(
this);
100 if (!it.key()->ref.deref())
102 it = m_fontEnginesToClean.erase(it);
110void QSGDefaultRenderContext::invalidateGlyphCaches()
113 auto it = m_glyphCaches.begin();
114 while (it != m_glyphCaches.end()) {
115 if (!(*it)->isActive()) {
116 qCDebug(lcGlyphCaches()) <<
"Direct delete glyph cache:"
118 <<
"fontEngine:" << fontEngineOfRawFont(it.value()->referenceFont())
119 << it.value()->referenceFont().familyName()
120 << it.value()->referenceFont().styleName()
122 << it.key().familyName
123 << it.key().styleName
124 << it.key().faceId.filename;
127 qCDebug(lcGlyphCaches()) <<
"Stale glyph cache:"
129 <<
"fontEngine:" << fontEngineOfRawFont(it.value()->referenceFont())
130 << it.value()->referenceFont().familyName()
131 << it.value()->referenceFont().styleName()
133 << it.key().familyName
134 << it.key().styleName
135 << it.key().faceId.filename;
137 m_staleGlyphCaches.append(*it);
140 it = m_glyphCaches.erase(it);
144 qDeleteAll(m_curveGlyphAtlases);
145 m_curveGlyphAtlases.clear();
148void QSGDefaultRenderContext::invalidate()
153 qDeleteAll(m_texturesToDelete);
154 m_texturesToDelete.clear();
156 qDeleteAll(m_textures);
159 for (
auto it = m_depthStencilBuffers.cbegin(), end = m_depthStencilBuffers.cend(); it != end; ++it) {
160 QSharedPointer<QSGDepthStencilBuffer> buf = it.value().toStrongRef();
165 m_depthStencilBuffers.clear();
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 if (m_rhiAtlasManager) {
184 m_rhiAtlasManager->invalidate();
185 m_rhiAtlasManager->deleteLater();
186 m_rhiAtlasManager =
nullptr;
194 for (
auto it = m_fontEnginesToClean.constBegin(); it != m_fontEnginesToClean.constEnd(); ++it) {
195 it.key()->clearGlyphCache(
this);
196 if (!it.key()->ref.deref())
199 m_fontEnginesToClean.clear();
201 qDeleteAll(m_curveGlyphAtlases);
202 m_curveGlyphAtlases.clear();
204 qCDebug(lcGlyphCaches()) <<
"Deleting" << m_glyphCaches.size() <<
"live glyph caches";
206 qDeleteAll(m_glyphCaches);
207 m_glyphCaches.clear();
209 qCDebug(lcGlyphCaches()) <<
"Deleting" << m_staleGlyphCaches.size() <<
"stale glyph caches";
211 qDeleteAll(m_staleGlyphCaches);
212 m_staleGlyphCaches.clear();
214 resetGlyphCacheResources();
219 m_sg->renderContextInvalidated(
this);
224void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio,
225 QRhiCommandBuffer *cb,
226 const QQuickGraphicsConfiguration &config)
228 m_currentDevicePixelRatio = devicePixelRatio;
229 m_useDepthBufferFor2D = config.isDepthBufferEnabledFor2D();
234 m_currentFrameCommandBuffer = cb;
237void QSGDefaultRenderContext::beginNextFrame(QSGRenderer *renderer,
const QSGRenderTarget &renderTarget,
238 RenderPassCallback mainPassRecordingStart,
239 RenderPassCallback mainPassRecordingEnd,
240 void *callbackUserData)
242 renderer->setRenderTarget(renderTarget);
243 renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
245 m_currentFrameCommandBuffer = renderTarget.cb;
246 m_currentFrameRenderPass = renderTarget.rpDesc;
254void QSGDefaultRenderContext::endNextFrame(QSGRenderer *renderer)
260 if (m_glyphCacheResourceUpdates) {
261 if (m_currentFrameCommandBuffer)
262 m_currentFrameCommandBuffer->resourceUpdate(m_glyphCacheResourceUpdates);
264 m_glyphCacheResourceUpdates->release();
265 m_glyphCacheResourceUpdates =
nullptr;
268 m_currentFrameCommandBuffer =
nullptr;
269 m_currentFrameRenderPass =
nullptr;
272QSGTexture *QSGDefaultRenderContext::createTexture(
const QImage &image, uint flags)
const
274 bool atlas = flags & CreateTexture_Atlas;
275 bool mipmap = flags & CreateTexture_Mipmap;
276 bool alpha = flags & CreateTexture_Alpha;
281 if (!mipmap && atlas && QThread::currentThread() == m_rhi->thread()) {
282 QSGTexture *t = m_rhiAtlasManager->create(image, alpha);
288 QSGPlainTexture *texture =
new QSGPlainTexture;
289 texture->setImage(image);
290 if (texture->hasAlphaChannel() && !alpha)
291 texture->setHasAlphaChannel(
false);
316void QSGDefaultRenderContext::preprocess()
318 for (
auto it = m_glyphCaches.begin(); it != m_glyphCaches.end(); ++it) {
319 it.value()->processPendingGlyphs();
320 it.value()->update();
323 for (
auto it = m_staleGlyphCaches.begin(); it != m_staleGlyphCaches.end(); ++it) {
324 (*it)->processPendingGlyphs();
329QSGCurveGlyphAtlas *QSGDefaultRenderContext::curveGlyphAtlas(
const QRawFont &font)
331 FontKey key = FontKey(font, 0);
332 QSGCurveGlyphAtlas *atlas = m_curveGlyphAtlases.value(key,
nullptr);
333 if (atlas ==
nullptr) {
334 atlas =
new QSGCurveGlyphAtlas(font);
335 m_curveGlyphAtlases.insert(key, atlas);
341QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(
const QRawFont &font,
int renderTypeQuality)
343 FontKey key(font, renderTypeQuality);
344 QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
345 if (!cache && font.isValid()) {
346 cache =
new QSGRhiDistanceFieldGlyphCache(
this, font, renderTypeQuality);
347 m_glyphCaches.insert(key, cache);
349 qCDebug(lcGlyphCaches()) <<
"Creating new glyph cache:"
351 <<
"fontEngine:" << fontEngineOfRawFont(cache->referenceFont())
352 << cache->referenceFont().familyName()
353 << cache->referenceFont().styleName()
357 << key.faceId.filename;
359 qCDebug(lcGlyphCaches()) <<
"Found existing glyph cache:"
361 <<
"fontEngine:" << fontEngineOfRawFont(cache->referenceFont())
362 << cache->referenceFont().familyName()
363 << cache->referenceFont().styleName()
367 << key.faceId.filename;
392void QSGDefaultRenderContext::resetGlyphCacheResources()
394 if (m_glyphCacheResourceUpdates) {
395 m_glyphCacheResourceUpdates->release();
396 m_glyphCacheResourceUpdates =
nullptr;
399 for (QRhiTexture *t : std::as_const(m_pendingGlyphCacheTextures))
402 m_pendingGlyphCacheTextures.clear();
414QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::getDepthStencilBuffer(
const QSize &size,
int sampleCount)
416 const auto key = std::pair(size, sampleCount);
417 auto it = m_depthStencilBuffers.constFind(key);
418 if (it != m_depthStencilBuffers.cend()) {
420 return it.value().toStrongRef();
423 QRhiRenderBuffer *ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, sampleCount,
424 QSGRhiSupport::depthStencilBufferFlags());
426 qWarning(
"Failed to build depth-stencil buffer for layer");
430 QSharedPointer<QSGDepthStencilBuffer> buf(
new QSGDepthStencilBuffer(ds));
431 addDepthStencilBuffer(buf);
435void QSGDefaultRenderContext::addDepthStencilBuffer(
const QSharedPointer<QSGDepthStencilBuffer> &ds)
438 const auto key = std::pair(ds->ds->pixelSize(), ds->ds->sampleCount());
440 m_depthStencilBuffers.insert(key, ds.toWeakRef());
static QFontEngine * fontEngineOfRawFont(const QRawFont &font)