Apply gem
[platform/framework/native/shell.git] / src / FShell_AppWidgetLayer.cpp
index fe61a42..6cf36a5 100644 (file)
@@ -34,6 +34,7 @@
 #include <FBase_StringConverter.h>
 #include <FGrpRectangle.h>
 #include "FUi_Window.h"
+#include "FShell_AppWidgetBuffer.h"
 #include "FShell_AppWidgetLayer.h"
 #include "FShell_AppWidgetProviderManagerImpl.h"
 
@@ -85,21 +86,24 @@ PostRender(void* pData, Evas* pEvas, void* pEventInfo)
 namespace Tizen { namespace Shell
 {
 
-_AppWidgetLayer::_AppWidgetLayer(const FloatDimension& size)
+_AppWidgetLayer::_AppWidgetLayer(const Tizen::Base::String& providerId, const FloatDimension& size)
        : __isReleased(false)
        , __size(size)
        , __pEcoreEvas(null)
        , __pEvasObject(null)
-       , __providerId(L"")
+       , __providerId(providerId)
        , __pRenderBuffer(null)
+       , __pTempBuffer(null)
        , __bufferSize(0)
        , __pixmapId(-1)
+       , __pAppWidgetBuffer(new (std::nothrow) _AppWidgetBuffer)
 {
 }
 
 _AppWidgetLayer::~_AppWidgetLayer(void)
 {
        __pRenderBuffer = null;
+       __pTempBuffer = null;
        __pixmapId = -1;
 }
 
@@ -108,6 +112,8 @@ _AppWidgetLayer::OnConstructed(void)
 {
        result r = E_SUCCESS;
 
+       __pAppWidgetBuffer->Initialize();
+
        unique_ptr<Ecore_Evas, _EcoreEvasDeleter> pEcoreEvas(ecore_evas_buffer_allocfunc_new(__size.width, __size.height, AllocRenderBuffer, FreeRenderBuffer, this));
        SysTryReturn(NID_SHELL, pEcoreEvas, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
 
@@ -136,6 +142,12 @@ _AppWidgetLayer::OnConstructed(void)
        ecore_evas_alpha_set(__pEcoreEvas.get(), EINA_TRUE);
        evas_object_color_set(__pEvasObject.get(), 0, 0, 0, 0);
 
+       if (!__providerId.IsEmpty())
+       {
+               r = RegisterTouchEventListener();
+               SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
+       }
+
        return r;
 }
 
@@ -174,7 +186,6 @@ _AppWidgetLayer::SetLayerBounds(const FloatRectangle& bounds)
 
        ecore_evas_resize(__pEcoreEvas.get(), __size.width, __size.height);
 
-//     FloatRectangle fBounds(static_cast<float>(bounds.x), static_cast<float>(bounds.y), static_cast<float>(bounds.width), static_cast<float>(bounds.height));
        SetBounds(bounds);
 }
 
@@ -184,30 +195,57 @@ _AppWidgetLayer::AllocCanvas(int size)
        SysTryReturn(NID_SHELL, size > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
 
        __bufferSize = size;
-       void* pBuffer =  malloc(__bufferSize);
-       SysTryReturn(NID_SHELL, pBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
+       void* pBuffer = null;
+
+       if (__providerId.IsEmpty())
+       {
+               __pTempBuffer =  malloc(__bufferSize);\r
+               SysTryReturn(NID_SHELL, __pTempBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");\r
+               \r
+               pBuffer = __pTempBuffer;\r
+       }\r
+       else\r
+       {
+               if (__pixmapId == -1)
+               {
+                       __pixmapId = AcquirePixmap();
+                       SysTryReturn(NID_SHELL, __pixmapId != -1, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
+               }
 
-       __pRenderBuffer = pBuffer;
+               __pRenderBuffer = __pAppWidgetBuffer->AllocBuffer(__pixmapId, __size);
+               pBuffer = __pRenderBuffer;
+               __pAppWidgetBuffer->UnlockBuffer();
+       }
 
-       SysLog(NID_SHELL, "buffer (0x%x) size (%d)", pBuffer, __bufferSize);
+       SysLog(NID_SHELL, "buffer (0x%x 0x%x) size (%d) pixmap (%d)", __pTempBuffer, __pRenderBuffer, __bufferSize, __pixmapId);
 
        __isReleased = false;
 
-       return __pRenderBuffer;
+       return pBuffer;
 }
 
 void
 _AppWidgetLayer::FreeCanvas(void* pCanvas)
 {
-       if (!__isReleased)
+       SysLog(NID_SHELL, "buffer (0x%x 0x%x 0x%x) size (%d)", __pTempBuffer, __pRenderBuffer, pCanvas, __bufferSize);
+
+       if (__pTempBuffer)
        {
-               ReleasePixmap();
-               __isReleased = true;
+               free(__pTempBuffer);
+               __pTempBuffer = null;
+       }
+       else
+       {
+               if (__pAppWidgetBuffer)
+               {
+                       __pAppWidgetBuffer->DeallocBuffer();
+               }
        }
 
-       if (pCanvas)
+       if (!__isReleased)
        {
-               free(pCanvas);
+               ReleasePixmap();
+               __isReleased = true;
        }
 
        __pixmapId = -1;
@@ -218,122 +256,32 @@ result
 _AppWidgetLayer::SyncPixmap(const FloatDimension& size)
 {
        SysTryReturn(NID_SHELL, __pRenderBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
+       SysTryReturn(NID_SHELL, __pAppWidgetBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
 
        SysLog(NID_SHELL, "buffer (0x%x) size (%d) pixmapId (%d) width(%f) height(%f)", __pRenderBuffer, __bufferSize, __pixmapId, size.width, size.height);
 
-       Display* pDisplay = static_cast<Display*>(ecore_x_display_get());
-       SysTryReturn(NID_SHELL, pDisplay, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       result r = E_SUCCESS;
-       XShmSegmentInfo xShmSegmentInfo;
-       xShmSegmentInfo.shmseg = 0;
-
-       XImage* pXImage = null;
-       GC gc;
-       Screen* pScreen = null;
-       Visual* pVisual = null;
-
-       xShmSegmentInfo.shmid = shmget(IPC_PRIVATE, __bufferSize, IPC_CREAT | 0666);
-       SysTryReturn(NID_SHELL,  xShmSegmentInfo.shmid >= 0, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       xShmSegmentInfo.readOnly = False;
-       xShmSegmentInfo.shmaddr = static_cast<char*>(shmat(xShmSegmentInfo.shmid, null, 0));
-       SysTryCatch(NID_SHELL, xShmSegmentInfo.shmaddr != (void *)-1, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       pScreen = DefaultScreenOfDisplay(pDisplay);
-       SysTryCatch(NID_SHELL, pScreen, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       pVisual = DefaultVisualOfScreen(pScreen);
-       SysTryCatch(NID_SHELL, pVisual, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       pXImage = XShmCreateImage(pDisplay, pVisual, 32, ZPixmap, null, &xShmSegmentInfo, size.width, size.height);
-       SysTryCatch(NID_SHELL, pXImage, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       pXImage->data = xShmSegmentInfo.shmaddr;
-       XShmAttach(pDisplay, &xShmSegmentInfo);
-       XSync(pDisplay, False);
-
-       gc = XCreateGC(pDisplay, static_cast<Pixmap>(__pixmapId), 0, null);
-       SysTryCatch(NID_SHELL, gc, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-
-       memcpy(pXImage->data, __pRenderBuffer, __bufferSize);
-
-#if defined(_BUFFER_TEST)
-       {
-               FILE* pFile = null;
-               static int idx = 0;
-               char filename[1024];
-               snprintf(filename, sizeof(filename), "/tmp/provider%d.raw", idx++);
-               pFile = fopen(filename, "w+b");
-               if (pFile)
-               {
-                       fwrite(__pRenderBuffer, __bufferSize, 1, pFile);
-                       fclose(pFile);
-                       SysLog(NID_SHELL, "_BUFFER_TEST: buffer (0x%x) size (%d) pixmapId (%d) width(%f) height(%f)", __pRenderBuffer, __bufferSize, __pixmapId, size.width, size.height);
-               }
-               else
-               {
-                       SysLog(NID_SHELL, "File open failed: (%s) buffer (0x%x) size (%d) pixmapId (%d)", strerror(errno), __pRenderBuffer, __bufferSize, __pixmapId);
-               }
-       }
-#endif // _BUFFER_TEST
-
-       // Do not send the event. Instead of X event, master will send the updated event to the viewer
-       XShmPutImage(pDisplay, static_cast<Pixmap>(__pixmapId), gc, pXImage, 0, 0, 0, 0, size.width, size.height, False);
-       XSync(pDisplay, False);
-
-       XFreeGC(pDisplay, gc);
-       XShmDetach(pDisplay, &xShmSegmentInfo);
-       XDestroyImage(pXImage);
-
-       if (xShmSegmentInfo.shmaddr != (void *)-1)
-       {
-               shmdt(xShmSegmentInfo.shmaddr);
-       }
-
-       if (xShmSegmentInfo.shmid >= 0)
-       {
-               shmctl(xShmSegmentInfo.shmid, IPC_RMID, 0);
-       }
-
-       return r;
-
-CATCH:
-
-       if (pDisplay)
-       {
-               XShmDetach(pDisplay, &xShmSegmentInfo);
-       }
-
-       if (pXImage)
-       {
-               XDestroyImage(pXImage);
-       }
+       XShmPutImage(__pAppWidgetBuffer->GetDisplay(), static_cast<Pixmap>(__pixmapId), __pAppWidgetBuffer->GetGc(), __pAppWidgetBuffer->GetXImage(), 0, 0, 0, 0, size.width, size.height, False);
+       XSync(__pAppWidgetBuffer->GetDisplay(), False);
 
-       if (xShmSegmentInfo.shmaddr != (void *)-1)
-       {
-               shmdt(xShmSegmentInfo.shmaddr);
-       }
-
-       if (xShmSegmentInfo.shmid >= 0)
-       {
-               shmctl(xShmSegmentInfo.shmid, IPC_RMID, 0);
-       }
-
-       return E_OUT_OF_MEMORY;
+       return E_SUCCESS;
 }
 
 void
 _AppWidgetLayer::OnRendered(void)
 {
-       if (__pixmapId == -1)
+       result r = E_SUCCESS;
+
+       if (!__pAppWidgetBuffer->IsGemBufferEnabled())
        {
-               __pixmapId = AcquirePixmap();
-               SysTryReturnVoidResult(NID_SHELL, __pixmapId >= 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
-       }
+               if (__pixmapId == -1)
+               {
+                       __pixmapId = AcquirePixmap();
+                       SysTryReturnVoidResult(NID_SHELL, __pixmapId >= 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
+               }
 
-       result r = SyncPixmap(__size);
-       SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
+               r = SyncPixmap(__size);
+               SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
+       }
 
        r = Sync(__size);
        SysTryReturnVoidResult(NID_SHELL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
@@ -430,11 +378,20 @@ _AppWidgetLayer::Flush(void)
 {
        SysLog(NID_SHELL, "ENTER");
 
+       bool needed = IsFlushNeeded();
+
+       if (needed)
+       {
+               __pAppWidgetBuffer->LockBuffer();
+       }
+
        _EflLayer::Flush();
 
-       if (IsFlushNeeded())
+       if (needed)
        {
                OnRendered();
+
+               __pAppWidgetBuffer->UnlockBuffer();
        }
 }