Support post render callback
[platform/core/uifw/pepper-dali.git] / pepper-dali / internal / object-impl.cpp
1 /*
2  * Copyright (c) 2016 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 <pepper-dali/internal/object-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <pepper-dali/internal/shell-client-impl.h>
23 #include <pepper-dali/internal/object-view-impl.h>
24
25 // EXTERNAL INCLUDES
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/images/buffer-image.h>
28 #include <dali/public-api/events/touch-event.h>
29 #include <dali/public-api/adaptor-framework/native-image-source.h>
30 #include <wayland-tbm-server.h>
31
32 namespace Dali
33 {
34
35 namespace Pepper
36 {
37
38 namespace Internal
39 {
40
41 namespace
42 {
43
44 #if defined(DEBUG_ENABLED)
45 Integration::Log::Filter* gPepperObjectLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_OBJECT" );
46 #endif
47
48 } // unnamed namespace
49
50 ObjectPtr Object::New( pepper_surface_t* surface, Pepper::Input input )
51 {
52   ObjectPtr impl = new Object();
53
54   // Second-phase init of the implementation
55   impl->Initialize( surface, input );
56
57   return impl;
58 }
59
60 Object::Object()
61 : mSurface( NULL ),
62   mBuffer( NULL ),
63   mPointer( NULL ),
64   mKeyboard( NULL ),
65   mTouch( NULL ),
66   mShmBuffer( NULL ),
67   mTbmSurface( 0 ),
68   mSurfaceDestroyListener( NULL ),
69   mBufferDestroyListener( NULL ),
70   mWidth( 0 ),
71   mHeight( 0 )
72 {
73 }
74
75 Object::~Object()
76 {
77   if( mBuffer )
78   {
79     pepper_buffer_unreference( mBuffer );
80     pepper_event_listener_remove( mBufferDestroyListener );
81   }
82
83   if( mSurfaceDestroyListener )
84   {
85     pepper_event_listener_remove( mSurfaceDestroyListener );
86   }
87 }
88
89 void Object::Initialize( pepper_surface_t* surface, Pepper::Input input )
90 {
91   mSurface = surface;
92
93   mPointer = input.GetPointer();
94   mKeyboard = input.GetKeyboard();
95   mTouch = input.GetTouch();
96
97   mSurfaceDestroyListener = pepper_object_add_event_listener( (pepper_object_t*)surface, PEPPER_EVENT_OBJECT_DESTROY, 0, Object::OnDestroySurface, this );
98
99   DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::Initialize: success\n" );
100 }
101
102 bool Object::AttchBuffer( int* width, int* height )
103 {
104   pepper_buffer_t* buffer;
105   wl_resource* bufferResource;
106   wl_shm_buffer* shmBuffer = NULL;
107   tbm_surface_h tbmSurface = NULL;
108   int bufWidth, bufHeight;
109
110   buffer = pepper_surface_get_buffer( mSurface );
111   if( !buffer )
112   {
113     DALI_LOG_INFO( gPepperObjectLogging, Debug::General, "Object::AttchBuffer: pepper_surface_get_buffer is failed\n" );
114     return false;
115   }
116
117   if( mBuffer )
118   {
119     pepper_buffer_unreference( mBuffer );
120     pepper_event_listener_remove( mBufferDestroyListener );
121   }
122
123   pepper_buffer_reference( buffer );
124
125   mBuffer = buffer;
126   mBufferDestroyListener = pepper_object_add_event_listener( (pepper_object_t*)buffer, PEPPER_EVENT_OBJECT_DESTROY, 0, Object::OnDestroyBuffer, this );
127
128   if( !mObjectView )
129   {
130     mObjectView = Pepper::ObjectView::New();
131
132     // Set surface and input modules
133     Pepper::GetImplementation( mObjectView ).SetSurface( mSurface );
134     Pepper::GetImplementation( mObjectView ).SetInput( mPointer, mKeyboard, mTouch );
135
136     Pepper::Object handle( this );
137     mObjectViewAddedSignal.Emit( handle, mObjectView );
138   }
139
140   bufferResource = pepper_buffer_get_resource( buffer );
141
142   shmBuffer = wl_shm_buffer_get( bufferResource );
143   if( shmBuffer )
144   {
145     bufWidth = wl_shm_buffer_get_width( shmBuffer );
146     bufHeight = wl_shm_buffer_get_height( shmBuffer );
147
148     if( shmBuffer != mShmBuffer )
149     {
150       // create a new image
151       PixelBuffer* pixelBuffer = static_cast< PixelBuffer* >( wl_shm_buffer_get_data( shmBuffer ) );
152       mBufferImage = BufferImage::New( pixelBuffer, bufWidth, bufHeight );
153
154       mObjectView.SetImage( mBufferImage );
155
156       mShmBuffer = shmBuffer;
157     }
158   }
159   else
160   {
161     tbmSurface = wayland_tbm_server_get_surface( NULL, bufferResource );
162     if( tbmSurface )
163     {
164       bufWidth = tbm_surface_get_width( tbmSurface );
165       bufHeight = tbm_surface_get_height( tbmSurface );
166
167       if ( tbmSurface != mTbmSurface )
168       {
169         // create a new image
170         NativeImageSourcePtr nativeImageSource = NativeImageSource::New( tbmSurface );
171         mNativeImage = NativeImage::New( *nativeImageSource );
172
173         mObjectView.SetImage( mNativeImage );
174
175         mTbmSurface = tbmSurface;
176       }
177     }
178     else
179     {
180       DALI_LOG_INFO( gPepperObjectLogging, Debug::General, "Object::AttchBuffer: Failed to get buffer\n" );
181       return false;
182     }
183   }
184
185   if( ( mWidth != bufWidth ) || ( mHeight != bufHeight ) )
186   {
187     mWidth = bufWidth;
188     mHeight = bufHeight;
189
190     // resize actor
191     mObjectView.SetSize( mWidth, mHeight );
192   }
193
194   if( width )
195   {
196     *width = bufWidth;
197   }
198
199   if( height )
200   {
201     *height = bufHeight;
202   }
203
204   DALI_LOG_INFO( gPepperObjectLogging, Debug::Verbose, "Object::AttchBuffer: this = %p, width = %d, height = %d", this, bufWidth, bufHeight );
205
206   return true;
207 }
208
209 Pepper::Object::ObjectSignalType& Object::ObjectViewAddedSignal()
210 {
211   return mObjectViewAddedSignal;
212 }
213
214 Pepper::Object::ObjectSignalType& Object::ObjectViewDeletedSignal()
215 {
216   return mObjectViewDeletedSignal;
217 }
218
219 void Object::OnDestroySurface( pepper_event_listener_t* listener, pepper_object_t* pepperObject, uint32_t id, void* info, void* data )
220 {
221   Object* object = static_cast< Object* >( data );
222
223   Pepper::Object handle( object );
224   object->mObjectViewDeletedSignal.Emit( handle, object->mObjectView );
225
226   object->mSurface = NULL;
227   object->mTbmSurface = NULL;
228
229   if( object->mSurfaceDestroyListener )
230   {
231     pepper_event_listener_remove( object->mSurfaceDestroyListener );
232   }
233 }
234
235 void Object::OnDestroyBuffer( pepper_event_listener_t* listener, pepper_object_t* pepperObject, uint32_t id, void* info, void* data )
236 {
237   Object* object = static_cast< Object* >( data );
238
239   if( object->mBuffer )
240   {
241     pepper_buffer_unreference( object->mBuffer );
242     pepper_event_listener_remove( object->mBufferDestroyListener );
243   }
244
245 #if 0
246   if( object->mShmBuffer )
247   {
248     void* shmData = wl_shm_buffer_get_data( object->mShmBuffer );
249
250     object->mBufferImage = BufferImage::New( object->mWidth, object->mHeight );
251
252     PixelBuffer* buffer = object->mBufferImage.GetBuffer();
253     memcpy(buffer, shmData, object->mWidth * object->mHeight * 4);
254
255     object->mBufferImage.Update();
256
257     object->mObjectView.SetImage( object->mBufferImage );
258   }
259   else if( object->mTbmSurface )
260   {
261   }
262 #endif
263 }
264
265 } // namespace Internal
266
267 } // namespace Pepper
268
269 } // namespace Dali