2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "canvas-view-rasterize-thread.h"
22 #include <dali/devel-api/adaptor-framework/thread-settings.h>
23 #include <dali/integration-api/adaptor-framework/adaptor.h>
31 CanvasRendererRasterizingTask::CanvasRendererRasterizingTask(CanvasView* canvasView, CanvasRenderer canvasRenderer)
32 : mCanvasView(canvasView),
33 mCanvasRenderer(canvasRenderer),
34 mPixelData(PixelData()),
39 bool CanvasRendererRasterizingTask::Rasterize()
41 if(mCanvasRenderer && mCanvasRenderer.Rasterize())
43 Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer();
44 auto width = pixbuf.GetWidth();
45 auto height = pixbuf.GetHeight();
46 if(width > 0 && height > 0)
48 mBufferSize.width = width;
49 mBufferSize.height = height;
51 mPixelData = Devel::PixelBuffer::Convert(pixbuf);
58 CanvasView* CanvasRendererRasterizingTask::GetCanvasView() const
60 return mCanvasView.Get();
63 PixelData CanvasRendererRasterizingTask::GetPixelData() const
68 Vector2 CanvasRendererRasterizingTask::GetBufferSize() const
73 CanvasViewRasterizeThread::CanvasViewRasterizeThread()
74 : mTrigger(new EventThreadCallback(MakeCallback(this, &CanvasViewRasterizeThread::ApplyRasterized))),
75 mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
76 mProcessorRegistered(false),
77 mRasterizationCompletedSignal()
81 CanvasViewRasterizeThread::~CanvasViewRasterizeThread()
83 if(mProcessorRegistered && Adaptor::IsAvailable())
85 Adaptor::Get().UnregisterProcessor(*this);
89 void CanvasViewRasterizeThread::TerminateThread(CanvasViewRasterizeThread*& thread)
93 // add an empty task would stop the thread from conditional wait.
94 thread->AddTask(CanvasRendererRasterizingTaskPtr());
103 void CanvasViewRasterizeThread::AddTask(CanvasRendererRasterizingTaskPtr task)
105 bool wasEmpty = false;
108 // Lock while adding task to the queue
109 ConditionalWait::ScopedLock lock(mConditionalWait);
110 wasEmpty = mRasterizeTasks.empty();
111 if(!wasEmpty && task != NULL)
113 // Remove the tasks with the same renderer.
114 // Older task which waiting to rasterize and apply the svg to the same renderer is expired.
115 for(std::vector<CanvasRendererRasterizingTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
117 if((*it) && (*it)->GetCanvasView() == task->GetCanvasView()) //Need
119 mRasterizeTasks.erase(it);
124 mRasterizeTasks.push_back(task);
126 if(!mProcessorRegistered && Adaptor::IsAvailable())
128 Adaptor::Get().RegisterProcessor(*this);
129 mProcessorRegistered = true;
135 // wake up the image loading thread
136 mConditionalWait.Notify();
140 CanvasRendererRasterizingTaskPtr CanvasViewRasterizeThread::NextCompletedTask()
142 // Lock while popping task out from the queue
143 Mutex::ScopedLock lock(mMutex);
145 if(mCompletedTasks.empty())
147 return CanvasRendererRasterizingTaskPtr();
150 std::vector<CanvasRendererRasterizingTaskPtr>::iterator next = mCompletedTasks.begin();
151 CanvasRendererRasterizingTaskPtr nextTask = *next;
152 mCompletedTasks.erase(next);
157 void CanvasViewRasterizeThread::RemoveTask(CanvasView* canvasView)
159 // Lock while remove task from the queue
160 ConditionalWait::ScopedLock lock(mConditionalWait);
161 if(!mRasterizeTasks.empty())
163 for(std::vector<CanvasRendererRasterizingTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
165 if((*it) && (*it)->GetCanvasView() == canvasView)
167 mRasterizeTasks.erase(it);
173 UnregisterProcessor();
176 CanvasRendererRasterizingTaskPtr CanvasViewRasterizeThread::NextTaskToProcess()
178 // Lock while popping task out from the queue
179 ConditionalWait::ScopedLock lock(mConditionalWait);
182 while(mRasterizeTasks.empty())
184 mConditionalWait.Wait(lock);
187 // pop out the next task from the queue
188 std::vector<CanvasRendererRasterizingTaskPtr>::iterator next = mRasterizeTasks.begin();
189 CanvasRendererRasterizingTaskPtr nextTask = *next;
190 mRasterizeTasks.erase(next);
195 void CanvasViewRasterizeThread::AddCompletedTask(CanvasRendererRasterizingTaskPtr task)
197 // Lock while adding task to the queue
198 Mutex::ScopedLock lock(mMutex);
199 mCompletedTasks.push_back(task);
201 // wake up the main thread
205 void CanvasViewRasterizeThread::Run()
207 SetThreadName("CanvasViewThread");
208 mLogFactory.InstallLogFunction();
210 while(CanvasRendererRasterizingTaskPtr task = NextTaskToProcess())
212 if(task->Rasterize())
214 AddCompletedTask(task);
219 void CanvasViewRasterizeThread::ApplyRasterized()
221 while(CanvasRendererRasterizingTaskPtr task = NextCompletedTask())
223 RasterizationCompletedSignal().Emit(task->GetPixelData());
226 UnregisterProcessor();
229 void CanvasViewRasterizeThread::Process(bool postProcessor)
234 CanvasViewRasterizeThread::RasterizationCompletedSignalType& CanvasViewRasterizeThread::RasterizationCompletedSignal()
236 return mRasterizationCompletedSignal;
239 void CanvasViewRasterizeThread::UnregisterProcessor()
241 if(mProcessorRegistered)
243 if(mRasterizeTasks.empty() && mCompletedTasks.empty() && Adaptor::IsAvailable())
245 Adaptor::Get().UnregisterProcessor(*this);
246 mProcessorRegistered = false;
251 } // namespace Internal
253 } // namespace Toolkit