Merge "Fix the texture bleeding with wrapping in atlas" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / image-atlas / image-load-thread.cpp
1 /*
2  * Copyright (c) 2015 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
18 // CLASS HEADER
19 #include "image-load-thread.h"
20
21 namespace Dali
22 {
23
24 namespace Toolkit
25 {
26
27 namespace Internal
28 {
29
30 LoadingTask::LoadingTask(BitmapLoader loader, uint32_t packPositionX, uint32_t packPositionY, uint32_t width, uint32_t height )
31 : loader( loader ),
32   packRect( packPositionX, packPositionY, width, height )
33 {
34 }
35
36 LoadQueue::LoadQueue()
37 {
38 }
39
40 LoadQueue::~LoadQueue()
41 {
42 }
43
44 LoadingTask* LoadQueue::NextTask()
45 {
46   // Lock while popping task out from the queue
47   ConditionalWait::ScopedLock lock( mConditionalWait );
48
49   while( mTasks.Empty() )
50   {
51     mConditionalWait.Wait( lock );
52   }
53
54   Vector< LoadingTask* >::Iterator next = mTasks.Begin();
55   LoadingTask* nextTask = *next;
56   mTasks.Erase( next );
57
58   return nextTask;
59 }
60
61 void LoadQueue::AddTask( LoadingTask* task )
62 {
63   bool wasEmpty = false;
64
65   {
66     // Lock while adding task to the queue
67     ConditionalWait::ScopedLock lock( mConditionalWait );
68     wasEmpty = mTasks.Empty();
69     mTasks.PushBack( task );
70   }
71
72   if( wasEmpty)
73   {
74     // wake up the image loading thread
75     mConditionalWait.Notify();
76   }
77 }
78
79 CompleteQueue::CompleteQueue(EventThreadCallback* trigger)
80 : mTrigger( trigger )
81 {}
82
83 CompleteQueue::~CompleteQueue()
84 {
85   delete mTrigger;
86 }
87
88 LoadingTask* CompleteQueue::NextTask()
89 {
90   // Lock while popping task out from the queue
91   Mutex::ScopedLock lock( mMutex );
92
93   if( mTasks.Empty() )
94   {
95     return NULL;
96   }
97
98   Vector< LoadingTask* >::Iterator next = mTasks.Begin();
99   LoadingTask* nextTask = *next;
100   mTasks.Erase( next );
101
102   return nextTask;
103 }
104
105 void CompleteQueue::AddTask( LoadingTask* task )
106 {
107   // Lock while adding task to the queue
108   Mutex::ScopedLock lock( mMutex );
109   mTasks.PushBack( task );
110
111   // wake up the main thread
112   mTrigger->Trigger();
113 }
114
115
116 ImageLoadThread::ImageLoadThread( LoadQueue& loadQueue, CompleteQueue& completeQueue )
117 : mLoadQueue( loadQueue ),
118   mCompleteQueue( completeQueue )
119 {
120 }
121
122 ImageLoadThread::~ImageLoadThread()
123 {
124 }
125
126 void ImageLoadThread::Run()
127 {
128   while( LoadingTask* task = mLoadQueue.NextTask() )
129   {
130     task->loader.Load();
131     mCompleteQueue.AddTask( task );
132   }
133 }
134
135 } // namespace Internal
136
137 } // namespace Toolkit
138
139 } // namespace Dali