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

ossia / score / 30213925900

26 Jul 2026 06:03PM UTC coverage: 15.298% (-0.01%) from 15.311%
30213925900

push

github

jcelerier
3rdparty: bump libossia for the network-context poll fix

Brings in ossia/libossia#913: SDL joystick init no longer requires haptic
support (which the Emscripten SDL2 port does not have), and
network_context::poll() restarts the io_context, without which the
WebAssembly polling path stops after its first tick.

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

30400 of 198713 relevant lines covered (15.3%)

997.67 hits per line

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

0.0
/src/plugins/score-plugin-gfx/Gfx/InvertYRenderer.cpp
1
#include "InvertYRenderer.hpp"
2

3
#include <Gfx/Graph/RenderList.hpp>
4
#include <Gfx/Graph/Utils.hpp>
5

6
namespace Gfx
7
{
8

9
InvertYRenderer::InvertYRenderer(
×
10
    const score::gfx::Node& n, score::gfx::TextureRenderTarget rt,
11
    QRhiReadbackResult& readback)
12
    : score::gfx::OutputNodeRenderer{n}
×
13
    , m_inputTarget{std::move(rt)}
×
14
    , m_readback{&readback}
15
{
×
16
}
×
17

18
void InvertYRenderer::init(
×
19
    score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res)
20
{
21
  m_renderTarget = score::gfx::createRenderTarget(
×
22
      renderer.state, renderer.state.renderFormat, m_inputTarget.texture->pixelSize(),
×
23
      renderer.samples(), renderer.requiresDepth(*this->node.input[0]));
×
24

25
  const auto& mesh = renderer.defaultTriangle();
×
26
  m_mesh = renderer.initMeshBuffer(mesh, res);
×
27

28
  // We need to have a pass to invert the Y coordinate to go
29
  // from GL direction (Y up) to normal video (Y down)
30
  // FIXME spout likely needs the same
31
  static const constexpr auto gl_filter = R"_(#version 450
32
    layout(location = 0) in vec2 v_texcoord;
33
    layout(location = 0) out vec4 fragColor;
34

35
    layout(binding = 3) uniform sampler2D tex;
36

37
    void main()
38
    {
39
#if defined(QSHADER_MSL) || defined(QSHADER_HLSL)
40
      // Metal already has attachment output inverted
41
      fragColor = texture(tex, vec2(v_texcoord.x, v_texcoord.y));
42
#else
43
      fragColor = texture(tex, vec2(v_texcoord.x, 1. - v_texcoord.y));
44
#endif
45
    }
46
    )_";
47
  std::tie(m_vertexS, m_fragmentS)
×
48
      = score::gfx::makeShaders(renderer.state, mesh.defaultVertexShader(), gl_filter);
×
49

50
  // Put the input texture, where all the input nodes are rendering, in a sampler.
51
  {
52
    auto sampler = renderer.state.rhi->newSampler(
×
53
        QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
54
        QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
55

56
    sampler->setName("FullScreenImageNode::sampler");
×
57
    sampler->create();
×
58

59
    m_samplers.push_back({sampler, this->m_inputTarget.texture});
×
60
  }
61

62
  m_p = score::gfx::buildPipeline(
×
63
      renderer, mesh, m_vertexS, m_fragmentS, m_renderTarget, nullptr, nullptr,
×
64
      m_samplers);
×
65
}
×
66

67
void InvertYRenderer::update(
×
68
    score::gfx::RenderList& renderer, QRhiResourceUpdateBatch& res, score::gfx::Edge* e)
69
{
70
}
×
71

72
void InvertYRenderer::release(score::gfx::RenderList&)
×
73
{
74
  m_p.release();
×
75
  for(auto& s : m_samplers)
×
76
  {
77
    delete s.sampler;
×
78
  }
79
  m_samplers.clear();
×
80
  m_renderTarget.release();
×
81
}
×
82

83
void InvertYRenderer::finishFrame(
×
84
    score::gfx::RenderList& renderer, QRhiCommandBuffer& cb,
85
    QRhiResourceUpdateBatch*& res)
86
{
87
  cb.beginPass(m_renderTarget.renderTarget, Qt::black, {1.0f, 0}, res);
×
88
  res = nullptr;
×
89
  {
90
    const auto sz = renderer.state.renderSize;
×
91
    cb.setGraphicsPipeline(m_p.pipeline);
×
92
    cb.setShaderResources(m_p.srb);
×
93
    cb.setViewport(QRhiViewport(0, 0, sz.width(), sz.height()));
×
94

95
    const auto& mesh = renderer.defaultTriangle();
×
96
    mesh.draw(this->m_mesh, cb);
×
97
  }
98

99
  auto next = renderer.state.rhi->nextResourceUpdateBatch();
×
100

101
  QRhiReadbackDescription rb(m_renderTarget.texture);
×
102
  next->readBackTexture(rb, m_readback);
×
103
  cb.endPass(next);
×
104

105
  next = nullptr;
×
106
}
×
107

108

109

110
ScaledRenderer::ScaledRenderer(score::gfx::TextureRenderTarget outputTarget, const score::gfx::RenderState &state, const score::gfx::Node &parent, QRhiSwapChain* swapChain)
×
111
    : score::gfx::OutputNodeRenderer{parent}
×
112
    , m_renderTarget{outputTarget}
×
113
    , m_swapChain{swapChain}
114
{
×
115
}
×
116

117
ScaledRenderer::~ScaledRenderer() { }
×
118

119
void ScaledRenderer::init(score::gfx::RenderList &renderer, QRhiResourceUpdateBatch &res)
×
120
{
121
  m_inputTarget = score::gfx::createRenderTarget(
×
122
      renderer.state, renderer.state.renderFormat, renderer.state.renderSize,
×
123
      renderer.samples(), renderer.requiresDepth(*this->node.input[0]));
×
124

125
  const auto& mesh = renderer.defaultTriangle();
×
126
  m_mesh = renderer.initMeshBuffer(mesh, res);
×
127
  static const constexpr auto gl_filter = R"_(#version 450
128
      layout(location = 0) in vec2 v_texcoord;
129
      layout(location = 0) out vec4 fragColor;
130

131
      layout(binding = 3) uniform sampler2D tex;
132

133
      void main()
134
      {
135
#if defined(QSHADER_SPIRV)
136
        fragColor = texture(tex, vec2(v_texcoord.x, 1. - v_texcoord.y));
137
#else
138
        fragColor = texture(tex, vec2(v_texcoord.x, v_texcoord.y));
139
#endif
140
      }
141
      )_";
142

143
  std::tie(m_vertexS, m_fragmentS)
×
144
      = score::gfx::makeShaders(renderer.state, mesh.defaultVertexShader(), gl_filter);
×
145

146
  m_samplers = {};
×
147
  // Put the input texture, where all the input nodes are rendering, in a sampler.
148
  {
149
    auto sampler = renderer.state.rhi->newSampler(
×
150
        QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
151
        QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
152

153
    sampler->setName("FullScreenImageNode::sampler");
×
154
    sampler->create();
×
155

156
    m_samplers[0] = {sampler, this->m_inputTarget.texture};
×
157
  }
158

159
  if(m_swapChain)
×
160
    m_renderTarget.renderTarget = m_swapChain->currentFrameRenderTarget();
×
161

162
  m_p = score::gfx::buildPipeline(
163
      renderer, mesh, m_vertexS, m_fragmentS, m_renderTarget, nullptr, nullptr,
164
      m_samplers);
165

166
}
×
167

168
void ScaledRenderer::update(score::gfx::RenderList &renderer, QRhiResourceUpdateBatch &res, score::gfx::Edge *edge) {
×
169
}
×
170

171
void ScaledRenderer::runRenderPass(score::gfx::RenderList &, QRhiCommandBuffer &commands, score::gfx::Edge &e)
×
172
{
173
}
×
174

175
void ScaledRenderer::finishFrame(score::gfx::RenderList &renderer, QRhiCommandBuffer &cb, QRhiResourceUpdateBatch *&res)
×
176
{
177
  if(m_swapChain)
×
178
    m_renderTarget.renderTarget = m_swapChain->currentFrameRenderTarget();
×
179

180
  auto* rt = m_renderTarget.renderTarget;
×
181
  if(!rt)
×
182
    return;
×
183

184
  cb.beginPass(rt, Qt::black, {1.0f, 0}, res);
×
185
  res = nullptr;
×
186
  {
187
    // For a swapchain the render target is authoritative: state.outputSize is
188
    // only refreshed when the swapchain is resized, and a zero-sized viewport
189
    // renders nothing.
190
    auto sz = renderer.state.outputSize;
×
191
    if(m_swapChain && !rt->pixelSize().isEmpty())
×
192
      sz = rt->pixelSize();
×
193

194

195
    cb.setGraphicsPipeline(m_p.pipeline);
×
196
    cb.setShaderResources(m_p.srb);
×
197
    cb.setViewport(QRhiViewport(0, 0, sz.width(), sz.height()));
×
198

199
    const auto& mesh = renderer.defaultTriangle();
×
200
    mesh.draw(this->m_mesh, cb);
×
201
  }
202
  cb.endPass();
×
203
}
×
204

205
void ScaledRenderer::release(score::gfx::RenderList &)
×
206
{
207
  m_p.release();
×
208
  m_inputTarget.release();
×
209
  for(auto& s : m_samplers)
×
210
  {
211
    delete s.sampler;
×
212
  }
213
  m_samplers = {};
×
214
  //m_renderTarget.release();
215
}
216

217
score::gfx::TextureRenderTarget ScaledRenderer::renderTargetForInput(const score::gfx::Port &p)
×
218
{
219
  return m_inputTarget;
×
220
}
221

222

223
score::gfx::TextureRenderTarget BasicRenderer::renderTargetForInput(const score::gfx::Port &p) { return m_rt; }
×
224

225
BasicRenderer::BasicRenderer(score::gfx::TextureRenderTarget outputTarget, const score::gfx::RenderState &state, const score::gfx::Node &parent)
×
226
    : score::gfx::OutputNodeRenderer{parent}
×
227
    , m_rt{outputTarget}
×
228
{
×
229
}
×
230

231
BasicRenderer::~BasicRenderer() { }
×
232

233
void BasicRenderer::init(score::gfx::RenderList &renderer, QRhiResourceUpdateBatch &res) { }
×
234

235
void BasicRenderer::update(score::gfx::RenderList &renderer, QRhiResourceUpdateBatch &res, score::gfx::Edge *edge) {
×
236
}
×
237

238
void BasicRenderer::runRenderPass(score::gfx::RenderList &, QRhiCommandBuffer &commands, score::gfx::Edge &e) { }
×
239

240
void BasicRenderer::release(score::gfx::RenderList &) { }
×
241

242
}
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