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

ossia / score / 35952114601

24 Sep 2026 03:35AM UTC coverage: 41.187% (-0.3%) from 41.488%
35952114601

push

github

jcelerier
gfx: keep the driver's defects in one place, per render list

An empty render pass below the sample count of an earlier rasterising one
in the same command buffer loses the device on NVIDIA + Vulkan. Qt Quick's
layers have their own sample count and stay empty until their scene has
content, so a Quick node downstream of a shader node records exactly that
pair. Give each render list a Quirks it can ask, and split the command
buffer before handing it to Quick. SCORE_GFX_NO_QUIRKS=1 turns the
work-arounds off.

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

9 of 14 new or added lines in 3 files covered. (64.29%)

1113 existing lines in 9 files now uncovered.

122373 of 297112 relevant lines covered (41.19%)

113120.13 hits per line

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

74.06
/src/plugins/score-lib-process/Process/Process.cpp
1
// This is an open source non-commercial project. Dear PVS-Studio, please check
2
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3
#include "Process.hpp"
4

5
#include <Process/Dataflow/PortVisibility.hpp>
6

7
#include <Process/Dataflow/Port.hpp>
8
#include <Process/ExpandMode.hpp>
9
#include <Process/PresetHelpers.hpp>
10
#include <Process/TimeValue.hpp>
11

12
#include <LocalTree/ProcessComponent.hpp>
13

14
#include <score/model/ComponentUtils.hpp>
15
#include <score/model/EntitySerialization.hpp>
16
#include <score/model/IdentifiedObject.hpp>
17
#include <score/model/Identifier.hpp>
18
#include <score/model/ModelMetadata.hpp>
19
#include <score/tools/Bind.hpp>
20
#include <score/widgets/SetIcons.hpp>
21

22
#include <ossia/detail/algorithms.hpp>
23
#include <ossia/detail/disable_fpe.hpp>
24
#include <ossia/network/base/device.hpp>
25
#include <ossia/network/base/node.hpp>
26

27
#include <QObject>
28

29
#include <wobjectimpl.h>
30

31
W_OBJECT_IMPL(Process::ProcessModel)
32,703✔
32

33
#if !defined(SCORE_ALL_UNITY)
34
template class IdentifiedObject<Process::ProcessModel>;
35
template class score::SerializableInterface<Process::ProcessModelFactory>;
36
#endif
37
namespace Process
38
{
39

40
const QIcon& getCategoryIcon(const QString& category) noexcept
71,424✔
41
{
42
  static const ossia::flat_map<QString, QIcon> categoryIcon{
74,224✔
43
      {"AI", makeIcon(QStringLiteral(":/icons/ai.png"))},
175✔
44
      {"Analysis", makeIcon(QStringLiteral(":/icons/analysis.png"))},
175✔
45
      {"Audio", makeIcon(QStringLiteral(":/icons/audio.png"))},
175✔
46
      {"Plugins", makeIcon(QStringLiteral(":/icons/filter.png"))},
175✔
47
      {"Midi", makeIcon(QStringLiteral(":/icons/midi.png"))},
175✔
48
      {"Control", makeIcon(QStringLiteral(":/icons/controls.png"))},
175✔
49
      {"Visuals", makeIcon(QStringLiteral(":/icons/gfx.png"))},
175✔
50
      {"Automations", makeIcon(QStringLiteral(":/icons/automation.png"))},
175✔
51
      {"Impro", makeIcon(QStringLiteral(":/icons/controls.png"))},
175✔
52
      {"Script", makeIcon(QStringLiteral(":/icons/script.png"))},
175✔
53
      {"Structure", makeIcon(QStringLiteral(":/icons/structure.png"))},
175✔
54
      {"Network", makeIcon(QStringLiteral(":/icons/sync.png"))},
175✔
55
      {"Monitoring", makeIcon(QStringLiteral(":/icons/ui.png"))},
175✔
56
      {"Spatial", makeIcon(QStringLiteral(":/icons/spatial.png"))},
175✔
57
      // Kept until the remaining processes are renamed to "Spatial": the icon
58
      // is looked up on the first path segment only, so both spellings need a
59
      // row or one of them renders without an icon.
60
      {"Spatialization", makeIcon(QStringLiteral(":/icons/spatial.png"))},
175✔
61
      {"Timing", makeIcon(QStringLiteral(":/icons/timing.png"))},
175✔
62
  };
63
  static const QIcon invalid;
71,424✔
64
  if(auto it = categoryIcon.find(category); it != categoryIcon.end())
71,424✔
65
  {
66
    return it->second;
71,424✔
67
  }
68
  if(auto slash_it = category.indexOf("/"); slash_it != -1)
×
69
  {
70
    if(auto it = categoryIcon.find(category.mid(0, slash_it)); it != categoryIcon.end())
×
71
    {
72
      return it->second;
×
73
    }
74
  }
×
75
  return invalid;
×
76
}
71,424✔
77
ProcessModel::ProcessModel(
3,074✔
78
    TimeVal duration, const Id<ProcessModel>& id, const QString& name, QObject* parent)
79
    : Entity{id, name, parent}
1,537✔
80
    , m_duration{std::move(duration)}
81
    , m_slotHeight{300}
82
    , m_loopDuration{m_duration}
83
    , m_size{200, 100}
84
    , m_loops{false}
85
{
3,074✔
86
  ossia::disable_fpe();
1,537✔
87
  con(metadata(), &score::ModelMetadata::NameChanged, this,
3,074✔
88
      [this] { prettyNameChanged(); });
3,181✔
89
  connect(this, &Process::ProcessModel::resetExecution, this, [this] {
2,312✔
90
    for(auto& p : this->m_inlets)
2,646✔
91
      p->executionReset();
1,871✔
92
    for(auto& p : this->m_outlets)
1,635✔
93
      p->executionReset();
860✔
94
  });
775✔
95
  // metadata().setInstanceName(*this);
96
}
×
97

98
ProcessModel::~ProcessModel()
2,415✔
99
{
2,415✔
100
  identified_object_destroying(this);
2,415✔
101
}
2,415✔
102

103
QString ProcessModel::effect() const noexcept
318✔
104
{
105
  return {};
318✔
106
}
107

108
void ProcessModel::setDurationAndScale(const TimeVal& newDuration) noexcept
×
109
{
110
  setDuration(newDuration);
×
111
}
×
112

113
void ProcessModel::setDurationAndGrow(const TimeVal& newDuration) noexcept
×
114
{
115
  setDuration(newDuration);
×
116
}
×
117

118
void ProcessModel::setDurationAndShrink(const TimeVal& newDuration) noexcept
×
119
{
120
  setDuration(newDuration);
×
121
}
×
122

123
ProcessModel::ProcessModel(DataStream::Deserializer& vis, QObject* parent)
846✔
124
    : Entity(vis, parent)
423✔
125
{
846✔
126
  ossia::disable_fpe();
423✔
127
  vis.writeTo(*this);
423✔
128
  con(metadata(), &score::ModelMetadata::NameChanged, this,
846✔
129
      [this] { prettyNameChanged(); });
423✔
130
}
×
131

132
ProcessModel::ProcessModel(JSONObject::Deserializer& vis, QObject* parent)
910✔
133
    : Entity(vis, parent)
455✔
134
{
910✔
135
  ossia::disable_fpe();
455✔
136
  vis.writeTo(*this);
455✔
137
  con(metadata(), &score::ModelMetadata::NameChanged, this,
910✔
138
      [this] { prettyNameChanged(); });
455✔
139
}
×
140

141
QString ProcessModel::prettyName() const noexcept
2,228✔
142
{
143
  return metadata().getName();
2,228✔
144
}
145

146
void ProcessModel::setParentDuration(ExpandMode mode, const TimeVal& t) noexcept
1✔
147
{
148
  switch(mode)
1✔
149
  {
150
    case ExpandMode::Scale:
151
      setDurationAndScale(t);
×
152
      break;
×
153
    case ExpandMode::GrowShrink: {
154
      if(duration() < t)
1✔
155
        setDurationAndGrow(t);
×
156
      else
157
        setDurationAndShrink(t);
1✔
158
      break;
1✔
159
    }
160
    case ExpandMode::ForceGrow: {
161
      if(duration() < t)
×
162
        setDurationAndGrow(t);
×
163
      break;
×
164
    }
165
    case ExpandMode::CannotExpand:
×
166
    default:
167
      break;
×
168
  }
169
}
1✔
170

171
TimeVal ProcessModel::contentDuration() const noexcept
×
172
{
173
  return TimeVal::zero();
×
174
}
175

176
void ProcessModel::setDuration(const TimeVal& other) noexcept
2✔
177
{
178
  m_duration = other;
2✔
179
  durationChanged(m_duration);
2✔
180
}
2✔
181

182
const TimeVal& ProcessModel::duration() const noexcept
2,349✔
183
{
184
  return m_duration;
2,349✔
185
}
186

187
ProcessStateDataInterface* ProcessModel::startStateData() const noexcept
981✔
188
{
189
  return nullptr;
981✔
190
}
191

192
ProcessStateDataInterface* ProcessModel::endStateData() const noexcept
981✔
193
{
194
  return nullptr;
981✔
195
}
196

197
Selection ProcessModel::selectableChildren() const noexcept
×
198
{
199
  return {};
×
200
}
201

202
Selection ProcessModel::selectedChildren() const noexcept
×
203
{
204
  return {};
×
205
}
206

207
void ProcessModel::setSelection(const Selection& s) const noexcept
1✔
208
{
209
  // OPTIMIZEME
210
  auto cld = this->findChildren<Selectable*>();
1✔
211
  for(Selectable* child : cld)
10✔
212
  {
213
    child->set(s.contains(child->parent()));
9✔
214
  }
215
}
1✔
216

217
Process::Inlet* ProcessModel::inlet(const Id<Process::Port>& p) const noexcept
5✔
218
{
219
  for(auto e : m_inlets)
16✔
220
    if(e->id() == p)
15✔
221
      return e;
4✔
222
  return nullptr;
1✔
223
}
5✔
224

225
Process::Outlet* ProcessModel::outlet(const Id<Process::Port>& p) const noexcept
1✔
226
{
227
  for(auto e : m_outlets)
1✔
228
    if(e->id() == p)
1✔
229
      return e;
1✔
230
  return nullptr;
×
231
}
1✔
232

233
void ProcessModel::loadPreset(const Preset& preset)
6✔
234
{
235
  const rapidjson::Document doc = readJson(preset.data);
6✔
236
  loadFixedControls(doc.GetArray(), *this);
6✔
237
}
6✔
238

239
Preset ProcessModel::savePreset() const noexcept
8✔
240
{
241
  Preset p;
8✔
242
  p.name = this->metadata().getName();
8✔
243
  p.key.key = this->concreteKey();
8✔
244

245
  JSONReader r;
8✔
246
  saveFixedControls(r, *this);
8✔
247
  p.data = r.toByteArray();
8✔
248
  return p;
8✔
249
}
8✔
250

251
std::vector<Preset> ProcessModel::builtinPresets() const noexcept
×
252
{
253
  return {};
×
254
}
255

256
bool ProcessModel::presetMatches(const Preset& preset) const noexcept
×
257
{
258
  return preset.key.key == concreteKey() && preset.key.effect == effect();
×
259
}
260

UNCOV
261
void ProcessModel::ancestorStartDateChanged() { }
×
262

263
void ProcessModel::ancestorTempoChanged() { }
×
264

265
void ProcessModel::forEachControl(
×
266
    smallfun::function<void(ControlInlet&, const ossia::value&)> f) const
267
{
268
  for(const auto& inlet : m_inlets)
×
269
  {
270
    if(auto ctrl = qobject_cast<Process::ControlInlet*>(inlet))
×
271
    {
272
      f(*ctrl, ctrl->value());
×
UNCOV
273
    }
×
274
  }
UNCOV
275
}
×
276

UNCOV
277
void ProcessModel::setCreatingControls(bool ok) { }
×
278

UNCOV
279
bool ProcessModel::creatingControls() const noexcept
×
280
{
UNCOV
281
  return this->flags() & ProcessFlags::CreateControls;
×
282
}
283

284
void ProcessModel::setLoops(bool b)
24✔
285
{
286
  if(b != m_loops)
24✔
287
  {
288
    m_loops = b;
22✔
289
    loopsChanged(b);
22✔
290
  }
22✔
291
}
24✔
292

293
void ProcessModel::setStartOffset(TimeVal b)
10✔
294
{
295
  if(b != m_startOffset)
10✔
296
  {
297
    m_startOffset = b;
9✔
298
    startOffsetChanged(b);
9✔
299
  }
9✔
300
}
10✔
301

302
void ProcessModel::setLoopDuration(TimeVal b)
9✔
303
{
304
  if(b.msec() < 0.1)
9✔
UNCOV
305
    b = TimeVal::fromMsecs(0.1);
×
306

307
  if(b != m_loopDuration)
9✔
308
  {
309
    m_loopDuration = b;
9✔
310
    loopDurationChanged(b);
9✔
311
  }
9✔
312
}
9✔
313

314
QPointF ProcessModel::position() const noexcept
86,107✔
315
{
316
  return m_position;
86,107✔
317
}
318

319
QSizeF ProcessModel::size() const noexcept
83,710✔
320
{
321
  return m_size;
83,710✔
322
}
323

324
void ProcessModel::setPosition(const QPointF& v)
969✔
325
{
326
  if(v != m_position)
969✔
327
  {
328
    m_position = v;
967✔
329
    positionChanged(v);
967✔
330
  }
967✔
331
}
969✔
332

333
void ProcessModel::setSize(const QSizeF& v)
437✔
334
{
335
  if(v != m_size)
437✔
336
  {
337
    m_size = v;
437✔
338
    sizeChanged(v);
437✔
339
  }
437✔
340
}
437✔
341

342
FoldMode ProcessModel::foldMode() const noexcept
906✔
343
{
344
  return m_foldMode;
906✔
345
}
346

347
void ProcessModel::setFoldMode(FoldMode v)
6✔
348
{
349
  if(v != m_foldMode)
6✔
350
  {
351
    m_foldMode = v;
6✔
352
    foldModeChanged(v);
6✔
353
  }
6✔
354
}
6✔
355

356
bool ProcessModel::folded() const noexcept
394✔
357
{
358
  switch(m_foldMode)
394✔
359
  {
360
    case FoldMode::Folded:
361
      return true;
5✔
362
    case FoldMode::Unfolded:
363
      return false;
2✔
364
    case FoldMode::Auto:
387✔
365
    default:
366
      return std::ssize(m_inlets) > MaxUnpaginatedControls;
387✔
367
  }
368
}
394✔
369

370
double ProcessModel::getSlotHeight() const noexcept
9,851✔
371
{
372
  return m_slotHeight;
9,851✔
373
}
374

375
void ProcessModel::setSlotHeight(double v) noexcept
566✔
376
{
377
  m_slotHeight = v;
566✔
378
  slotHeightChanged(v);
566✔
379
}
566✔
380

381
void ProcessModel::setExecuting(bool e)
1,796✔
382
{
383
  m_executing = e;
1,796✔
384
}
1,796✔
385

386
std::optional<Process::MagneticInfo>
387
ProcessModel::magneticPosition(const QObject* o, const TimeVal t) const noexcept
2✔
388
{
389
  return {};
2✔
390
}
391

UNCOV
392
bool ProcessModel::externalSourceOutOfDate() const noexcept
×
393
{
UNCOV
394
  return false;
×
395
}
396

397
score::Command*
UNCOV
398
ProcessModel::refreshFromExternalSource(const score::DocumentContext& ctx) const
×
399
{
UNCOV
400
  return nullptr;
×
401
}
402

403
ProcessModel* parentProcess(QObject* obj) noexcept
11✔
404
{
405
  if(obj)
11✔
406
    obj = obj->parent();
11✔
407

408
  while(obj && !qobject_cast<ProcessModel*>(obj))
11✔
409
  {
410
    obj = obj->parent();
×
411
  }
412

413
  if(obj)
11✔
414
    return static_cast<ProcessModel*>(obj);
11✔
UNCOV
415
  return nullptr;
×
416
}
11✔
417

418
const ProcessModel* parentProcess(const QObject* obj) noexcept
37✔
419
{
420
  if(obj)
37✔
421
    obj = obj->parent();
37✔
422

423
  while(obj && !qobject_cast<const ProcessModel*>(obj))
37✔
424
  {
425
    obj = obj->parent();
×
426
  }
427

428
  if(obj)
37✔
429
    return static_cast<const ProcessModel*>(obj);
37✔
430
  return nullptr;
×
431
}
37✔
432

433
QString processLocalTreeAddress(const ProcessModel& proc)
×
434
{
435
  if(auto lt = findComponent<LocalTree::ProcessComponent>(proc.components()))
×
436
  {
UNCOV
437
    return QString::fromStdString(
×
UNCOV
438
        lt->node().get_device().get_name() + ":" + lt->node().osc_address());
×
439
  }
UNCOV
440
  return {};
×
UNCOV
441
}
×
442
}
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