Skip to content

Commit afe4b29

Browse files
Development/monitor modes fixes (#931)
* Compositor: add error handling * Compositor: configure DRM pipeline if hardware is not pre-configured
1 parent 801ee2a commit afe4b29

File tree

10 files changed

+395
-345
lines changed

10 files changed

+395
-345
lines changed

Compositor/lib/Mesa/Compositor.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,12 @@ namespace Plugin {
331331
class AtomicFifo {
332332
public:
333333
AtomicFifo()
334-
: _head { 0 }
335-
, _tail { 0 }
334+
: _head{ 0 }
335+
, _tail{ 0 }
336336
{
337337
// Initialize array elements
338338
for (auto& element : _queue) {
339-
element.store(T {}, std::memory_order_relaxed);
339+
element.store(T{}, std::memory_order_relaxed);
340340
}
341341
}
342342

@@ -637,7 +637,10 @@ namespace Plugin {
637637

638638
{
639639
_connector = Compositor::CreateBuffer(name, width, height, refreshRate, format, renderer, &_sink);
640-
TRACE(Trace::Information, (_T("Output %s created."), name.c_str()));
640+
641+
if (_connector.IsValid() == false) {
642+
TRACE(Trace::Error, (_T("Could not create output connector for %s"), name.c_str()));
643+
}
641644
}
642645

643646
virtual ~Output()
@@ -683,7 +686,7 @@ namespace Plugin {
683686
{
684687
return (_connector->Height());
685688
}
686-
bool IsValid()
689+
bool IsValid() const
687690
{
688691
return _connector.IsValid();
689692
}

Compositor/lib/Mesa/backend/src/DRM/Connector.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ namespace Compositor {
335335
}
336336
Core::ProxyType<Compositor::IRenderer::IFrameBuffer> FrameBuffer() const override
337337
{
338-
return _frameBuffer.FrameBuffer();
338+
return (_frameBuffer.IsValid() == true) ? _frameBuffer.FrameBuffer() : Core::ProxyType<Compositor::IRenderer::IFrameBuffer>();
339339
}
340340

341341
private:

Compositor/lib/Mesa/backend/src/DRM/DRM.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,14 +261,19 @@ namespace Compositor {
261261
ASSERT(drmAvailable() == 1);
262262
ASSERT(connectorName.empty() == false);
263263

264+
Core::ProxyType<IOutput> connector;
265+
264266
TRACE_GLOBAL(Trace::Backend, ("Requesting connector '%s'", connectorName.c_str()));
265267
std::string gpuNodeName(DRM::GetGPUNode(connectorName));
266-
Core::ProxyType<Backend::DRM> backend = Backend::_backends.Instance<Backend::DRM>(gpuNodeName, gpuNodeName);
267268

268-
Core::ProxyType<IOutput> connector;
269+
if (gpuNodeName.empty() == false) {
270+
Core::ProxyType<Backend::DRM> backend = Backend::_backends.Instance<Backend::DRM>(gpuNodeName, gpuNodeName);
269271

270-
if (backend.IsValid()) {
271-
connector = backend->GetConnector(connectorName, width, height, refreshRate, format, renderer, feedback);
272+
if (backend.IsValid()) {
273+
connector = backend->GetConnector(connectorName, width, height, refreshRate, format, renderer, feedback);
274+
}
275+
} else {
276+
TRACE_GLOBAL(Trace::Error, ("Could not find GPU node for connector '%s'", connectorName.c_str()));
272277
}
273278

274279
return connector;

Compositor/lib/Mesa/drm/DRM.cpp

Lines changed: 171 additions & 62 deletions
Large diffs are not rendered by default.

Compositor/lib/Mesa/drm/DRM.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace Compositor {
4040
class Properties;
4141

4242
using Identifier = uint32_t;
43-
static constexpr uint32_t InvalidIdentifier = ~0;
43+
static constexpr uint32_t InvalidIdentifier = 0;
4444

4545
struct ConnectorScanResult {
4646
bool success = false;

Compositor/lib/Mesa/renderer/test/BaseTest.h

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,66 @@ class BaseTest {
3838
BaseTest& _parent;
3939
};
4040

41+
public:
42+
class ConsoleOptions : public Core::Options {
43+
public:
44+
ConsoleOptions(int argumentCount, TCHAR* arguments[])
45+
: Core::Options(argumentCount, arguments, _T("o:r:f:H:W:h"))
46+
, RenderNode("/dev/dri/renderD128")
47+
, Output("HDMI-A-1")
48+
, FPS(0) // Default to 0 (use connector's default)
49+
, Width(0)
50+
, Height(0)
51+
{
52+
Parse();
53+
}
54+
~ConsoleOptions()
55+
{
56+
}
57+
58+
public:
59+
const TCHAR* RenderNode;
60+
const TCHAR* Output;
61+
uint16_t FPS;
62+
uint16_t Width;
63+
uint16_t Height;
64+
65+
private:
66+
virtual void Option(const TCHAR option, const TCHAR* argument)
67+
{
68+
switch (option) {
69+
case 'o':
70+
Output = argument;
71+
break;
72+
case 'r':
73+
RenderNode = argument;
74+
break;
75+
case 'f':
76+
FPS = std::stoi(argument);
77+
break;
78+
case 'H':
79+
Height = std::stoi(argument);
80+
break;
81+
case 'W':
82+
Width = std::stoi(argument);
83+
break;
84+
85+
case 'h':
86+
default:
87+
fprintf(stderr, "Usage: " EXPAND_AND_QUOTE(APPLICATION_NAME) " [-o <HDMI-A-1>] [-r </dev/dri/renderD128>] [-f <30000>] [-H 1080] [-W 1920]\n");
88+
exit(EXIT_FAILURE);
89+
break;
90+
}
91+
}
92+
};
93+
4194
public:
4295
BaseTest() = delete;
4396
BaseTest(const BaseTest&) = delete;
4497
BaseTest& operator=(const BaseTest&) = delete;
4598

46-
BaseTest(const std::string& connectorId, const std::string& renderId, const uint16_t mFramePerSecond)
99+
BaseTest(const std::string& connectorId, const std::string& renderId,
100+
const uint16_t mFramePerSecond = 0, const uint16_t width = 0, const uint16_t height = 0)
47101
: _renderer()
48102
, _connector()
49103
, _period(mFramePerSecond > 0 ? std::chrono::microseconds(1000000000) / mFramePerSecond : std::chrono::microseconds(16667))
@@ -63,12 +117,17 @@ class BaseTest {
63117
_renderer = Compositor::IRenderer::Instance(_renderFd);
64118
ASSERT(_renderer.IsValid());
65119

120+
TRACE(Trace::Information, ("Using renderer %s[%d] on connector %s (hxw: %dx%d) at %d fps", renderId.c_str(), _renderFd, connectorId.c_str(), width, height, mFramePerSecond));
121+
66122
_connector = Compositor::CreateBuffer(
67-
connectorId, 1920, 1080, mFramePerSecond,
123+
connectorId, width, height, mFramePerSecond,
68124
Compositor::PixelFormat::Default(),
69125
_renderer, &_sink);
70126

71-
ASSERT(_connector.IsValid());
127+
if (_connector.IsValid() == false) {
128+
TRACE(Trace::Error, ("Could not create connector for %s", connectorId.c_str()));
129+
ASSERT(false);
130+
}
72131
}
73132

74133
virtual ~BaseTest()

Compositor/lib/Mesa/renderer/test/testclear.cpp

Lines changed: 27 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ class RenderTest : public BaseTest {
6060
RenderTest(const RenderTest&) = delete;
6161
RenderTest& operator=(const RenderTest&) = delete;
6262

63-
RenderTest(const std::string& connectorId, const std::string& renderId, const uint16_t framePerSecond, const uint8_t rotationsPerSecond)
64-
: BaseTest(connectorId, renderId, framePerSecond)
63+
RenderTest(const std::string& connectorId, const std::string& renderId, const uint16_t FPS, const uint16_t width = 0, const uint16_t height = 0)
64+
: BaseTest(connectorId, renderId, FPS, width, height)
6565
, _color(hsv2rgb(_rotation, .9, .7))
66-
, _rotationPeriod(std::chrono::seconds(rotationsPerSecond))
66+
, _rotationPeriod(std::chrono::seconds(10))
6767
, _rotation(0)
6868
{
6969
NewFrame();
@@ -112,30 +112,35 @@ class RenderTest : public BaseTest {
112112

113113
Core::ProxyType<Compositor::IRenderer::IFrameBuffer> frameBuffer = connector->FrameBuffer();
114114

115-
renderer->Bind(frameBuffer);
115+
if (frameBuffer.IsValid() == true) {
116+
renderer->Bind(frameBuffer);
116117

117-
renderer->Begin(connector->Width(), connector->Height());
118-
renderer->Clear(_color);
119-
renderer->End();
120-
renderer->Unbind(frameBuffer);
118+
renderer->Begin(connector->Width(), connector->Height());
119+
renderer->Clear(_color);
120+
renderer->End();
121+
renderer->Unbind(frameBuffer);
121122

122-
connector->Commit();
123+
connector->Commit();
123124

124-
auto periodCount = Period().count();
125+
auto periodCount = Period().count();
125126

126-
if (periodCount > 0) {
127-
_rotation += 360. / (_rotationPeriod.count() * (std::chrono::microseconds(std::chrono::seconds(1)).count() / periodCount));
128-
} else {
129-
TRACE(Trace::Warning, ("Period count is zero, skipping rotation update"));
130-
}
127+
if (periodCount > 0) {
128+
_rotation += 360. / (_rotationPeriod.count() * (std::chrono::microseconds(std::chrono::seconds(1)).count() / periodCount));
129+
} else {
130+
TRACE(Trace::Warning, ("Period count is zero, skipping rotation update"));
131+
}
131132

132-
if (_rotation >= 360) {
133-
_rotation = 0;
134-
}
133+
if (_rotation >= 360) {
134+
_rotation = 0;
135+
}
135136

136-
_color = hsv2rgb(_rotation, .9, .7);
137+
_color = hsv2rgb(_rotation, .9, .7);
137138

138-
WaitForVSync(1000);
139+
WaitForVSync(1000);
140+
} else {
141+
TRACE(Trace::Error, ("No valid framebuffer to render to"));
142+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
143+
}
139144

140145
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start);
141146
}
@@ -145,47 +150,13 @@ class RenderTest : public BaseTest {
145150
const std::chrono::seconds _rotationPeriod;
146151
float _rotation;
147152
}; // RenderTest
148-
class ConsoleOptions : public Core::Options {
149-
public:
150-
ConsoleOptions(int argumentCount, TCHAR* arguments[])
151-
: Core::Options(argumentCount, arguments, _T("o:r:h"))
152-
, RenderNode("/dev/dri/card0")
153-
, Output(RenderNode)
154-
{
155-
Parse();
156-
}
157-
~ConsoleOptions()
158-
{
159-
}
160-
161-
public:
162-
const TCHAR* RenderNode;
163-
const TCHAR* Output;
164153

165-
private:
166-
virtual void Option(const TCHAR option, const TCHAR* argument)
167-
{
168-
switch (option) {
169-
case 'o':
170-
Output = argument;
171-
break;
172-
case 'r':
173-
RenderNode = argument;
174-
break;
175-
case 'h':
176-
default:
177-
fprintf(stderr, "Usage: " EXPAND_AND_QUOTE(APPLICATION_NAME) " [-o <HDMI-A-1>] [-r </dev/dri/renderD128>]\n");
178-
exit(EXIT_FAILURE);
179-
break;
180-
}
181-
}
182-
};
183154
}
184155

185156
int main(int argc, char* argv[])
186157
{
187158
bool quitApp(false);
188-
ConsoleOptions options(argc, argv);
159+
BaseTest::ConsoleOptions options(argc, argv);
189160

190161
Messaging::LocalTracer& tracer = Messaging::LocalTracer::Open();
191162

@@ -215,7 +186,7 @@ int main(int argc, char* argv[])
215186

216187
TRACE_GLOBAL(Trace::Information, ("%s - build: %s", executableName, __TIMESTAMP__));
217188

218-
RenderTest test(options.Output, options.RenderNode, 0, 10);
189+
RenderTest test(options.Output, options.RenderNode, options.FPS, options.Width, options.Height);
219190

220191
test.Start();
221192

0 commit comments

Comments
 (0)