• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ossia / score / 38475390298

13 Oct 2026 09:56PM UTC coverage: 48.898% (+0.8%) from 48.076%
38475390298

push

github

jcelerier
gfx: commit the initial batch before a frame can release what it names

RenderList::renderImpl carried m_initialBatch, holding every renderer's
init()-time uploads, into the frame's first pass. When an inlet spec changed
before that first frame, the surgical render-target update released and
re-initialised the renderer first, and releaseState() deletes its material
UBO outright, so the batch then named a freed QRhiBuffer. On OpenGL,
enqueueResourceUpdates copies a uniform-buffer update into the buffer's
CPU-side store: a write into freed memory, or, after destroy() cleared it,
into QByteArray's static empty storage. test_gfx_input_sampler_filter
(raw raster, OpenGL) crashed there, or read back black, depending on what
reused the allocation.

The batch is now committed to the command buffer as soon as the frame takes
it, as onEdgeRemoved() and Graph::relinkGraph() already flush it before
releasing renderer state.

The new case in test_gfx_outside_frame_release_buffer re-inits a probe
renderer on the first frame and checks, from its releaseState(), whether the
batch its upload went into still holds it: deterministic, on every backend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JeL19ofVgPe9u9q7J1V9ex

2 of 2 new or added lines in 1 file covered. (100.0%)

6331 existing lines in 89 files now uncovered.

160459 of 328149 relevant lines covered (48.9%)

146726.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/src/plugins/score-plugin-js/JS/ThreadLocalQmlEngine.cpp
1
#include "ThreadLocalQmlEngine.hpp"
2

3
#include <QDir>
4
#include <QQmlAbstractUrlInterceptor>
5
#include <QQmlEngine>
6

7
namespace JS
8
{
9
namespace
10
{
11
class DriveLetterUrlFix final : public QQmlAbstractUrlInterceptor
12
{
13
public:
14
  QUrl intercept(const QUrl& url, DataType) override
4,167 ✔
15
  {
16
    const QString scheme = url.scheme();
4,167 ✔
17
    if(scheme.size() != 1 || !scheme[0].isLetter() || !url.host().isEmpty())
4,167 ✔
18
      return url;
4,167 ✔
19

20
    // QUrl lower-cases the scheme; drive letters are case-insensitive.
21
    // A '?' or '#' in the file name was split off as query / fragment:
22
    // put them back, they are part of the path.
UNCOV
23
    QString path = scheme.toUpper() + QLatin1Char(':') + url.path(QUrl::FullyDecoded);
×
UNCOV
24
    if(url.hasQuery())
×
UNCOV
25
      path += QLatin1Char('?') + url.query(QUrl::FullyDecoded);
×
UNCOV
26
    if(url.hasFragment())
×
UNCOV
27
      path += QLatin1Char('#') + url.fragment(QUrl::FullyDecoded);
×
UNCOV
28
    return QUrl::fromLocalFile(QDir::fromNativeSeparators(path));
×
29
  }
4,167 ✔
30
};
31

32
struct DriveLetterUrlFixHolder : QObject
3,525 ✔
33
{
34
  DriveLetterUrlFix interceptor;
35
  QQmlEngine* engine{};
3,525 ✔
36
  ~DriveLetterUrlFixHolder() override
7,048 ✔
37
  {
7,048 ✔
38
    if(engine)
3,524 ✔
39
      engine->removeUrlInterceptor(&interceptor);
3,524 ✔
40
  }
7,048 ✔
41
};
42
}
43

44
void installLocalPathUrlFix(QQmlEngine& engine)
3,525 ✔
45
{
46
  static constexpr auto marker = "score_qml_drive_letter_url_fix";
47
  if(engine.property(marker).toBool())
3,525 ✔
UNCOV
48
    return;
×
49

50
  auto* holder = new DriveLetterUrlFixHolder;
3,525 ✔
51
  holder->engine = &engine;
3,525 ✔
52
  holder->setParent(&engine);
3,525 ✔
53
  engine.addUrlInterceptor(&holder->interceptor);
3,525 ✔
54
  engine.setProperty(marker, true);
3,525 ✔
55
}
3,525 ✔
56

57
std::shared_ptr<QQmlEngine> acquireThreadLocalEngine(const std::function<void(QQmlEngine&)>& onConstruction)
24 ✔
58
{
59
  thread_local struct QQmlEngineWatcher {
24 ✔
60
    ~QQmlEngineWatcher() {
9 ✔
61
      engine.reset();
9 ✔
62
    }
9 ✔
63
    std::weak_ptr<QQmlEngine> engine{};
64
  } g_qqmlWatcher;
65

66
  auto engine = g_qqmlWatcher.engine.lock();
24 ✔
67
  if(!engine) {
24 ✔
68
    engine = std::make_shared<QQmlEngine>();
24 ✔
69
    g_qqmlWatcher.engine = engine;
24 ✔
70
    installLocalPathUrlFix(*engine);
24 ✔
71
    if(onConstruction)
24 ✔
72
      onConstruction(*engine);
24 ✔
73
  }
24 ✔
74

75
  return engine;
24 ✔
76
}
24 ✔
77
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc