WindowSystem: Forced composition should also redraw HW layers
[profile/ivi/layer-management.git] / LayerManagerPlugins / Renderers / Graphic / src / WindowSystems / WaylandBaseWindowSystem.cpp
1 /***************************************************************************
2 *
3 * Copyright 2010, 2011 BMW Car IT GmbH
4 * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *        http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *
20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
21 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
24 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
25 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
26 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 *
28 ****************************************************************************/
29
30 #include "WindowSystems/WaylandBaseWindowSystem.h"
31 #include "Log.h"
32 #include "Layer.h"
33 #include <time.h>
34 #include <sys/time.h>
35 #include <sys/wait.h>
36 #include <linux/fb.h>
37 #include <fcntl.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <iomanip>
43
44 #include "WindowSystems/WaylandServerinfoServerProtocol.h"
45
46 extern "C" {
47     struct serverinfo {
48         struct wl_resource base;
49         WaylandBaseWindowSystem* windowSystem;
50     };
51
52     struct serverinfoClient {
53         struct wl_client *client;
54         uint connectionId;
55         struct wl_list link;
56     };
57
58     void WaylandBaseWindowSystem::serverinfoIFCreateConnection(struct wl_client *client, struct wl_resource *resource)
59     {
60         struct serverinfo* deliver = (struct serverinfo*)resource->data;
61
62         // creates new connection id and store it in memory
63         struct serverinfoClient* clientPair = (struct serverinfoClient*)malloc( sizeof *clientPair );
64
65         clientPair->client = client;
66         clientPair->connectionId = deliver->windowSystem->m_manageConnectionId;
67         deliver->windowSystem->m_manageConnectionId++;
68
69         wl_list_init(&clientPair->link);
70         wl_list_insert(&deliver->windowSystem->m_connectionList, &clientPair->link);
71
72         // send native client handle to this client.
73         // by protocol default, this information is not needed.
74         wl_resource_post_event(resource, SERVERINFO_CONNECTION_ID, clientPair->connectionId);
75         LOG_DEBUG("WaylandBaseWindowSystem", "serverinfoIFCreateConnection() create connection id" << clientPair->connectionId << " for client " << clientPair->client);
76     }
77
78     struct serverinfo_interface g_serverinfoImplementation = {
79         WaylandBaseWindowSystem::serverinfoIFCreateConnection,
80     };
81
82     void WaylandBaseWindowSystem::bindServerinfo(struct wl_client *client, void *data, uint32_t version, uint32_t id)
83     {
84         LOG_DEBUG("WaylandBaseWindowSystem", "bindServerinfo client:" << client << ", data:" << data << ", version:" << version << ", id:" << id);
85         wl_client_add_object(client, &serverinfo_interface, &g_serverinfoImplementation, id, data);
86     }
87
88     void WaylandBaseWindowSystem::createServerinfo(WaylandBaseWindowSystem* windowSystem)
89     {
90         struct serverinfo* serverInfo;
91
92         serverInfo = (struct serverinfo*)malloc(sizeof *serverInfo);
93         if (NULL == serverInfo){
94             LOG_ERROR("WaylandBaseWindowSystem", "failed to alloc serverinfo");
95             return;
96         }
97
98         serverInfo->base.object.interface = &serverinfo_interface;
99         serverInfo->base.object.implementation = (void(**)(void)) &g_serverinfoImplementation;
100         serverInfo->base.client = NULL;
101         serverInfo->base.data = NULL;
102         serverInfo->windowSystem = windowSystem;
103
104         m_serverInfoGlobal = wl_display_add_global(windowSystem->m_wlDisplay, &serverinfo_interface, serverInfo, WaylandBaseWindowSystem::bindServerinfo);
105         if (NULL == m_serverInfoGlobal)
106         {
107             LOG_ERROR("WaylandBaseWindowSystem", "failed wl_display_add_global");
108             free(serverInfo);
109             return;
110         }
111
112         m_serverInfo = (void*)serverInfo;
113     };
114 }
115
116 WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene)
117 : BaseWindowSystem(pScene)
118 , m_wlDisplay(NULL)
119 , m_wlDisplayClient(NULL)
120 , m_wlCompositorClient(NULL)
121 , m_wlSurfaceClient(NULL)
122 , renderThread(0)
123 , run_lock()
124 , graphicSystem(NULL)
125 , m_wlShm(NULL)
126 , m_serverInfoGlobal(NULL)
127 , m_serverInfo(NULL)
128 , m_wlCompositorGlobal(NULL)
129 , m_initialized(false)
130 , m_takeScreenshot(ScreenShotNone)
131 , m_displayname(displayname)
132 , m_success(false)
133 , m_systemState(IDLE_STATE)
134 , m_manageConnectionId(256)
135 , m_screenShotFile()
136 , m_screenShotSurfaceID(0)
137 , m_screenShotLayerID(0)
138 , m_debugMode(false)
139 , m_error(false)
140 , m_width(width)
141 , m_height(height)
142 , m_listFrameCallback()
143 , m_connectionList()
144 {
145     LOG_DEBUG("WaylandBaseWindowSystem", "creating WaylandBaseWindowSystem width:" << width << " height:" << height);
146
147     // init and take mutex, so windowsystem only does init phase until mutex is released again
148     pthread_mutex_init(&run_lock, NULL);
149     pthread_mutex_lock(&run_lock);
150 }
151
152 WaylandBaseWindowSystem::~WaylandBaseWindowSystem()
153 {
154 }
155
156 void WaylandBaseWindowSystem::printDebug()
157 {
158     // print stuff about layerlist
159     std::stringstream debugmessage;
160     debugmessage << "Layer:  ID |   X  |   Y  |   W  |   H  | Al. \n";
161
162     LayerList list = m_pScene->getCurrentRenderOrder();
163
164     // loop the layers
165     LayerListConstIterator iter = list.begin();
166     LayerListConstIterator iterEnd = list.end();
167
168     for(; iter != iterEnd; ++iter)
169     {
170         Rectangle dest = (*iter)->getDestinationRegion();
171         debugmessage << "            " << std::setw(4) << (*iter)->getID() << " " << std::setw(3) << dest.x << " " << std::setw(3) << dest.y << " " << std::setw(3) << dest.width << " " << std::setw(3) << dest.height << " " << std::setw(3) << (*iter)->opacity << "\n";
172
173         debugmessage << "    Surface:  ID |Al.|  SVP: X |  Y |  W |  H     DVP:  X |  Y |  W |  H \n";
174
175         // loop the surfaces of within each layer
176         SurfaceList surfaceList = (*iter)->getAllSurfaces();
177         SurfaceListIterator surfaceIter = surfaceList.begin();
178         SurfaceListIterator surfaceIterEnd = surfaceList.end();
179
180         for(; surfaceIter != surfaceIterEnd ; ++surfaceIter)
181         {
182             Rectangle src = (*surfaceIter)->getSourceRegion();
183             Rectangle dest = (*surfaceIter)->getDestinationRegion();
184             debugmessage << "                        " << std::setw(4) << (*surfaceIter)->getID() << " " << std::setprecision(3) << (*surfaceIter)->opacity<< " " << std::setw(3) << src.x << " " << std::setw(3) << src.y << " " << std::setw(3) << src.width << " " << std::setw(3) << src.height << " " << std::setw(3) << dest.x << " " << std::setw(3) << dest.y << " " << std::setw(3) << dest.width << " " << std::setw(3) << dest.height  << "\n";
185         }
186     }
187     LOG_DEBUG("WaylandBaseWindowSystem",debugmessage.str());
188 }
189
190 Surface* WaylandBaseWindowSystem::getSurfaceFromNativeSurface(struct native_surface* nativeSurface)
191 {
192     // go though all surfaces
193     const std::map<unsigned int,Surface*> surfaces = m_pScene->getAllSurfaces();
194     for(std::map<unsigned int, Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); ++currentS)
195     {
196         Surface* currentSurface = (*currentS).second;
197         if (!currentSurface)
198         {
199             continue;
200         }
201         WaylandPlatformSurface* nativePlatform = (WaylandPlatformSurface*)currentSurface->platform;
202         if (!nativePlatform)
203         {
204             continue;
205         }
206         if (nativePlatform->connectionId != nativeSurface->connectionId)
207         {
208             continue;
209         }
210         if (nativePlatform->surfaceId != nativeSurface->surface.resource.object.id)
211         {
212             continue;
213         }
214         return currentSurface;
215     }
216     LOG_DEBUG("WaylandBaseWindowSystem", "could not find surface for surface " << nativeSurface);
217     return NULL;
218 }
219
220 void WaylandBaseWindowSystem::checkForNewSurfaceNativeContent()
221 {
222     m_pScene->lockScene();
223     LayerList layers = m_pScene->getCurrentRenderOrder();
224     for(LayerListConstIterator current = layers.begin(); current != layers.end(); current++)
225     {
226         SurfaceList surfaces = (*current)->getAllSurfaces();
227         for(SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++)
228         {
229             if ((*currentS)->hasNativeContent())
230             {
231                 allocatePlatformSurface(*currentS);
232             }
233             else // While we are at it, also cleanup any stale native content
234             {
235                 deallocatePlatformSurface(*currentS);
236             }
237         }
238     }
239     m_pScene->unlockScene();
240 }
241
242 static struct timeval tv0;
243 static struct timeval tv0_forRender;
244
245
246 void WaylandBaseWindowSystem::calculateSurfaceFps(Surface *currentSurface, float time )
247 {
248         char floatStringBuffer[256];
249         float surfaceUpdateFps = ((float)(currentSurface->updateCounter)) / time ;
250         float surfaceDrawFps = ((float)(currentSurface->drawCounter)) / time ;
251         sprintf(floatStringBuffer, "0x%08x update fps: %3.2f", currentSurface->getID(),surfaceUpdateFps);
252         currentSurface->updateCounter = 0;
253         LOG_INFO("WaylandBaseWindowSystem", "Surface " << floatStringBuffer);
254         sprintf(floatStringBuffer, "0x%08x draw fps: %3.2f", currentSurface->getID(),surfaceDrawFps);
255         currentSurface->drawCounter = 0;
256         LOG_INFO("WaylandBaseWindowSystem", "Surface " << floatStringBuffer);
257 }
258
259 void WaylandBaseWindowSystem::calculateFps()
260 {
261     struct timeval tv;
262     float FPS = 0.0;
263     int Frame = 0;
264     float timeSinceLastCalc = 0.0;
265
266     // we have rendered a frame
267     Frame ++;
268     std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
269     // every 3 seconds, calculate & print fps
270     gettimeofday(&tv, NULL);
271     timeSinceLastCalc = (float)(tv.tv_sec-tv0.tv_sec) + 0.000001*((float)(tv.tv_usec-tv0.tv_usec));
272
273     // calculate every rendering because of event driven
274     // if (timeSinceLastCalc > 10.0f)
275     // {
276         //LOG_INFO("WaylandBaseWindowSystem", "tv.tv_sec:" << tv.tv_sec << ", tv.tv_usec:" << tv.tv_usec);
277         //LOG_INFO("WaylandBaseWindowSystem", "timeSinceLastCalc " << timeSinceLastCalc);
278         FPS = ((float)(Frame)) / timeSinceLastCalc;
279         char floatStringBuffer[256];
280         sprintf(floatStringBuffer, "Overall fps: %f", FPS);
281
282         timeSinceLastCalc = (float)(tv.tv_sec-tv0_forRender.tv_sec) + 0.000001*((float)(tv.tv_usec-tv0_forRender.tv_usec));
283         for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
284         {
285             SurfaceList surfaceList = (*current)->getAllSurfaces();
286             SurfaceListIterator surfaceIter = surfaceList.begin();
287             SurfaceListIterator surfaceIterEnd = surfaceList.end();
288             for(; surfaceIter != surfaceIterEnd ; ++surfaceIter)
289             {
290                 calculateSurfaceFps((*surfaceIter),timeSinceLastCalc);
291             }
292         }
293         LOG_INFO("WaylandBaseWindowSystem", floatStringBuffer);
294         tv0 = tv;
295         Frame = 0;
296     // }
297 }
298
299 void WaylandBaseWindowSystem::CheckRedrawAllLayers()
300 {
301     std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
302     for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
303     {
304         Layer* currentLayer = (Layer*)*current;
305         graphicSystem->beginLayer(currentLayer);
306         graphicSystem->checkRenderLayer();
307         graphicSystem->endLayer();
308     }
309 }
310
311 void WaylandBaseWindowSystem::RedrawAllLayers()
312 {
313     std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
314     bool bRedraw = m_forceComposition || m_damaged || (m_systemState == REDRAW_STATE);
315
316     // m_damaged represents that SW composition is required
317     // At this point if a layer has damaged = true then it must be a HW layer that needs update.
318     // A SW layer which needs update will make m_damaged = true
319     if (bRedraw)
320     {
321         graphicSystem->activateGraphicContext();
322 #ifndef WL_OMIT_CLEAR_GB
323         graphicSystem->clearBackground();
324 #endif /* WL_OMIT_CLEAR_GB */
325     }
326     for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
327     {
328         if ((*current)->getLayerType() == Hardware)
329         {
330             if (m_forceComposition || (*current)->damaged)
331             {
332                 renderHWLayer(*current);
333                 (*current)->damaged = false;
334             }
335         }
336         else if (bRedraw)
337         {
338             graphicSystem->beginLayer(*current);
339             graphicSystem->renderSWLayer();
340             graphicSystem->endLayer();
341         }
342     }
343     if (bRedraw)
344     {
345 #ifdef WL_LOG_DETAIL_TIMER
346         struct timeval tv_s;
347         struct timeval tv_e;
348         float timeSinceLastCalc = 0.0;
349         gettimeofday(&tv_s, NULL);
350         graphicSystem->swapBuffers();
351         gettimeofday(&tv_e, NULL);
352         timeSinceLastCalc = (float)(tv_e.tv_sec-tv_s.tv_sec) + 0.000001*((float)(tv_e.tv_usec-tv_s.tv_usec));
353         LOG_INFO("WaylandBaseWindowSystem", "swapBuffers" << timeSinceLastCalc);
354 #else
355         graphicSystem->swapBuffers();
356 #endif
357         graphicSystem->releaseGraphicContext();
358     }
359 }
360
361 void WaylandBaseWindowSystem::renderHWLayer(Layer *layer)
362 {
363     (void)layer;
364 }
365
366 void WaylandBaseWindowSystem::Redraw()
367 {
368     gettimeofday(&tv0_forRender, NULL);
369
370     // draw all the layers
371     //graphicSystem->clearBackground();
372     /*LOG_INFO("WaylandBaseWindowSystem","Locking List");*/
373     m_pScene->lockScene();
374
375     CheckRedrawAllLayers();
376     RedrawAllLayers();
377
378     m_pScene->unlockScene();
379
380     if (m_forceComposition || m_damaged || (m_systemState == REDRAW_STATE))
381     {
382         // TODO: This block won't be executed for HW only changes
383         // Is that acceptable?
384         if (m_debugMode)
385         {
386             printDebug();
387         }
388
389         calculateFps();
390
391         /* Reset the damage flag, all is up to date */
392         m_forceComposition = false;
393         m_damaged = false;
394         m_systemState = IDLE_STATE;
395     }
396 }
397
398 void WaylandBaseWindowSystem::Screenshot()
399 {
400     /*LOG_INFO("WaylandBaseWindowSystem","Locking List");*/
401     m_pScene->lockScene();
402     graphicSystem->activateGraphicContext();
403     graphicSystem->clearBackground();
404
405     if (m_takeScreenshot==ScreenshotOfDisplay)
406     {
407         LOG_DEBUG("WaylandBaseWindowSystem", "Taking screenshot");
408         std::list<Layer*> layers = m_pScene->getCurrentRenderOrder();
409
410         for(std::list<Layer*>::const_iterator current = layers.begin(); current != layers.end(); current++)
411         {
412             if ((*current)->getLayerType() != Hardware)
413             {
414                 graphicSystem->beginLayer(*current);
415                 graphicSystem->renderSWLayer();
416                 graphicSystem->endLayer();
417             }
418         }
419     }
420     else if(m_takeScreenshot==ScreenshotOfLayer)
421     {
422         LOG_DEBUG("WaylandBaseWindowSystem", "Taking screenshot of layer");
423         Layer* currentLayer = m_pScene->getLayer(m_screenShotLayerID);
424
425         if (currentLayer!=NULL){
426             graphicSystem->beginLayer(currentLayer);
427             graphicSystem->renderSWLayer();
428             graphicSystem->endLayer();
429         }
430     }
431     else if(m_takeScreenshot==ScreenshotOfSurface)
432     {
433         LOG_DEBUG("WaylandBaseWindowSystem", "Taking screenshot of surface");
434         Layer* currentLayer = m_pScene->getLayer(m_screenShotLayerID);
435         Surface* currentSurface = m_pScene->getSurface(m_screenShotSurfaceID);
436
437         if (currentLayer!=NULL && currentSurface!=NULL){
438             graphicSystem->beginLayer(currentLayer);
439             graphicSystem->renderSurface(currentSurface);
440             graphicSystem->endLayer();
441         }
442     }
443
444     graphicSystem->saveScreenShotOfFramebuffer(m_screenShotFile);
445 //  graphicSystem->swapBuffers();
446     m_takeScreenshot = ScreenShotNone;
447     LOG_DEBUG("WaylandBaseWindowSystem", "Done taking screenshot");
448
449     graphicSystem->releaseGraphicContext();
450     m_pScene->unlockScene();
451     /*LOG_INFO("WaylandBaseWindowSystem","UnLocking List");*/
452 }
453
454 void WaylandBaseWindowSystem::destroyListenerSurfaceBuffer(struct wl_listener* listener, struct wl_resource* resource, uint32_t time)
455 {
456     LOG_DEBUG("WaylandBaseWindowSystem", "destroyListenerSurfaceBuffer listener:" << listener << ", resource:" << resource << ", time:" << time);
457     struct native_surface *es = container_of(listener, struct native_surface, buffer_destroy_listener);
458
459     es->buffer = NULL;
460 }
461
462 struct native_surface* WaylandBaseWindowSystem::createNativeSurface()
463 {
464     LOG_DEBUG("WaylandBaseWindowSystem", "createNativeSurface IN");
465     struct native_surface* surface = (struct native_surface*)calloc(1, sizeof *surface);
466     if (NULL == surface)
467     {
468         LOG_ERROR("WaylandBaseWindowSystem", "failed to create native surface");
469         return NULL;
470     }
471
472     wl_list_init(&surface->link);
473     wl_list_init(&surface->buffer_link);
474
475     surface->surface.resource.client = NULL;
476
477     surface->windowSystem = this;
478     // TODO visual
479     // surface->visual = NONE_VISUAL;
480
481     surface->buffer = NULL;
482     surface->buffer_destroy_listener.func = destroyListenerSurfaceBuffer;
483
484     LOG_DEBUG("WaylandBaseWindowSystem", "createNativeSurface OUT");
485     return surface;
486 }
487
488 uint32_t WaylandBaseWindowSystem::getTime(void)
489 {
490 #ifdef WL_OMIT_GETTIME
491     return 0xF0F0F0F0;
492 #else /* WL_OMIT_GETTIME */
493     struct timeval tv;
494
495     gettimeofday(&tv, NULL);
496
497     return tv.tv_sec * 1000 + tv.tv_usec / 1000;
498 #endif /* WL_OMIT_GETTIME */
499 }
500
501 void WaylandBaseWindowSystem::destroySurfaceCallback(struct wl_resource* resource)
502 {
503     struct native_surface* nativeSurface = container_of(resource, struct native_surface, surface.resource);
504     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)nativeSurface->windowSystem);
505     Surface* ilmSurface = windowSystem->getSurfaceFromNativeSurface(nativeSurface);
506
507     if (NULL != ilmSurface)
508     {
509         if (NULL != ilmSurface->platform)
510         {
511             delete ilmSurface->platform;
512             ilmSurface->platform = NULL;
513         }
514         windowSystem->graphicSystem->getTextureBinder()->destroyClientBuffer(ilmSurface);
515     }
516
517     wl_list_remove(&nativeSurface->link);
518     wl_list_remove(&nativeSurface->buffer_link);
519
520     if (nativeSurface->buffer)
521     {
522         wl_list_remove(&nativeSurface->buffer_destroy_listener.link);
523     }
524
525     free(nativeSurface);
526 }
527
528 extern "C" void WaylandBaseWindowSystem::surfaceIFDestroy(struct wl_client *client, struct wl_resource *resource)
529 {
530     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFDestroy client:" << client << ", resource:" << resource);
531     wl_resource_destroy(resource, getTime());
532 }
533
534 void WaylandBaseWindowSystem::postReleaseBuffer(struct wl_buffer *buffer)
535 {
536     LOG_DEBUG("WaylandBaseWindowSystem", "postReleaseBufferIN");
537     if (--buffer->busy_count > 0)
538     {
539         return;
540     }
541
542     if (NULL == buffer->resource.client)
543     {
544         LOG_ERROR("WaylandBaseWindowSystem", "Release client is NULL");
545     }
546     wl_resource_queue_event(&buffer->resource, WL_BUFFER_RELEASE);
547     LOG_DEBUG("WaylandBaseWindowSystem", "postReleaseBuffer OUT");
548 }
549
550 void WaylandBaseWindowSystem::attachBufferToNativeSurface(struct wl_buffer* buffer, struct wl_surface* surface)
551 {
552     LOG_DEBUG("WaylandBaseWindowSystem", "attachBufferToNativeSurface IN");
553     struct native_surface* nativeSurface = (struct native_surface*)surface;
554     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)nativeSurface->windowSystem);
555     Surface* ilmSurface = windowSystem->getSurfaceFromNativeSurface(nativeSurface);
556     if (NULL == ilmSurface)
557     {
558         LOG_ERROR("WaylandBaseWindowSystem", "failed to get surface for wl_surface");
559         return;
560     }
561     struct wl_list* surfaces_attached_to;
562
563     ilmSurface->updateCounter++;
564     ilmSurface->removeNativeContent();
565     ilmSurface->setNativeContent((long int)buffer);
566     WaylandPlatformSurface* nativePlatformSurface = (WaylandPlatformSurface*)ilmSurface->platform;
567     if (0 != nativePlatformSurface)
568     {
569         windowSystem->graphicSystem->getTextureBinder()->createClientBuffer(ilmSurface);
570         LOG_DEBUG("WaylandBaseWindowSystem","nativePlatformSurface->enable");
571         nativePlatformSurface->enableRendering();
572     }
573
574     if (wl_buffer_is_shm(buffer))
575     {
576         LOG_DEBUG("WaylandBaseWindowSystem", "shm buffer" << buffer);
577
578         // TODO:only ARGB32.
579         //switch (wl_shm_buffer_get_format(buffer)) {
580         //case WL_SHM_FORMAT_ARGB32:
581         //es->visual = WLSC_ARGB_VISUAL;
582         //break;
583         //case WL_SHM_FORMAT_PREMULTIPLIED_ARGB32:
584         //es->visual = WLSC_PREMUL_ARGB_VISUAL;
585         //break;
586         //case WL_SHM_FORMAT_XRGB32:
587         //es->visual = WLSC_RGB_VISUAL;
588         //break;
589         //}
590
591         surfaces_attached_to = (wl_list*)buffer->user_data;
592
593         wl_list_remove(&nativeSurface->buffer_link);
594         wl_list_insert(surfaces_attached_to, &nativeSurface->buffer_link);
595     }
596     else {
597         LOG_DEBUG("WaylandBaseWindowSystem", "wl buffer");
598
599         // TODO: we need to get the visual from the wl_buffer */
600         // es->visual = WLSC_PREMUL_ARGB_VISUAL;
601         // es->pitch = es->width;
602     }
603     LOG_DEBUG("WaylandBaseWindowSystem", "attachBufferToNativeSurface OUT");
604 }
605
606 extern "C" void WaylandBaseWindowSystem::surfaceIFAttach(struct wl_client* client,
607                struct wl_resource* resource,
608                struct wl_resource* buffer_resource, int32_t x, int32_t y)
609 {
610     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFAttach client:" << client << ", resource:" << resource << ", buffer_resource:" << buffer_resource << ", x:" << x << ", y:" << y);
611     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFAttach IN");
612     struct native_surface* nativeSurface = (struct native_surface*)resource->data;
613     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)nativeSurface->windowSystem);
614     struct wl_buffer* buffer = (struct wl_buffer*)buffer_resource->data;
615
616     if (nativeSurface->buffer)
617     {
618         windowSystem->postReleaseBuffer(nativeSurface->buffer);
619         wl_list_remove(&nativeSurface->buffer_destroy_listener.link);
620     }
621
622     buffer->busy_count++;
623     nativeSurface->buffer = buffer;
624     wl_list_insert(nativeSurface->buffer->resource.destroy_listener_list.prev, &nativeSurface->buffer_destroy_listener.link);
625
626     windowSystem->attachBufferToNativeSurface(buffer, &nativeSurface->surface);
627
628     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFAttach OUT");
629 }
630
631 extern "C" void WaylandBaseWindowSystem::surfaceIFDamage(struct wl_client *client,
632                struct wl_resource *resource,
633                int32_t x, int32_t y, int32_t width, int32_t height)
634 {
635     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFDamage client:" << client << ", resource:" << resource << ", x:" << x << ", y:" << y << ", width:" << width << ", height:" << height);
636     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFDamage IN");
637     struct native_surface* nativeSurface = (struct native_surface*)resource->data;
638     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)nativeSurface->windowSystem);
639
640     Surface* surface = windowSystem->getSurfaceFromNativeSurface(nativeSurface);
641     if (NULL == surface)
642     {
643         LOG_ERROR("WaylandBaseWindowSystem", "invalid surface");
644         return;
645     }
646     surface->damaged = true;
647
648     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFDamage OUT");
649 }
650
651 extern "C" void WaylandBaseWindowSystem::destroyFrameCallback(struct wl_resource *resource)
652 {
653     struct native_frame_callback* cb = (struct native_frame_callback*)resource->data;
654
655     wl_list_remove(&cb->link);
656     free(cb);
657 }
658
659 extern "C" void WaylandBaseWindowSystem::surfaceIFFrame(struct wl_client *client,
660               struct wl_resource *resource, uint32_t callback)
661 {
662     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFFrame IN");
663     struct native_frame_callback* cb;
664     struct native_surface* es = (struct native_surface*)resource->data;
665     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)es->windowSystem);
666
667     cb = (struct native_frame_callback*)malloc(sizeof *cb);
668     if (NULL == cb)
669     {
670         wl_resource_post_no_memory(resource);
671         return;
672     }
673
674     cb->resource.object.interface = &wl_callback_interface;
675     cb->resource.object.id = callback;
676     cb->resource.destroy = destroyFrameCallback;
677     cb->resource.client = client;
678     cb->resource.data = cb;
679
680     wl_client_add_resource(client, &cb->resource);
681     wl_list_insert(windowSystem->m_listFrameCallback.prev, &cb->link);
682
683     windowSystem->checkForNewSurfaceNativeContent();
684     idleEventRepaint(windowSystem);
685
686     LOG_DEBUG("WaylandBaseWindowSystem", "surfaceIFFrame OUT");
687 }
688
689 extern "C" const struct wl_surface_interface g_surfaceInterface = {
690     WaylandBaseWindowSystem::surfaceIFDestroy,
691     WaylandBaseWindowSystem::surfaceIFAttach,
692     WaylandBaseWindowSystem::surfaceIFDamage,
693     WaylandBaseWindowSystem::surfaceIFFrame
694 };
695
696 extern "C" void WaylandBaseWindowSystem::compositorIFCreateSurface
697                 (struct wl_client *client, struct wl_resource* resource, uint32_t id)
698 {
699     LOG_DEBUG("WaylandBaseWindowSystem", "compositorIFCreateSurface IN");
700     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*) resource->data);
701     struct native_surface* surface;
702
703     surface = windowSystem->createNativeSurface();
704     if (NULL == surface)
705     {
706         wl_resource_post_no_memory(resource);
707         return;
708     }
709
710     surface->surface.resource.destroy = destroySurfaceCallback;
711     surface->windowSystem = windowSystem;
712
713     surface->surface.resource.object.id = id;
714     surface->surface.resource.object.interface = &wl_surface_interface;
715     surface->surface.resource.object.implementation = (void (**)(void))&g_surfaceInterface;
716     surface->surface.resource.data = surface;
717
718     struct serverinfoClient* serverinfoPairNode;
719
720     wl_list_for_each(serverinfoPairNode, &windowSystem->m_connectionList, link) {
721         if (serverinfoPairNode->client != client)
722         {
723             continue;
724         }
725         surface->connectionId = serverinfoPairNode->connectionId;
726         break;
727     }
728
729     windowSystem->checkForNewSurface();
730     wl_client_add_resource(client, &surface->surface.resource);
731     LOG_DEBUG("WaylandBaseWindowSystem", "compositorIFCreateSurface OUT");
732 }
733
734 const static struct wl_compositor_interface g_compositorInterface = {
735     WaylandBaseWindowSystem::compositorIFCreateSurface,
736 };
737
738 extern "C" void WaylandBaseWindowSystem::shmIFBufferCreated(struct wl_buffer *buffer)
739 {
740     LOG_DEBUG("WaylandBaseWindowSystem", "shmIFBufferCreated IN");
741     struct wl_list* surfaces_attached_to;
742
743     surfaces_attached_to = (struct wl_list*)malloc(sizeof *surfaces_attached_to);
744     if (NULL == surfaces_attached_to)
745     {
746         buffer->user_data = NULL;
747         return;
748     }
749
750     wl_list_init(surfaces_attached_to);
751
752     buffer->user_data = surfaces_attached_to;
753     LOG_DEBUG("WaylandBaseWindowSystem", "shmIFBufferCreated OUT");
754 }
755
756 extern "C" void WaylandBaseWindowSystem::shmIFBufferDamaged(struct wl_buffer* buffer, int32_t x, int32_t y, int32_t width, int32_t height)
757 {
758     LOG_DEBUG("WaylandBaseWindowSystem", "shmIFBufferDamaged buffer:" << buffer << ", x:" << x << ", y:" << y << ", width:" << width << ", height:" << height);
759 }
760
761 extern "C" void WaylandBaseWindowSystem::shmIFBufferDestroyed(struct wl_buffer *buffer)
762 {
763     LOG_DEBUG("WaylandBaseWindowSystem", "shmIFBufferDestroyed IN");
764     struct wl_list* surfaces_attached_to = (struct wl_list*)buffer->user_data;
765     struct native_surface* nativeSurface;
766     struct native_surface* next;
767
768     wl_list_for_each_safe(nativeSurface, next, surfaces_attached_to, buffer_link)
769     {
770         wl_list_remove(&nativeSurface->buffer_link);
771         wl_list_init(&nativeSurface->buffer_link);
772     }
773
774     free(surfaces_attached_to);
775     LOG_DEBUG("WaylandBaseWindowSystem", "shmIFBufferDestroyed OUT");
776 }
777
778 const static struct wl_shm_callbacks g_shmCallbacks = {
779     WaylandBaseWindowSystem::shmIFBufferCreated,
780     WaylandBaseWindowSystem::shmIFBufferDamaged,
781     WaylandBaseWindowSystem::shmIFBufferDestroyed
782 };
783
784 /**
785  * Thread in charge of the CompositorWindow eventloop
786  * Friend function of class WaylandBaseWindowSystem
787  */
788 extern "C" void* WaylandBaseWindowSystem::eventLoopCallback(void *ptr)
789 {
790     WaylandBaseWindowSystem *windowsys = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*) ptr);
791     return windowsys->eventLoop();
792 }
793
794 void WaylandBaseWindowSystem::bindCompositor(struct wl_client* client, void* data, uint32_t version, uint32_t id)
795 {
796     LOG_DEBUG("WaylandBaseWindowSystem", "bindCompositor client:" << client << ", data:" << data << ", version:" << version << ", id:" << id);
797     wl_client_add_object(client, &wl_compositor_interface, &g_compositorInterface, id, data);
798 }
799
800 void WaylandBaseWindowSystem::repaint(int msecs)
801 {
802     LOG_DEBUG("WaylandBaseWindowSystem", "repaint IN");
803     struct native_frame_callback* cb;
804     struct native_frame_callback* cnext;
805
806     Redraw();
807
808     wl_list_for_each_safe(cb, cnext, &m_listFrameCallback, link)
809     {
810         wl_resource_post_event(&cb->resource, WL_CALLBACK_DONE, msecs);
811         wl_resource_destroy(&cb->resource, 0);
812     }
813     LOG_DEBUG("WaylandBaseWindowSystem", "repaint OUT");
814 }
815
816 void WaylandBaseWindowSystem::idleEventRepaint(void *data)
817 {
818     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)data);
819     LOG_DEBUG("WaylandBaseWindowSystem", "idleEventRepaint IN");
820     windowSystem->repaint(getTime());
821     LOG_DEBUG("WaylandBaseWindowSystem", "idleEventRepaint OUT");
822 }
823
824 bool WaylandBaseWindowSystem::initCompositor()
825 {
826     LOG_DEBUG("WaylandBaseWindowSystem", "initCompositor START");
827
828     m_wlCompositorGlobal = wl_display_add_global(m_wlDisplay, &wl_compositor_interface, this, bindCompositor);
829     if (NULL == m_wlCompositorGlobal)
830     {
831         LOG_ERROR("WaylandBaseWindowSystem", "wl_display_add_global:failed to set wl_compositor_interface");
832         return false;
833     }
834     LOG_DEBUG("WaylandBaseWindowSystem", "wl_display_add_global:SUCCESS");
835
836     m_wlShm = wl_shm_init(m_wlDisplay, &g_shmCallbacks);
837     if (NULL == m_wlShm)
838     {
839         LOG_ERROR("WaylandBaseWindowSystem", "failed to init wl_shm");
840         return false;
841     }
842
843     wl_list_init(&m_listFrameCallback);
844
845     wl_list_init(&m_connectionList);
846     createServerinfo(this);
847
848     LOG_DEBUG("WaylandBaseWindowSystem", "initCompositor END");
849     return true;
850 }
851
852 void WaylandBaseWindowSystem::shutdownCompositor()
853 {
854     if (NULL != m_serverInfoGlobal)
855     {
856         wl_display_remove_global(m_wlDisplay, m_serverInfoGlobal);
857         m_serverInfoGlobal = NULL;
858     }
859     if (NULL != m_serverInfo)
860     {
861         free(m_serverInfo);
862         m_serverInfo = NULL;
863     }
864     if (NULL != m_wlShm)
865     {
866         wl_shm_finish(m_wlShm);
867         m_wlShm = NULL;
868     }
869     if (NULL != m_wlCompositorGlobal)
870     {
871         wl_display_remove_global(m_wlDisplay, m_wlCompositorGlobal);
872         m_wlCompositorGlobal = NULL;
873     }
874 }
875
876 void WaylandBaseWindowSystem::wakeUpRendererThread()
877 {
878 }
879
880 int WaylandBaseWindowSystem::signalEventOnTerm(int signal_number, void *data)
881 {
882     WaylandBaseWindowSystem* windowSystem = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*)data);
883
884     LOG_INFO("WaylandBaseWindowSystem", "caught signal " << signal_number);
885     windowSystem->cleanup();
886
887     return 1;
888 }
889
890 void* WaylandBaseWindowSystem::eventLoop()
891 {
892     // INITALIZATION
893     LOG_DEBUG("WaylandBaseWindowSystem", "Enter thread");
894
895     bool status = true;
896     struct wl_event_loop *loop;
897
898     do
899     {
900         m_wlDisplay = wl_display_create();
901
902         if (NULL == m_wlDisplay)
903         {
904             LOG_ERROR("WaylandBaseWindowSystem", "failed to create wayland display");
905             break;
906         }
907         LOG_DEBUG("WaylandBaseWindowSystem", "create wayland display");
908
909         loop = wl_display_get_event_loop(m_wlDisplay);
910         wl_event_loop_add_signal(loop, SIGTERM, signalEventOnTerm, this);
911         wl_event_loop_add_signal(loop, SIGINT, signalEventOnTerm, this);
912         wl_event_loop_add_signal(loop, SIGQUIT, signalEventOnTerm, this);
913         wl_event_loop_add_signal(loop, SIGKILL, signalEventOnTerm, this);
914
915         LOG_DEBUG("WaylandBaseWindowSystem", "wl_event_loop_add_signal");
916
917         status = this->initCompositor();
918         if (false == status)
919         {
920             LOG_ERROR("WaylandBaseWindowSystem", "failed to init compositor");
921             break;
922         }
923         LOG_DEBUG("WaylandBaseWindowSystem", "SUCCESS:initCompositor");
924
925         //. create Native Context
926         status = createNativeContext();
927         if (false == status)
928         {
929             LOG_ERROR("WaylandBaseWindowSystem", "failed to create Native context");
930             break;
931         }
932         LOG_DEBUG("WaylandBaseWindowSystem", "SUCCESS:createNativeContext");
933
934         //. create egl context
935         status = initGraphicSystem();
936         if (false == status)
937         {
938             LOG_ERROR("WaylandBaseWindowSystem", "failed to init graphicSystem");
939             break;
940         }
941         LOG_DEBUG("WaylandBaseWindowSystem", "SUCCESS:init GraphicSystem");
942
943         this->m_success = status;
944         this->m_initialized = true;
945
946         // Done with init, wait for lock to actually run (ie start/stop method called)
947         pthread_mutex_lock(&this->run_lock);
948
949         LOG_DEBUG("WaylandBaseWindowSystem", "Starting Event loop");
950
951         // run the main event loop while rendering
952         gettimeofday(&tv0, NULL);
953         LOG_DEBUG("WaylandBaseWindowSystem", "Enter render loop");
954
955         // clear screen to avoid garbage on startup
956         this->graphicSystem->clearBackground();
957         this->graphicSystem->swapBuffers();
958
959         if (wl_display_add_socket(m_wlDisplay, NULL))
960         {
961             LOG_ERROR("WaylandBaseWindowSystem", "failed to add socket");
962                 this->m_success = false;
963                 this->m_initialized = false;
964                 break;
965         }
966
967         wl_display_run(m_wlDisplay);
968
969     } while(0);
970
971     this->cleanup();
972     LOG_DEBUG("WaylandBaseWindowSystem", "Renderer thread finished");
973     return NULL;
974 }
975
976 extern "C" void WaylandBaseWindowSystem::surfaceListenerFrame(void* data, struct wl_callback* callback, uint32_t time)
977 {
978     data = data; // TODO:to avoid warning
979     time = time; // TODO:to avoid warining
980     if (callback)
981     {
982         wl_callback_destroy(callback);
983     }
984 }
985
986 extern "C" const struct wl_callback_listener g_frameListener = {
987     WaylandBaseWindowSystem::surfaceListenerFrame
988 };
989
990 void WaylandBaseWindowSystem::signalRedrawEvent()
991 {
992     LOG_DEBUG("WaylandBaseWindowSystem", "signalRedrawEvent");
993     // set flag that redraw is needed
994     this->m_systemState = REDRAW_STATE;
995
996     struct wl_callback* callback = wl_surface_frame(m_wlSurfaceClient);
997     wl_callback_add_listener(callback, &g_frameListener, NULL);
998     wl_display_flush(m_wlDisplayClient);
999 }
1000
1001 void WaylandBaseWindowSystem::cleanup()
1002 {
1003     LOG_DEBUG("WaylandBaseWindowSystem", "Cleanup");
1004
1005     shutdownCompositor();
1006
1007     if (NULL != m_wlDisplay)
1008     {
1009         wl_display_terminate(m_wlDisplay);
1010         m_wlDisplay = NULL;
1011     }
1012 }
1013
1014 extern "C" void WaylandBaseWindowSystem::bindDisplayClient(struct wl_display* display, uint32_t id, const char* interface, uint32_t version, void* data)
1015 {
1016     LOG_DEBUG("WaylandBaseWindowSystem", "version " << version);
1017     WaylandBaseWindowSystem* windowsys = static_cast<WaylandBaseWindowSystem*>( (WaylandBaseWindowSystem*) data);
1018     int ans_strcmp = 0;
1019
1020     do
1021     {
1022         ans_strcmp = strcmp(interface, "wl_compositor");
1023         if (0 == ans_strcmp)
1024         {
1025             windowsys->m_wlCompositorClient = (wl_compositor*)wl_display_bind(display, id, &wl_compositor_interface);
1026             break;
1027         }
1028     } while(0);
1029 }
1030
1031 bool WaylandBaseWindowSystem::createWaylandClient()
1032 {
1033     do
1034     {
1035         while (NULL == m_wlDisplayClient)
1036         {
1037             usleep(10000);
1038             LOG_DEBUG("WaylandBaseWindowSystem", "Waiting start wayland server");
1039
1040             m_wlDisplayClient = wl_display_connect(NULL);
1041         }
1042
1043         LOG_DEBUG("WaylandBaseWindowSystem", "connect display");
1044
1045         m_wlCompositorGlobalListener = wl_display_add_global_listener(m_wlDisplayClient, WaylandBaseWindowSystem::bindDisplayClient, this);
1046         if (NULL == m_wlCompositorGlobalListener)
1047         {
1048             LOG_ERROR("WaylandBaseWindowSystem", "Waiting start wayland server");
1049             break;
1050         }
1051         wl_display_iterate(m_wlDisplayClient, WL_DISPLAY_READABLE);
1052         wl_display_roundtrip(m_wlDisplayClient);
1053
1054         m_wlSurfaceClient = wl_compositor_create_surface(m_wlCompositorClient);
1055         if (NULL == m_wlSurfaceClient)
1056         {
1057             LOG_ERROR("WaylandBaseWindowSystem", "failed to create client surface");
1058             break;
1059         }
1060         LOG_DEBUG("WaylandBaseWindowSystem", "create client surface");
1061
1062         return true;
1063     } while(0);
1064
1065     releaseWaylandClient();
1066
1067     return false;
1068 }
1069
1070 void WaylandBaseWindowSystem::releaseWaylandClient()
1071 {
1072     if (NULL != m_wlSurfaceClient)
1073     {
1074         wl_surface_destroy(m_wlSurfaceClient);
1075         m_wlSurfaceClient = NULL;
1076     }
1077     if (NULL != m_wlCompositorClient)
1078     {
1079         wl_compositor_destroy(m_wlCompositorClient);
1080         m_wlCompositorClient = NULL;
1081     }
1082     if (NULL != m_wlDisplayClient)
1083     {
1084 #if 0 // will add wayland version more than 0.85.0
1085         wl_display_disconnect(m_wlDisplayClient);
1086 #endif
1087         m_wlDisplayClient = NULL;
1088     }
1089 }
1090
1091 bool WaylandBaseWindowSystem::init(BaseGraphicSystem<void*, void*>* base)
1092 {
1093     LOG_DEBUG("WaylandBaseWindowSystem", "init base:" << base);
1094     graphicSystem = base;
1095     int status = pthread_create(&renderThread, NULL, eventLoopCallback, (void*)this);
1096     if (0 != status)
1097     {
1098         return false;
1099     }
1100
1101     while (false == m_initialized)
1102     {
1103         usleep(10000); // TODO
1104         LOG_DEBUG("WaylandBaseWindowSystem","Waiting start compositor complete " << m_initialized);
1105     }
1106     LOG_INFO("WaylandBaseWindowSystem","Start complete [connect display]" << m_initialized << " success " << m_success);
1107     return m_success;
1108 }
1109
1110 bool WaylandBaseWindowSystem::start()
1111 {
1112     bool result = true;
1113     LOG_DEBUG("WaylandBaseWindowSystem", "Starting / Creating thread");
1114     // let thread actually run
1115     if ( m_error == false )
1116     {
1117         pthread_mutex_unlock(&run_lock);
1118     } else {
1119         pthread_mutex_unlock(&run_lock);
1120         result = false;
1121     }
1122
1123     result = createWaylandClient();
1124     if (false == result)
1125     {
1126         LOG_DEBUG("WaylandBaseWindowSystem", "Failed to create wayland client");
1127     }
1128
1129     return result;
1130 }
1131
1132 void WaylandBaseWindowSystem::stop()
1133 {
1134     LOG_INFO("WaylandBaseWindowSystem","Stopping..");
1135     // needed if start was never called, we wake up thread, so it can immediatly finish
1136     // this->signalRedrawEvent();
1137
1138     releaseWaylandClient();
1139
1140     pthread_mutex_unlock(&run_lock);
1141     pthread_join(renderThread, NULL);
1142 }
1143
1144 void WaylandBaseWindowSystem::allocatePlatformSurface(Surface* surface)
1145 {
1146     LOG_INFO("WaylandBaseWindowSystem","allocatePlatformSurface begin");
1147     WaylandPlatformSurface* nativeSurface = (WaylandPlatformSurface*)surface->platform;
1148     if (!nativeSurface)
1149     {
1150         LOG_DEBUG("WaylandBaseWindowSystem","creating native surface for new window");
1151         // this surface does not have a native platform surface attached yet!
1152         nativeSurface = (WaylandPlatformSurface*)graphicSystem->getTextureBinder()->createPlatformSurface(surface);
1153         if (0 != nativeSurface)
1154         {
1155             unsigned int surfaceId = surface->getNativeContent();
1156             LOG_DEBUG("WaylandBaseWindowSystem","surface->getNativeContent()"<<surfaceId);
1157             nativeSurface->connectionId = (unsigned short)((surfaceId >> 16) & 0xFFFF);
1158             nativeSurface->surfaceId = (unsigned short)(surfaceId & 0xFFFF);
1159             surface->platform = nativeSurface;
1160         }
1161         else
1162         {
1163             LOG_ERROR("WaylandBaseWindowSystem","failed to allocate platformsurface");
1164         }
1165     }
1166     LOG_INFO("WaylandBaseWindowSystem","allocatePlatformSurface end");
1167 }
1168
1169 void WaylandBaseWindowSystem::deallocatePlatformSurface(Surface* surface)
1170 {
1171     LOG_DEBUG("WaylandBaseWindowSystem","deallocatePlatformSurface begin");
1172     WaylandPlatformSurface* nativeSurface = (WaylandPlatformSurface*)surface->platform;
1173     if (nativeSurface)
1174     {
1175         LOG_DEBUG("WaylandBaseWindowSystem","destroyingnative surface");
1176 #if 0 // TODO
1177         graphicSystem->getTextureBinder()->destroyClientBuffer(surface);
1178
1179         surface->renderPropertyChanged = true;
1180         delete surface->platform;
1181         surface->platform = NULL;
1182 #endif
1183     }
1184     LOG_DEBUG("WaylandBaseWindowSystem","deallocatePlatformSurface end");
1185 }
1186
1187 void WaylandBaseWindowSystem::doScreenShot(std::string fileName)
1188 {
1189     m_takeScreenshot = ScreenshotOfDisplay;
1190     m_screenShotFile = fileName;
1191 }
1192
1193 void WaylandBaseWindowSystem::doScreenShotOfLayer(std::string fileName, const uint id)
1194 {
1195     m_takeScreenshot = ScreenshotOfLayer;
1196     m_screenShotFile = fileName;
1197     m_screenShotLayerID = id;
1198 }
1199
1200 void WaylandBaseWindowSystem::doScreenShotOfSurface(std::string fileName, const uint id, const uint layer_id)
1201 {
1202     m_takeScreenshot = ScreenshotOfSurface;
1203     m_screenShotFile = fileName;
1204     m_screenShotSurfaceID = id;
1205     m_screenShotLayerID = layer_id;
1206 }