4d60fee81e4920428833cb40ab76cf2935583322
[platform/core/uifw/dali-adaptor.git] / dali / internal / legacy / common / tizen-platform-abstraction.cpp
1 /*
2  * Copyright (c) 2019 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 <dali/internal/legacy/common/tizen-platform-abstraction.h>
20
21 // EXTERNAL INCLUDES
22 #include <dirent.h>
23 #include <fstream>
24 #include <algorithm>
25 #include <dali/integration-api/debug.h>
26 #include <dali/integration-api/bitmap.h>
27 #include <dali/integration-api/resource-types.h>
28 #include <dali/public-api/signals/callback.h>
29
30 // INTERNAL INCLUDES
31 #include <dali/internal/adaptor/common/adaptor-impl.h>
32 #include <dali/internal/imaging/common/image-loader.h>
33 #include <dali/internal/system/common/file-reader.h>
34 #include <dali/internal/imaging/common/pixel-buffer-impl.h>
35
36 namespace Dali
37 {
38
39 namespace TizenPlatform
40 {
41
42 struct TizenPlatformAbstraction::TimerCallback : ConnectionTracker
43 {
44   Dali::Timer mTimer;
45   TizenPlatformAbstraction* mOwner;
46   CallbackBase* mCallback;
47   const uint32_t mIdNumber;
48
49   static uint32_t sNextTimerId;
50
51   TimerCallback(TizenPlatformAbstraction* owner, CallbackBase* callback, uint32_t ms)
52   : mTimer(Dali::Timer::New(ms)),
53     mOwner(owner),
54     mCallback(callback),
55     mIdNumber(sNextTimerId++)
56   {
57     mTimer.TickSignal().Connect( this, &TimerCallback::Tick );
58     mTimer.Start();
59   }
60
61   bool Tick()
62   {
63     mOwner->RunTimerFunction(*this);
64     return false;
65   }
66 };
67
68 uint32_t TizenPlatformAbstraction::TimerCallback::sNextTimerId = 0;
69
70 TizenPlatformAbstraction::TizenPlatformAbstraction()
71 : mDataStoragePath( "" ),
72   mTimerPairsWaiting(),
73   mTimerPairsSpent()
74
75 {
76 }
77
78 TizenPlatformAbstraction::~TizenPlatformAbstraction()
79 {
80 }
81
82 ImageDimensions TizenPlatformAbstraction::GetClosestImageSize( const std::string& filename,
83                                                                ImageDimensions size,
84                                                                FittingMode::Type fittingMode,
85                                                                SamplingMode::Type samplingMode,
86                                                                bool orientationCorrection )
87 {
88   return ImageLoader::GetClosestImageSize( filename, size, fittingMode, samplingMode, orientationCorrection );
89 }
90
91 ImageDimensions TizenPlatformAbstraction::GetClosestImageSize( Integration::ResourcePointer resourceBuffer,
92                                                                ImageDimensions size,
93                                                                FittingMode::Type fittingMode,
94                                                                SamplingMode::Type samplingMode,
95                                                                bool orientationCorrection )
96 {
97   return ImageLoader::GetClosestImageSize( resourceBuffer, size, fittingMode, samplingMode, orientationCorrection );
98 }
99
100 Integration::ResourcePointer TizenPlatformAbstraction::LoadImageSynchronously(const Integration::BitmapResourceType& resource, const std::string& resourcePath)
101 {
102   return ImageLoader::LoadImageSynchronously( resource, resourcePath );
103 }
104
105 Integration::BitmapPtr TizenPlatformAbstraction::DecodeBuffer( const Integration::BitmapResourceType& resource, uint8_t * buffer, size_t size )
106 {
107   Integration::BitmapPtr resultBitmap;
108   Dali::Devel::PixelBuffer bitmap;
109
110   Dali::Internal::Platform::FileReader fileReader( buffer, size );
111   FILE * const fp = fileReader.GetFile();
112   if( fp )
113   {
114     bool result = ImageLoader::ConvertStreamToBitmap( resource, "", fp, bitmap );
115     if ( !result || !bitmap )
116     {
117       bitmap.Reset();
118       DALI_LOG_WARNING( "Unable to decode bitmap supplied as in-memory blob.\n" );
119     }
120     else
121     {
122       Integration::Bitmap::Profile profile{Integration::Bitmap::Profile::BITMAP_2D_PACKED_PIXELS};
123
124       // For backward compatibility the Bitmap must be created
125       auto retval = Integration::Bitmap::New(profile, Dali::ResourcePolicy::OWNED_DISCARD);
126
127       retval->GetPackedPixelsProfile()->ReserveBuffer(
128               bitmap.GetPixelFormat(),
129               bitmap.GetWidth(),
130               bitmap.GetHeight(),
131               bitmap.GetWidth(),
132               bitmap.GetHeight()
133             );
134
135       auto& impl = Dali::GetImplementation(bitmap);
136
137       std::copy( impl.GetBuffer(), impl.GetBuffer()+impl.GetBufferSize(), retval->GetBuffer());
138       resultBitmap.Reset(retval);
139     }
140   }
141
142   return resultBitmap;
143 }
144
145 bool TizenPlatformAbstraction::LoadShaderBinaryFile( const std::string& filename, Dali::Vector< unsigned char >& buffer ) const
146 {
147   bool result = false;
148
149 #ifdef SHADERBIN_CACHE_ENABLED
150   std::string path;
151
152   // First check the system location where shaders are stored at install time:
153   path = DALI_SHADERBIN_DIR;
154   path += filename;
155   result = LoadFile( path, buffer );
156
157   // Fallback to the cache of shaders stored after previous runtime compilations:
158   // On desktop this looks in the current working directory that the app was launched from.
159   if( mResourceLoader && result == false )
160   {
161     path = mDataStoragePath;
162     path += filename;
163     result = LoadFile( path, buffer );
164   }
165 #endif
166
167   return result;
168 }
169
170 bool TizenPlatformAbstraction::SaveShaderBinaryFile( const std::string& filename, const unsigned char * buffer, unsigned int numBytes ) const
171 {
172   bool result = false;
173
174 #ifdef SHADERBIN_CACHE_ENABLED
175
176   // Use the cache of shaders stored after previous runtime compilations:
177   // On desktop this looks in the current working directory that the app was launched from.
178   std::string path = mDataStoragePath;
179   path += filename;
180   result = SaveFile( path, buffer, numBytes );
181
182 #endif
183
184   return result;
185 }
186
187 void TizenPlatformAbstraction::SetDataStoragePath( const std::string& path )
188 {
189   mDataStoragePath = path;
190 }
191
192 uint32_t TizenPlatformAbstraction::StartTimer( uint32_t milliseconds, CallbackBase* callback )
193 {
194   TimerCallback* timerCallbackPtr = new TimerCallback(this, callback, milliseconds);
195
196   // Stick it in the list
197   mTimerPairsWaiting.push_back(timerCallbackPtr);
198
199   return timerCallbackPtr->mIdNumber;
200 }
201
202 void TizenPlatformAbstraction::CancelTimer ( uint32_t timerId )
203 {
204   auto iter = std::remove_if(
205     mTimerPairsWaiting.begin(), mTimerPairsWaiting.end(),
206     [&timerId]( TimerCallback* timerCallbackPtr )
207     {
208       if( timerCallbackPtr->mIdNumber == timerId )
209       {
210         timerCallbackPtr->mTimer.Stop();
211         return true;
212       }
213       else
214       {
215         return false;
216       }
217     }
218   );
219
220   mTimerPairsWaiting.erase( iter, mTimerPairsWaiting.end() );
221 }
222
223 void TizenPlatformAbstraction::RunTimerFunction(TimerCallback& timerPtr)
224 {
225   CallbackBase::Execute( *timerPtr.mCallback );
226
227   std::vector<TimerCallback*>::iterator timerIter = std::find( mTimerPairsWaiting.begin(), mTimerPairsWaiting.end(), &timerPtr );
228
229   if( timerIter == std::end(mTimerPairsWaiting) )
230   {
231     DALI_ASSERT_DEBUG(false);
232   }
233
234   // ...and move it
235   std::move(timerIter, timerIter+1, std::back_inserter(mTimerPairsSpent));
236
237   mTimerPairsWaiting.erase(timerIter, timerIter+1);
238
239   Dali::Adaptor::Get().AddIdle( MakeCallback( this, &TizenPlatformAbstraction::CleanupTimers ), false );
240 }
241
242
243 void TizenPlatformAbstraction::CleanupTimers()
244 {
245   mTimerPairsSpent.clear();
246 }
247
248
249 TizenPlatformAbstraction* CreatePlatformAbstraction()
250 {
251   return new TizenPlatformAbstraction();
252 }
253
254 bool SaveFile( const std::string& filename, const unsigned char * buffer, unsigned int numBytes )
255 {
256   DALI_ASSERT_DEBUG( 0 != filename.length());
257
258   bool result = false;
259
260   std::filebuf buf;
261   buf.open(filename.c_str(), std::ios::out | std::ios_base::trunc | std::ios::binary);
262   if( buf.is_open() )
263   {
264     std::ostream stream(&buf);
265
266     // determine size of buffer
267     int length = static_cast<int>(numBytes);
268
269     // write contents of buffer to the file
270     stream.write(reinterpret_cast<const char*>(buffer), length);
271
272     if( !stream.bad() )
273     {
274       result = true;
275     }
276   }
277
278   return result;
279 }
280
281 }  // namespace TizenPlatform
282
283 }  // namespace Dali