Skip to content

Commit 8972deb

Browse files
author
msieben
committed
[libdrm-examples]: Extend multi-process compositing.
- Synchronization is placed in its own methods. It still requires user interaction. - Each client is rendered at its own position on 'screen'.
1 parent c4481b8 commit 8972deb

File tree

1 file changed

+95
-16
lines changed

1 file changed

+95
-16
lines changed

package/libdrm-examples/src/drm-prime-multi.cpp

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,9 @@ class RenderClient : public Base {
602602
bool Init ();
603603
bool Deinit ();
604604

605+
bool CreateRemoteBuffer ();
606+
bool DestroyRemoteBuffer ();
607+
605608
bool ShareBuffer ();
606609

607610
bool Render () override;
@@ -644,6 +647,10 @@ class Compositor: public Base {
644647
bool DestroySharedBuffer ();
645648

646649
bool ShareBuffer ();
650+
651+
bool AwaitRequestCreateSharingBuffer ();
652+
bool AwaitRequestCompleteSharingBuffer ();
653+
647654
bool Render () override;
648655
};
649656

@@ -731,7 +738,7 @@ bool Base::ShareBuffer (bool mode) {
731738
_ret = Receive (_msg, _prime._fd);
732739

733740
if (_ret != false) {
734-
size_t _id_p = _msg.find (_width_tag);
741+
size_t _id_p = _msg.find (_id_tag);
735742
size_t _width_p = _msg.find (_width_tag);
736743
size_t _height_p = _msg.find (_height_tag);
737744
size_t _stride_p = _msg.find (_stride_tag);
@@ -1028,6 +1035,9 @@ bool Base::Receive (std::string & msg, DRM::GBM::fd_t & fd) {
10281035
// Error
10291036
std::cout << "Error: read (" << strerror (errno) << ")" << std::endl;
10301037
}
1038+
else {
1039+
_valid = true;
1040+
}
10311041

10321042
}
10331043

@@ -1647,7 +1657,6 @@ bool EGL::Deinit () {
16471657
}
16481658

16491659
bool EGL::ImportBuffer (DRM::GBM::buf_t const & buf) {
1650-
// TODO:
16511660
bool _ret = false;
16521661

16531662
if (buf != DRM::GBM::InvalidBuf ()) {
@@ -1928,6 +1937,8 @@ bool GLES::Clear () {
19281937

19291938
_fbo = InvalidFbo ();
19301939

1940+
_tex = InvalidTex ();
1941+
19311942
_offset = GLES::InitialOffset ();
19321943

19331944
const_cast <remove_const <valid_t>::type &> (_valid) = false;
@@ -2150,9 +2161,8 @@ bool RenderClient::Run () {
21502161

21512162
// Breaks on error like a disconnected communication channel
21522163
while (_ret != false) {
2153-
_ret = ShareBuffer () != false && Render () != false;
2164+
_ret = CreateRemoteBuffer () != false && ShareBuffer () != false && Render () != false && DestroyRemoteBuffer () != false;
21542165

2155-
// TODO: communicate value via communication channels
21562166
if (_ret != false) {
21572167
std::string const _id_s = std::to_string (_id);
21582168
std::cout << "Client [" << _id_s << "] completed rendering frame." << std::endl;
@@ -2174,6 +2184,8 @@ bool RenderClient::Run () {
21742184
std::cout << "Error: RenderClient [" << std::to_string (_id) << "] is unable to complete time out of : " << std::to_string (_timeout.tv_nsec) << " [nsec]. Remaining time [nsec] : " << std::to_string (_remaining.tv_nsec) << std::endl;
21752185
}
21762186
#endif
2187+
2188+
// TODO: signal completion
21772189
}
21782190
}
21792191

@@ -2186,9 +2198,33 @@ bool RenderClient::Run () {
21862198
return _ret;
21872199
}
21882200

2201+
bool RenderClient::CreateRemoteBuffer () {
2202+
bool _ret = true;
2203+
2204+
// TODO: communicate over channel
2205+
2206+
std::cout << "RenderClient [" << std::to_string (_id) << "] has requested to create a remote buffer" << std::endl;
2207+
2208+
return _ret;
2209+
}
2210+
2211+
bool RenderClient::DestroyRemoteBuffer () {
2212+
bool _ret = true;
2213+
2214+
// TODO: communicate over channel
2215+
2216+
std::cout << "RenderClient [" << std::to_string (_id) << "] has requested to destroy a remote buffer" << std::endl;
2217+
2218+
return _ret;
2219+
}
2220+
21892221
bool RenderClient::ShareBuffer () {
21902222
bool _ret = Base::ShareBuffer (_priv);
21912223

2224+
if (_ret != false) {
2225+
std::cout << "RenderClient [" << std::to_string (_id) << "] has received access to the remote buffer" << std::endl;
2226+
}
2227+
21922228
return _ret;
21932229
}
21942230

@@ -2241,17 +2277,10 @@ bool Compositor::Run () {
22412277
bool _ret = Status ();
22422278

22432279
if ( _ret != false) {
2244-
char key = ' ';
2245-
2246-
// TODO: the client should request a buffer
2247-
while (ReadKey ("Press 'c' to create a buffer to be sent, 'Enter' or 'q' to quit", key) != false && key != 'q') {
22482280

2249-
if (key != 'c') {
2250-
continue;
2251-
}
2281+
while (AwaitRequestCreateSharingBuffer () != false) {
22522282

2253-
// TODO : sync via communication channel, ie, the client should signal it is complete
2254-
_ret = CreateSharedBuffer () != false && ShareBuffer () != false && ReadKey ("Press a key once the client (s) complete", key) != false && Render () != false;
2283+
_ret = CreateSharedBuffer () != false && ShareBuffer () != false && AwaitRequestCompleteSharingBuffer () != false && Render () != false /* && DestroySharedBuffer () */;
22552284

22562285
if (_ret != true) {
22572286
std::cout << "Error: cannot render a shared buffer" << std::endl;
@@ -2290,6 +2319,57 @@ bool Compositor::DestroySharedBuffer () {
22902319
return _ret;
22912320
}
22922321

2322+
bool Compositor::AwaitRequestCreateSharingBuffer () {
2323+
bool _ret = false;
2324+
2325+
// TODO: communicate over channel
2326+
2327+
char _key = '\0';
2328+
2329+
while (ReadKey ("Press 'c' to create a shared buffer after a client has requested one, 'Enter' or 'q' to quit", _key) != false && _key != 'q') {
2330+
switch (_key) {
2331+
case 'c' : {
2332+
_ret = true;
2333+
break;
2334+
}
2335+
default : {
2336+
continue;
2337+
}
2338+
}
2339+
2340+
break;
2341+
}
2342+
2343+
return _ret;
2344+
}
2345+
2346+
bool Compositor::AwaitRequestCompleteSharingBuffer () {
2347+
bool _ret = false;
2348+
2349+
// TODO: communicate over channel
2350+
2351+
char _key = '\0';
2352+
2353+
while (ReadKey ("Enter the number (id) of the client that has requested and received the shared buffer, 'Enter' or 'q' to quit", _key) != false && _key != 'q') {
2354+
switch (_key) {
2355+
// TODO: match number of (maximum) clients
2356+
case '1' : {
2357+
_ret = _gles.UpdateOffset (GLES::offset_t (0.25f, 0.25f, 0.0f));
2358+
break;
2359+
}
2360+
case '2' : {
2361+
_ret = _gles.UpdateOffset (GLES::offset_t (-0.25f, -0.25f, 0.0f));
2362+
break;
2363+
}
2364+
default : continue;
2365+
}
2366+
2367+
break;
2368+
}
2369+
2370+
return _ret;
2371+
}
2372+
22932373
bool Compositor::ShareBuffer () {
22942374
bool _ret = false;
22952375

@@ -2301,8 +2381,7 @@ bool Compositor::ShareBuffer () {
23012381
bool Compositor::Render () {
23022382
bool _ret = false;
23032383

2304-
// TODO: the offset is client based in multi client setup
2305-
_ret = _gles.UpdateOffset (GLES::InitialOffset ()) != false && _gles.RenderEGLImage (_egl.Image ()) != false && _egl.Render () != false && _drm.ScanOut () != false;
2384+
_ret = /* _gles.UpdateOffset (GLES::InitialOffset ()) != false && */ _gles.RenderEGLImage (_egl.Image ()) != false && _egl.Render () != false && _drm.ScanOut () != false;
23062385

23072386
return _ret;
23082387
}
@@ -2334,7 +2413,7 @@ main_ret_t main (int argc, char* argv []) {
23342413
constexpr unsigned int TIMEOUT = 1;
23352414
#endif
23362415

2337-
// TODO: no control which client takes the buffer so some form of synchronization / identification is required
2416+
// TODO: link with the additional communication bewteen compositor and clients, currently, just abstracted away in Await* and *RemoteBuffer functions
23382417
constexpr uint8_t _max_childs = 2;
23392418

23402419
uint8_t _num_childs = 1;

0 commit comments

Comments
 (0)