@@ -138,12 +138,6 @@ namespace Plugin {
138138 private:
139139 using BaseClass = Graphics::ServerBufferType<1 >;
140140
141- enum class State : uint8_t {
142- IDLE = 0x00 ,
143- RENDERING = 0x01 ,
144- PRESENTING = 0x02 ,
145- };
146-
147141 class Remote : public Exchange ::IComposition::IClient {
148142 public:
149143 Remote () = delete ;
@@ -240,7 +234,6 @@ namespace Plugin {
240234 , _geometry({ 0 , 0 , width, height })
241235 , _texture()
242236 , _remoteClient(*this )
243- , _state(State::IDLE)
244237 , _geometryChanged(false )
245238 {
246239 Core::ResourceMonitor::Instance ().Register (*this );
@@ -284,34 +277,17 @@ namespace Plugin {
284277 */
285278 void Request () override
286279 {
287- State expected (State::IDLE);
288-
289- if (_state.compare_exchange_strong (expected, State::RENDERING) == true ) {
290- _parent.Render (); // Trigger rendering operations
291- } else {
292- TRACE (Trace::Error, (_T (" Surface %s[%d] is not idle, but received a Request event while in %d" ), _callsign.c_str (), _id, _state.load ()));
293- ASSERT (false );
294- }
280+ _parent.Render ();
295281 }
296282
297283 void Pending ()
298284 {
299- State expected (State::RENDERING);
300-
301- if (_state.compare_exchange_strong (expected, State::PRESENTING) == true ) {
302- Rendered ();
303- } else {
304- TRACE (Trace::Error, (_T (" Surface %s[%d] is not rendering, but received a Pending event while in %d" ), _callsign.c_str (), _id, _state.load ()));
305- }
285+ Rendered ();
306286 }
307287
308288 void Completed ()
309289 {
310- State expected (State::PRESENTING);
311-
312- if (_state.compare_exchange_strong (expected, State::IDLE) == true ) {
313- Published ();
314- }
290+ Published ();
315291 }
316292
317293 /* *
@@ -390,8 +366,7 @@ namespace Plugin {
390366 Exchange::IComposition::Rectangle _geometry; // the actual geometry of the surface on the composition
391367 Core::ProxyType<Compositor::IRenderer::ITexture> _texture; // the texture handle that is known in the GPU/Renderer.
392368 Remote _remoteClient;
393- std::atomic<State> _state;
394- bool _geometryChanged = false ;
369+ bool _geometryChanged;
395370
396371 static uint32_t _sequence;
397372 }; // class Client
@@ -550,9 +525,9 @@ namespace Plugin {
550525 return _connector;
551526 }
552527
553- void Commit ()
528+ uint32_t Commit ()
554529 {
555- _connector->Commit ();
530+ return _connector->Commit ();
556531 }
557532
558533 private:
@@ -586,8 +561,10 @@ namespace Plugin {
586561 , _renderDescriptor(Compositor::InvalidFileDescriptor)
587562 , _renderNode()
588563 , _present(*this )
589- , _state(State::IDLE)
590564 , _autoScale(true )
565+ , _commitMutex()
566+ , _commitCV()
567+ , _canCommit(true )
591568 {
592569 }
593570 ~CompositorImplementation () override
@@ -643,10 +620,10 @@ namespace Plugin {
643620 _renderer = Compositor::IRenderer::Instance (_renderDescriptor);
644621 ASSERT (_renderer.IsValid ());
645622
646- if (config.AutoScale .IsSet () == true ) {
623+ if (config.AutoScale .IsSet () == true ) {
647624 _autoScale = config.AutoScale .Value ();
648- }
649-
625+ }
626+
650627 if (config.Output .IsSet () == false ) {
651628 return Core::ERROR_INCOMPLETE_CONFIG;
652629 } else {
@@ -813,12 +790,6 @@ namespace Plugin {
813790 END_INTERFACE_MAP
814791
815792 private:
816- enum class State : uint8_t {
817- IDLE = 0x00 ,
818- PRESENTING = 0x01 ,
819- PENDING = 0x02 ,
820- };
821-
822793 void VSync (const Compositor::IOutput* output VARIABLE_IS_NOT_USED, const uint32_t sequence VARIABLE_IS_NOT_USED, const uint64_t pts VARIABLE_IS_NOT_USED /* usec since epoch*/ )
823794 {
824795 {
@@ -828,28 +799,16 @@ namespace Plugin {
828799 });
829800 }
830801
831- State expected = State::PRESENTING;
832-
833- if (_state.compare_exchange_strong (expected, State::IDLE) == false ) {
834- expected = State::PENDING;
835-
836- if (_state.compare_exchange_strong (expected, State::PRESENTING) == true ) {
837- _present.Trigger ();
838- }
802+ {
803+ std::lock_guard<std::mutex> lock (_commitMutex);
804+ _canCommit.store (true , std::memory_order_release);
839805 }
806+ _commitCV.notify_one ();
840807 }
841808
842809 void Render ()
843810 {
844- State expected = State::PRESENTING;
845-
846- if (_state.compare_exchange_strong (expected, State::PENDING) == false ) {
847- expected = State::IDLE;
848-
849- if (_state.compare_exchange_strong (expected, State::PRESENTING) == true ) {
850- _present.Trigger ();
851- }
852- }
811+ _present.Run ();
853812 }
854813
855814 IComposition::IClient* CreateClient (const string& name, const uint32_t width, const uint32_t height) override
@@ -890,6 +849,7 @@ namespace Plugin {
890849
891850 {
892851 std::lock_guard<std::mutex> lock (_clientLock);
852+
893853 _clients.Visit ([&](const string& /* name*/ , const Core::ProxyType<Client> client) {
894854 RenderClient (client); // ~500-900 uS rpi4
895855 });
@@ -899,7 +859,24 @@ namespace Plugin {
899859
900860 _renderer->Unbind (frameBuffer);
901861
902- _output->Commit (); // Blit to screen
862+ // Block until VSync allows commit
863+ {
864+ std::unique_lock<std::mutex> lock (_commitMutex);
865+
866+ if (_commitCV.wait_for (lock, std::chrono::milliseconds (100 ), [this ] {
867+ return _canCommit.load (std::memory_order_acquire); // Wait for permission
868+ })) {
869+ // Got permission, reset it for next frame
870+ _canCommit.store (false , std::memory_order_release);
871+ } else {
872+ TRACE (Trace::Error, (_T (" Timeout waiting for VSync, forcing commit" )));
873+ // Don't reset _canCommit on timeout - let VSync handle it
874+ }
875+ }
876+
877+ uint32_t commit = _output->Commit ();
878+
879+ ASSERT (commit == Core::ERROR_NONE);
903880
904881 return Core::Time::Now ().Ticks ();
905882 }
@@ -951,35 +928,25 @@ namespace Plugin {
951928 Presenter (CompositorImplementation& parent)
952929 : Core::Thread(Thread::DefaultStackSize(), PresenterThreadName)
953930 , _parent(parent)
954- , _continue(false )
955931 {
956932 }
957933
958934 ~Presenter () override
959935 {
960936 Core::Thread::Stop ();
961-
962937 Core::Thread::Wait (Core::Thread::STOPPED, 100 );
963938 }
964939
965- void Trigger ()
966- {
967- Thread::Run ();
968- }
969-
970940 private:
971941 uint32_t Worker () override
972942 {
973943 Core::Thread::Block ();
974-
975944 _parent.RenderOutput (); // 3000us
976-
977945 return Core::infinite;
978946 }
979947
980948 private:
981949 CompositorImplementation& _parent;
982- std::atomic<bool > _continue;
983950 };
984951
985952 private:
@@ -1014,8 +981,10 @@ namespace Plugin {
1014981 int _renderDescriptor;
1015982 std::string _renderNode;
1016983 Presenter _present;
1017- std::atomic<State> _state;
1018984 bool _autoScale;
985+ std::mutex _commitMutex;
986+ std::condition_variable _commitCV;
987+ std::atomic<bool > _canCommit;
1019988 };
1020989
1021990 SERVICE_REGISTRATION (CompositorImplementation, 1 , 0 )
0 commit comments