Merge "(gles-sync-pool.cpp) Fixed some SVACE errors" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-sync-pool.cpp
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // Class header
18 #include <dali/internal/graphics/gles-impl/gles-sync-pool.h>
19
20 // External Headers
21 #include <dali/graphics-api/graphics-sync-object-create-info.h>
22
23 // Internal Headers
24 #include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
25 #include <dali/internal/graphics/gles/egl-sync-implementation.h>
26
27 #if defined(DEBUG_ENABLED)
28 extern Debug::Filter* gLogSyncFilter;
29 #endif
30
31 namespace Dali::Graphics::GLES
32 {
33 AgingSyncObject::AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool _egl)
34 : controller(controller),
35   writeContext(writeContext),
36   egl(_egl)
37 {
38   if(egl)
39   {
40     eglSyncObject = static_cast<Internal::Adaptor::EglSyncObject*>(controller.GetEglSyncImplementation().CreateSyncObject());
41     DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::cons; EGL::CreateSyncObject: %p\n", eglSyncObject);
42   }
43   else
44   {
45     auto gl = controller.GetGL();
46     if(gl)
47     {
48       glSyncObject = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
49     }
50   }
51 }
52
53 AgingSyncObject::~AgingSyncObject()
54 {
55   if(!controller.IsShuttingDown())
56   {
57     if(egl)
58     {
59       DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::dstr; EGL::DestroySyncObject: %p\n", eglSyncObject);
60       controller.GetEglSyncImplementation().DestroySyncObject(eglSyncObject);
61     }
62     else
63     {
64       auto gl = controller.GetGL();
65       if(gl && glSyncObject != nullptr)
66       {
67         gl->DeleteSync(glSyncObject);
68       }
69     }
70   }
71 }
72
73 bool AgingSyncObject::ClientWait()
74 {
75   bool synced = false;
76   if(egl)
77   {
78     if(eglSyncObject)
79     {
80       DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::ClientWait(); EGL::ClientWaitSync\n");
81       eglSyncObject->ClientWait();
82       synced = true;
83     }
84   }
85   else
86   {
87     auto gl = controller.GetGL();
88     if(gl && glSyncObject)
89     {
90       DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::ClientWait(); glClientWaitSync 1ms\n");
91       const GLuint64 TIMEOUT = 1000000; //1ms!
92       GLenum         result  = gl->ClientWaitSync(glSyncObject, GL_SYNC_FLUSH_COMMANDS_BIT, TIMEOUT);
93
94       synced = (result == GL_ALREADY_SIGNALED || result == GL_CONDITION_SATISFIED);
95     }
96   }
97   DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::ClientWait(); Result: %s\n", synced ? "Synced" : "NOT SYNCED");
98   return synced;
99 }
100
101 void AgingSyncObject::Wait()
102 {
103   if(egl)
104   {
105     if(eglSyncObject)
106     {
107       DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::Wait(); EGL::WaitSync\n");
108       eglSyncObject->Wait();
109     }
110   }
111   else
112   {
113     auto gl = controller.GetGL();
114     if(gl && glSyncObject)
115     {
116       DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::Wait(); glWaitSync\n");
117       gl->WaitSync(glSyncObject, 0, 0ull);
118     }
119   }
120 }
121
122 SyncPool::~SyncPool() = default;
123
124 AgingSyncObject* SyncPool::AllocateSyncObject(const Context* writeContext, SyncPool::SyncContext syncContext)
125 {
126   std::unique_ptr<AgingSyncObject> syncObject = std::make_unique<AgingSyncObject>(mController, writeContext, (syncContext == SyncContext::EGL));
127   mSyncObjects.push_back(std::move(syncObject));
128   return mSyncObjects.back().get();
129 }
130
131 void SyncPool::Wait(AgingSyncObject* syncPoolObject)
132 {
133   if(syncPoolObject != nullptr)
134   {
135     syncPoolObject->syncing = true;
136     syncPoolObject->Wait();
137   }
138 }
139
140 bool SyncPool::ClientWait(AgingSyncObject* syncPoolObject)
141 {
142   if(syncPoolObject)
143   {
144     return syncPoolObject->ClientWait();
145   }
146   return false;
147 }
148
149 void SyncPool::FreeSyncObject(AgingSyncObject* agingSyncObject)
150 {
151   auto iter = std::find_if(mSyncObjects.begin(), mSyncObjects.end(), [&agingSyncObject](AgingSyncPtrRef agingSyncPtr) { return agingSyncPtr.get() == agingSyncObject; });
152   if(iter != mSyncObjects.end())
153   {
154     iter->reset();
155   }
156 }
157
158 /**
159  * Age sync objects. Call at the end of each frame.
160  * When a sync object is older than 2 frames, delete it.
161  */
162 void SyncPool::AgeSyncObjects()
163 {
164   DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count: %d\n", mSyncObjects.size());
165
166   if(!mSyncObjects.empty())
167   {
168     // Age the remaining sync objects.
169     for(auto& agingSyncObject : mSyncObjects)
170     {
171       if(agingSyncObject != nullptr && (agingSyncObject->glSyncObject != 0 || agingSyncObject->eglSyncObject != nullptr))
172       {
173         if(agingSyncObject->age > 0)
174         {
175           agingSyncObject->age--;
176         }
177         else
178         {
179           agingSyncObject.reset();
180         }
181       }
182     }
183   }
184   // Move any old sync objects to the end of the list, and then remove them all.
185   mSyncObjects.erase(std::remove_if(mSyncObjects.begin(), mSyncObjects.end(), [&](std::unique_ptr<AgingSyncObject>& agingSyncObject) { return agingSyncObject == nullptr; }),
186                      mSyncObjects.end());
187
188   DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count after erase: %d\n", mSyncObjects.size());
189 }
190
191 } // namespace Dali::Graphics::GLES