Merge "Added PixelBuffer for image loading and operations." into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / emscripten / sdl-application.cpp
1 // EXTERNAL INCLUDES
2 #include "sdl-application.h"
3
4 #include <SDL.h>
5 #include <SDL_image.h>
6 #include <X11/Xlib.h>
7 #include <EGL/egl.h>
8 #include <SDL_syswm.h>
9 #include <stdio.h>
10 #include <sys/select.h>
11 #include <sys/ioctl.h>
12 #include <termios.h>
13 #include <stropts.h>
14 #include <unistd.h>
15
16 #include <dali/public-api/dali-core.h>
17 #include <dali/integration-api/events/touch-event-integ.h>
18
19 // INTERNAL INCLUDES
20 #include "integration-api/egl-interface.h"
21 #include "base/separate-update-render/frame-time.h"
22 #include <gl/egl-implementation.h>
23
24 #include "platform-abstractions/emscripten/emscripten-callbacks.h"
25
26 // emscripten are using SDL version 1.3 that isnt available for download
27 // but version 2.0 is close to version 1.3 but version 1.2 support removed.
28 // This is one way it isnt.
29 #if SDL_MAJOR_VERSION == 2
30 # define VIDEO_FLAGS SDL_WINDOW_OPENGL
31 #else
32 # define VIDEO_FLAGS SDL_OPENGL
33 #endif
34
35 namespace
36 {
37
38 void LogFunction(Dali::Integration::Log::DebugPriority priority, std::string& message)
39 {
40   printf("%s", message.c_str());
41   EM_ASM( console.log( message.c_str() ) );
42 }
43
44 }
45
46 namespace Dali
47 {
48
49 typedef ::Pixmap XPixmap;
50 typedef ::Window XWindow;
51 typedef ::Display XDisplay;
52 typedef ::Screen XScreen;
53
54 const unsigned int SdlApplication::DEFAULT_SURFACE_WIDTH = 600;
55 const unsigned int SdlApplication::DEFAULT_SURFACE_HEIGHT= 480;
56
57
58 SdlApplication::SdlApplication( size_t surfaceWidth,
59                                 size_t surfaceHeight,
60                                 float  horizontalDpi,
61                                 float  verticalDpi )
62   : mCore( NULL ),
63     mSurfaceWidth( surfaceWidth ),
64     mSurfaceHeight( surfaceHeight ),
65     mFrame( 0u ),
66     mSeconds(0),
67     mMicroSeconds(0)
68 {
69
70   EGLNativeDisplayType  display        = (EGLNativeDisplayType)XOpenDisplay(NULL);
71   bool                  isOwnSurface   = true;
72   mEglImplementation.InitializeGles( display, isOwnSurface );
73
74   SdlCreateWindow(surfaceWidth, surfaceHeight, "Dali");
75
76   bool                  isWindowType      = true;
77   Dali::ColorDepth      depth             = Dali::COLOR_DEPTH_32;
78   mEglImplementation.ChooseConfig( isWindowType, depth );
79
80   EGLNativeWindowType window = NULL;
81
82   mEglImplementation.CreateSurfaceWindow( window, depth );
83
84   mEglImplementation.CreateContext();
85
86   mEglImplementation.MakeContextCurrent();
87
88   //
89   // SDL/EGL setup, now create core
90   //
91   mCore = Dali::Integration::Core::New(
92     mRenderController,
93     mPlatformAbstraction,
94     mGlAbstraction,
95     mGlSyncAbstraction,
96     mGestureManager,
97     ResourcePolicy::DataRetention::DALI_RETAINS_ALL_DATA);
98
99   mCore->ContextCreated();
100   mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
101   mCore->SetDpi( horizontalDpi, verticalDpi );
102
103   Dali::Integration::Log::InstallLogFunction( LogFunction );
104
105   mCore->SceneCreated();
106 }
107
108 SdlApplication::~SdlApplication()
109 {
110   Dali::Integration::Log::UninstallLogFunction();
111   delete mCore;
112   SDL_Quit();
113 }
114
115 void SdlApplication::SdlCreateWindow(size_t surfaceWidth,
116                                      size_t surfaceHeight,
117                                      const std::string &title)
118 {
119   if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
120   {
121     DALI_LOG_WARNING("SDL_Init Err: %s\n", SDL_GetError() );
122     DALI_ASSERT_ALWAYS(!"Couldn't initialize SDL");
123   }
124
125   // load support for the JPG and PNG image formats
126   int flags    = IMG_INIT_JPG | IMG_INIT_PNG;
127   int initted  = IMG_Init(flags);
128   if( (initted & flags) != flags)
129   {
130     DALI_LOG_WARNING("IMG_Init Err:%s\n", IMG_GetError());
131     DALI_ASSERT_ALWAYS("!IMG_Init: Failed to init required jpg and png support!\n");
132   }
133
134   float gamma      = 0.0;
135   int bpp          = 0; // 0 means current display bpp
136
137   Uint32 video_flags = VIDEO_FLAGS;
138
139   SDL_Surface *surface = SDL_SetVideoMode( static_cast<int>(surfaceWidth),
140                                            static_cast<int>(surfaceHeight),
141                                            bpp,
142                                            video_flags );
143
144   if ( surface == NULL )
145   {
146     DALI_LOG_WARNING("Couldn't set GL mode: %s\n", SDL_GetError());
147     DALI_ASSERT_ALWAYS("Couldn't set GL mode");
148     SDL_Quit();
149     exit(1);
150   }
151
152   /* Set the window manager title bar */
153   SDL_WM_SetCaption( title.c_str(), "daliweb" );
154
155   /* Set the gamma for the window */
156   if ( gamma != 0.0 )
157   {
158     SDL_SetGamma(gamma, gamma, gamma);
159   }
160
161 }
162
163 void SdlApplication::DoUpdate( void )
164 {
165   // pump events
166   mCore->ProcessEvents();
167
168   // Update Time values
169   static Internal::Adaptor::FrameTime frameTime;
170   static bool init = false;
171   if( !init )
172   {
173     frameTime.SetMinimumFrameTimeInterval( 16667 );
174     init = true;
175   }
176
177   static unsigned int frameNo = 0;
178   frameNo++;
179   frameTime.SetSyncTime(frameNo);
180
181   float lastFrameDelta( 0.0f );
182   unsigned int lastSyncTime( 0 );
183   unsigned int nextSyncTime( 0 );
184   frameTime.PredictNextSyncTime( lastFrameDelta, lastSyncTime, nextSyncTime );
185
186   Integration::UpdateStatus status;
187
188   mCore->Update( lastFrameDelta, lastSyncTime, nextSyncTime, status );
189
190   Dali::Internal::Emscripten::stats.lastFrameDeltaSeconds = lastFrameDelta;
191   Dali::Internal::Emscripten::stats.lastSyncTimeMilliseconds = lastSyncTime;
192   Dali::Internal::Emscripten::stats.nextSyncTimeMilliseconds = nextSyncTime;
193
194   Dali::Internal::Emscripten::stats.keepUpdating = status.keepUpdating;
195   Dali::Internal::Emscripten::stats.needsNotification = status.needsNotification;
196   Dali::Internal::Emscripten::stats.secondsFromLastFrame = status.secondsFromLastFrame;
197
198 }
199
200
201 void SdlApplication::DoRender()
202 {
203   // render
204   mCore->Render( mRenderStatus );
205
206   mFrame++;
207
208   Dali::Internal::Emscripten::stats.frameCount = mFrame;
209
210   mEglImplementation.SwapBuffers();
211
212 }
213
214 void SdlApplication::SendTouchEvent(double x, double y, int mouseState)
215 {
216   PointState::Type state = PointState::UP;
217   if( 0 == mouseState )
218   {
219     state = PointState::DOWN;
220   }
221   else if( 1 == mouseState )
222   {
223     state = PointState::UP;
224   }
225   else if( 2 == mouseState )
226   {
227     state = PointState::MOTION;
228   }
229
230   Dali::Integration::TouchEvent e;
231   Dali::Integration::Point point;
232   point.SetState( state );
233   point.SetScreenPosition( Vector2( static_cast<float>(x), static_cast<float>(y) ) );
234   e.AddPoint( point );
235
236   mCore->QueueEvent(e);
237 }
238
239 void SdlApplication::SetSurfaceWidth( unsigned int width, unsigned height )
240 {
241   mSurfaceWidth = width;
242   mSurfaceHeight = height;
243
244   mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
245 }
246
247 }