30QSGDefaultRenderContext::QSGDefaultRenderContext(QSGContext *context)
31 : QSGRenderContext(context)
34 , m_rhiAtlasManager(
nullptr)
35 , m_currentFrameCommandBuffer(
nullptr)
36 , m_currentFrameRenderPass(
nullptr)
37 , m_useDepthBufferFor2D(
true)
38 , m_glyphCacheResourceUpdates(
nullptr)
46void QSGDefaultRenderContext::initialize(
const QSGRenderContext::InitParams *params)
51 const InitParams *initParams =
static_cast<
const InitParams *>(params);
52 if (initParams->sType != INIT_PARAMS_MAGIC)
53 qFatal(
"QSGDefaultRenderContext: Invalid parameters passed to initialize()");
55 m_initParams = *initParams;
57 m_rhi = m_initParams.rhi;
58 m_maxTextureSize = m_rhi->resourceLimit(QRhi::TextureSizeMax);
59 if (!m_rhiAtlasManager)
60 m_rhiAtlasManager =
new QSGRhiAtlasTexture::Manager(
this, m_initParams.initialSurfacePixelSize, m_initParams.maybeSurface);
62 m_glyphCacheResourceUpdates =
nullptr;
64 m_sg->renderContextInitialized(
this);
78void QSGDefaultRenderContext::flushGlyphCaches()
80 auto it = m_staleGlyphCaches.begin();
81 while (it != m_staleGlyphCaches.end()) {
82 if (!(*it)->isActive()) {
83 qCDebug(lcGlyphCaches()) <<
"Deleting stale glyph cache:"
85 <<
"fontEngine:" << fontEngineOfRawFont((*it)->referenceFont())
86 << (*it)->referenceFont().familyName();
88 it = m_staleGlyphCaches.erase(it);
95 auto it = m_fontEnginesToClean.begin();
96 while (it != m_fontEnginesToClean.end()) {
97 if (it.value() == 0) {
98 it.key()->clearGlyphCache(
this);
99 if (!it.key()->ref.deref())
101 it = m_fontEnginesToClean.erase(it);
109void QSGDefaultRenderContext::invalidateGlyphCaches()
112 auto it = m_glyphCaches.begin();
113 while (it != m_glyphCaches.end()) {
114 if (!(*it)->isActive()) {
115 qCDebug(lcGlyphCaches()) <<
"Direct delete glyph cache:"
117 <<
"fontEngine:" << fontEngineOfRawFont(it.value()->referenceFont())
118 << it.value()->referenceFont().familyName()
119 << it.value()->referenceFont().styleName()
121 << it.key().familyName
122 << it.key().styleName
123 << it.key().faceId.filename;
126 qCDebug(lcGlyphCaches()) <<
"Stale glyph cache:"
128 <<
"fontEngine:" << fontEngineOfRawFont(it.value()->referenceFont())
129 << it.value()->referenceFont().familyName()
130 << it.value()->referenceFont().styleName()
132 << it.key().familyName
133 << it.key().styleName
134 << it.key().faceId.filename;
136 m_staleGlyphCaches.append(*it);
139 it = m_glyphCaches.erase(it);
143 qDeleteAll(m_curveGlyphAtlases);
144 m_curveGlyphAtlases.clear();
147void QSGDefaultRenderContext::invalidate()
152 qDeleteAll(m_texturesToDelete);
153 m_texturesToDelete.clear();
155 qDeleteAll(m_textures);
158 for (
auto it = m_depthStencilBuffers.cbegin(), end = m_depthStencilBuffers.cend(); it != end; ++it) {
159 QSharedPointer<QSGDepthStencilBuffer> buf = it.value().toStrongRef();
164 m_depthStencilBuffers.clear();
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 if (m_rhiAtlasManager) {
183 m_rhiAtlasManager->invalidate();
184 m_rhiAtlasManager->deleteLater();
185 m_rhiAtlasManager =
nullptr;
193 for (
auto it = m_fontEnginesToClean.constBegin(); it != m_fontEnginesToClean.constEnd(); ++it) {
194 it.key()->clearGlyphCache(
this);
195 if (!it.key()->ref.deref())
198 m_fontEnginesToClean.clear();
200 qDeleteAll(m_curveGlyphAtlases);
201 m_curveGlyphAtlases.clear();
203 qCDebug(lcGlyphCaches()) <<
"Deleting" << m_glyphCaches.size() <<
"live glyph caches";
205 qDeleteAll(m_glyphCaches);
206 m_glyphCaches.clear();
208 qCDebug(lcGlyphCaches()) <<
"Deleting" << m_staleGlyphCaches.size() <<
"stale glyph caches";
210 qDeleteAll(m_staleGlyphCaches);
211 m_staleGlyphCaches.clear();
213 resetGlyphCacheResources();
218 m_sg->renderContextInvalidated(
this);
223void QSGDefaultRenderContext::prepareSync(qreal devicePixelRatio,
224 QRhiCommandBuffer *cb,
225 const QQuickGraphicsConfiguration &config)
227 m_currentDevicePixelRatio = devicePixelRatio;
228 m_useDepthBufferFor2D = config.isDepthBufferEnabledFor2D();
233 m_currentFrameCommandBuffer = cb;
236void QSGDefaultRenderContext::beginNextFrame(QSGRenderer *renderer,
const QSGRenderTarget &renderTarget,
237 RenderPassCallback mainPassRecordingStart,
238 RenderPassCallback mainPassRecordingEnd,
239 void *callbackUserData)
241 renderer->setRenderTarget(renderTarget);
242 renderer->setRenderPassRecordingCallbacks(mainPassRecordingStart, mainPassRecordingEnd, callbackUserData);
244 m_currentFrameCommandBuffer = renderTarget.cb;
245 m_currentFrameRenderPass = renderTarget.rpDesc;
253void QSGDefaultRenderContext::endNextFrame(QSGRenderer *renderer)
259 if (m_glyphCacheResourceUpdates) {
260 if (m_currentFrameCommandBuffer)
261 m_currentFrameCommandBuffer->resourceUpdate(m_glyphCacheResourceUpdates);
263 m_glyphCacheResourceUpdates->release();
264 m_glyphCacheResourceUpdates =
nullptr;
267 m_currentFrameCommandBuffer =
nullptr;
268 m_currentFrameRenderPass =
nullptr;
271QSGTexture *QSGDefaultRenderContext::createTexture(
const QImage &image, uint flags)
const
273 bool atlas = flags & CreateTexture_Atlas;
274 bool mipmap = flags & CreateTexture_Mipmap;
275 bool alpha = flags & CreateTexture_Alpha;
280 if (!mipmap && atlas && QThread::currentThread() == m_rhi->thread()) {
281 QSGTexture *t = m_rhiAtlasManager->create(image, alpha);
287 QSGPlainTexture *texture =
new QSGPlainTexture;
288 texture->setImage(image);
289 if (texture->hasAlphaChannel() && !alpha)
290 texture->setHasAlphaChannel(
false);
315void QSGDefaultRenderContext::preprocess()
317 for (
auto it = m_glyphCaches.begin(); it != m_glyphCaches.end(); ++it) {
318 it.value()->processPendingGlyphs();
319 it.value()->update();
322 for (
auto it = m_staleGlyphCaches.begin(); it != m_staleGlyphCaches.end(); ++it) {
323 (*it)->processPendingGlyphs();
328QSGCurveGlyphAtlas *QSGDefaultRenderContext::curveGlyphAtlas(
const QRawFont &font)
330 FontKey key = FontKey(font, 0);
331 QSGCurveGlyphAtlas *atlas = m_curveGlyphAtlases.value(key,
nullptr);
332 if (atlas ==
nullptr) {
333 atlas =
new QSGCurveGlyphAtlas(font);
334 m_curveGlyphAtlases.insert(key, atlas);
340QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(
const QRawFont &font,
int renderTypeQuality)
342 FontKey key(font, renderTypeQuality);
343 QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
344 if (!cache && font.isValid()) {
345 cache =
new QSGRhiDistanceFieldGlyphCache(
this, font, renderTypeQuality);
346 m_glyphCaches.insert(key, cache);
348 qCDebug(lcGlyphCaches()) <<
"Creating new glyph cache:"
350 <<
"fontEngine:" << fontEngineOfRawFont(cache->referenceFont())
351 << cache->referenceFont().familyName()
352 << cache->referenceFont().styleName()
356 << key.faceId.filename;
358 qCDebug(lcGlyphCaches()) <<
"Found existing glyph cache:"
360 <<
"fontEngine:" << fontEngineOfRawFont(cache->referenceFont())
361 << cache->referenceFont().familyName()
362 << cache->referenceFont().styleName()
366 << key.faceId.filename;
391void QSGDefaultRenderContext::resetGlyphCacheResources()
393 if (m_glyphCacheResourceUpdates) {
394 m_glyphCacheResourceUpdates->release();
395 m_glyphCacheResourceUpdates =
nullptr;
398 for (QRhiTexture *t : std::as_const(m_pendingGlyphCacheTextures))
401 m_pendingGlyphCacheTextures.clear();
413QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::getDepthStencilBuffer(
const QSize &size,
int sampleCount)
415 const auto key = std::pair(size, sampleCount);
416 auto it = m_depthStencilBuffers.constFind(key);
417 if (it != m_depthStencilBuffers.cend()) {
419 return it.value().toStrongRef();
422 QRhiRenderBuffer *ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, sampleCount);
424 qWarning(
"Failed to build depth-stencil buffer for layer");
428 QSharedPointer<QSGDepthStencilBuffer> buf(
new QSGDepthStencilBuffer(ds));
429 addDepthStencilBuffer(buf);
433void QSGDefaultRenderContext::addDepthStencilBuffer(
const QSharedPointer<QSGDepthStencilBuffer> &ds)
436 const auto key = std::pair(ds->ds->pixelSize(), ds->ds->sampleCount());
438 m_depthStencilBuffers.insert(key, ds.toWeakRef());
static QFontEngine * fontEngineOfRawFont(const QRawFont &font)