From 5bdde164a712ee6e86bd27fc5636f7cc220def0f Mon Sep 17 00:00:00 2001 From: HeeJu Kang Date: Mon, 29 Apr 2013 16:01:42 +0900 Subject: [PATCH] Apply gem Change-Id: I4c69945ed55399c166892e076c5c287d5b637c9d Signed-off-by: HeeJu Kang --- packaging/osp-shell.spec | 11 +- src/CMakeLists.txt | 4 +- src/FShell_AppWidgetBuffer.cpp | 477 +++++++++++++++++++++++++++++++++++++++ src/FShell_AppWidgetBuffer.h | 179 +++++++++++++++ src/FShell_AppWidgetFrame.cpp | 30 +-- src/FShell_AppWidgetLayer.cpp | 195 +++++++--------- src/FShell_AppWidgetLayer.h | 10 +- src/FShell_AppWidgetPopup.cpp | 53 +++-- src/FShell_AppWidgetView.cpp | 2 +- src/FShell_AppWidgetViewImpl.cpp | 2 +- 10 files changed, 790 insertions(+), 173 deletions(-) create mode 100644 src/FShell_AppWidgetBuffer.cpp create mode 100644 src/FShell_AppWidgetBuffer.h diff --git a/packaging/osp-shell.spec b/packaging/osp-shell.spec index 9010d0a..266367a 100755 --- a/packaging/osp-shell.spec +++ b/packaging/osp-shell.spec @@ -22,9 +22,14 @@ BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(appsvc) BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(minicontrol-provider) -BuildRequires: pkgconfig(x11) -BuildRequires: pkgconfig(xext) -BuildRequires: pkgconfig(xfixes) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(xfixes) +BuildRequires: pkgconfig(xdamage) +BuildRequires: pkgconfig(libdri2) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libtbm) +BuildRequires: pkgconfig(dri2proto) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(provider) BuildRequires: pkgconfig(livebox-viewer) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f0b394f..26ef95e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -72,6 +72,7 @@ SET (${this_target}_SOURCE_FILES FShellAppWidgetManager.cpp FShellAppWidgetProviderManager.cpp FShell_AppWidgetManagerIpcMessage.cpp + FShell_AppWidgetBuffer.cpp FShell_AppWidgetFrame.cpp FShell_AppWidgetFrameImpl.cpp FShell_AppWidgetFrameModel.cpp @@ -134,10 +135,9 @@ TARGET_LINK_LIBRARIES(${this_target} "-llivebox-viewer" ) TARGET_LINK_LIBRARIES(${this_target} "-llivebox-service" ) TARGET_LINK_LIBRARIES(${this_target} "-lprovider" ) TARGET_LINK_LIBRARIES(${this_target} "-lshortcut" ) -IF (NOT OSP_EMUL) TARGET_LINK_LIBRARIES(${this_target} "-ldri2" ) TARGET_LINK_LIBRARIES(${this_target} "-ldrm" ) -ENDIF (NOT OSP_EMUL) +TARGET_LINK_LIBRARIES(${this_target} "-ltbm" ) SET_TARGET_PROPERTIES(${this_target} PROPERTIES diff --git a/src/FShell_AppWidgetBuffer.cpp b/src/FShell_AppWidgetBuffer.cpp new file mode 100644 index 0000000..ed664d4 --- /dev/null +++ b/src/FShell_AppWidgetBuffer.cpp @@ -0,0 +1,477 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/** + * @file FShell_AppWidgetBuffer.cpp + * @brief This is the implementation file for the _AppWidgetBuffer class. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FShell_AppWidgetBuffer.h" + +using namespace std; +using namespace Tizen::Base; +using namespace Tizen::Graphics; +//using namespace Tizen::Ui::Animations; +//using namespace Tizen::Ui; + +namespace Tizen { namespace Shell +{ + +_AppWidgetBuffer::_AppWidgetBuffer(void) + : __screen(0) + , __pVisual(null) + , __dri2FileDescriptor(-1) +{ +} + +_AppWidgetBuffer::~_AppWidgetBuffer(void) +{ +} + +struct _Deleter +{ + void operator()(char* pStr) + { + free(pStr); + } +}; + +void +_AppWidgetBuffer::Initialize(void) +{ + __pDisplay.reset(XOpenDisplay(null)); + SysTryReturnVoidResult(NID_SHELL, __pDisplay, E_SYSTEM, "[E_SYSTEM] Propagating."); + + Screen* pScreen = DefaultScreenOfDisplay(__pDisplay.get()); + __screen = DefaultScreen(__pDisplay.get()); + __pVisual = DefaultVisualOfScreen(pScreen); + SysTryReturnVoidResult(NID_SHELL, __pVisual, E_SYSTEM, "[E_SYSTEM] Propagating."); + + Bool ret = False; + int eventBase = 0; + int errorBase = 0; + ret = DRI2QueryExtension(__pDisplay.get(), &eventBase, &errorBase); + if (!ret) + { + SysLog(NID_SHELL, "Do not support"); + return; + } + + int dri2Major = 0; + int dri2Minor = 0; + ret = DRI2QueryVersion(__pDisplay.get(), &dri2Major, &dri2Minor); + if (!ret) + { + SysLog(NID_SHELL, "Do not support"); + return; + } + + char* pDriverNameTemp = null; + char* pDeviceNameTemp = null; + + ret = DRI2Connect(__pDisplay.get(), DefaultRootWindow(__pDisplay.get()), &pDriverNameTemp, &pDeviceNameTemp); + if (!ret) + { + SysLog(NID_SHELL, "Do not support"); + return; + } + + unique_ptr pDriverName(pDriverNameTemp); + unique_ptr pDeviceName(pDeviceNameTemp); + + unique_ptr fileDescriptor(open(pDeviceName.get(), O_RDWR)); + if (fileDescriptor.get() < 0) + { + SysLog(NID_SHELL, "Do not support"); + return; + } + + drm_magic_t magic = 0; + drmGetMagic(fileDescriptor.get(), &magic); + SysLog(NID_SHELL, "Magic [0x%x]", magic); + ret = DRI2Authenticate(__pDisplay.get(), DefaultRootWindow(__pDisplay.get()), magic); + SysTryReturnVoidResult(NID_SHELL, ret == True, E_SYSTEM, "[E_SYSTEM] Propagating."); + + unique_ptr pBufMgr(tbm_bufmgr_init(fileDescriptor.get())); + SysTryReturnVoidResult(NID_SHELL, pBufMgr, E_SYSTEM, "[E_SYSTEM] Propagating."); + + __dri2FileDescriptor = move(fileDescriptor); + __pBufMgr = move(pBufMgr); +} + +void* +_AppWidgetBuffer::AllocBuffer(Pixmap pixmap, const Tizen::Graphics::FloatDimension& size) +{ + unique_ptr<_Buffer> pBuffer; + + if (!IsGemBufferEnabled()) + { + pBuffer.reset(new (std::nothrow) _Buffer(this)); + } + else + { + pBuffer.reset(new (std::nothrow) _GemBuffer(this)); + } + + SysTryReturn(NID_SHELL, pBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + void* pNativeBuffer = pBuffer->AllocBuffer(pixmap, size); + SysTryReturn(NID_SHELL, pNativeBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + __pBuffer = move(pBuffer); + + return pNativeBuffer; +} + +void +_AppWidgetBuffer::DeallocBuffer(void) +{ + SysTryReturnVoidResult(NID_SHELL, __pBuffer, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + __pBuffer->DeallocBuffer(); +} + +void* +_AppWidgetBuffer::LockBuffer(void) +{ + SysTryReturn(NID_SHELL, __pBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + void* pNativeBuffer = __pBuffer->LockBuffer(); + SysTryReturn(NID_SHELL, pNativeBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + return pNativeBuffer; +} + +void +_AppWidgetBuffer::UnlockBuffer(void) +{ + SysTryReturnVoidResult(NID_SHELL, __pBuffer, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + __pBuffer->UnlockBuffer(); +} + +bool +_AppWidgetBuffer::IsGemBufferEnabled(void) const +{ + return (__dri2FileDescriptor.get() >= 0); +} + +Display* +_AppWidgetBuffer::GetDisplay(void) const +{ + return __pDisplay.get(); +} + +GC +_AppWidgetBuffer::GetGc(void) const +{ + SysTryReturn(NID_SHELL, __pBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + return __pBuffer->GetGc(); +} + +XImage* +_AppWidgetBuffer::GetXImage(void) const +{ + SysTryReturn(NID_SHELL, __pBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + return __pBuffer->GetXImage(); +} + +_AppWidgetBuffer::_Buffer::_Buffer(_AppWidgetBuffer* pAppWidgetBuffer) + : __allocated(false) + , __locked(false) + , __pixmap(0) + , __depth(sizeof(int)) + , __pAppWidgetBuffer(pAppWidgetBuffer) + , __gc(null) + , __pXImage(null) +{ +} + +_AppWidgetBuffer::_Buffer::~_Buffer(void) +{ + DeleteBuffer(); +} + +void* +_AppWidgetBuffer::_Buffer::AllocBuffer(Pixmap pixmap, const Tizen::Graphics::FloatDimension& size) +{ + __pixmap = pixmap; + __size = size; + + OnCreateBuffer(); + + __allocated = true; + + return LockBuffer(); +} + +void +_AppWidgetBuffer::_Buffer::DeallocBuffer(void) +{ + OnDeleteBuffer(); + + __allocated = false; +} + +void* +_AppWidgetBuffer::_Buffer::LockBuffer(void) +{ + __locked = true; + + return OnLockBuffer(); +} + +void +_AppWidgetBuffer::_Buffer::UnlockBuffer(void) +{ + __locked = false; + + return OnUnlockBuffer(); +} + +GC +_AppWidgetBuffer::_Buffer::GetGc(void) const +{ + return __gc; +} + +XImage* +_AppWidgetBuffer::_Buffer::GetXImage(void) const +{ + return __pXImage; +} + +void +_AppWidgetBuffer::_Buffer::DeleteBuffer(void) +{ + if (__allocated) + { + XFreeGC(__pAppWidgetBuffer->__pDisplay.get(), __gc); + XShmDetach(__pAppWidgetBuffer->__pDisplay.get(), &__xShmSegmentInfo); + XDestroyImage(__pXImage); + + if (__xShmSegmentInfo.shmaddr != (void *)-1) + { + shmdt(__xShmSegmentInfo.shmaddr); + } + + if (__xShmSegmentInfo.shmid >= 0) + { + shmctl(__xShmSegmentInfo.shmid, IPC_RMID, 0); + } + } + + __allocated = false; +} + +void +_AppWidgetBuffer::_Buffer::OnCreateBuffer(void) +{ + int bufferSize = static_cast(__size.width) * static_cast(__size.height) * __depth; + SysLog(NID_SHELL, "%d [%f %f %d]", bufferSize, __size.width, __size.height, __depth); + + __xShmSegmentInfo.shmid = shmget(IPC_PRIVATE, bufferSize, IPC_CREAT | 0666); + SysTryReturnVoidResult(NID_SHELL, __xShmSegmentInfo.shmid >= 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + __xShmSegmentInfo.readOnly = False; + __xShmSegmentInfo.shmaddr = static_cast(shmat(__xShmSegmentInfo.shmid, null, 0)); + SysTryCatch(NID_SHELL, __xShmSegmentInfo.shmaddr != (void*)-1, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + __pXImage = XShmCreateImage(__pAppWidgetBuffer->__pDisplay.get(), __pAppWidgetBuffer->__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(__pAppWidgetBuffer->__pDisplay.get(), &__xShmSegmentInfo); + XSync(__pAppWidgetBuffer->__pDisplay.get(), False); + + __gc = XCreateGC(__pAppWidgetBuffer->__pDisplay.get(), static_cast(__pixmap), 0, null); + SysTryCatch(NID_SHELL, __gc, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + return; + +CATCH: + + XShmDetach(__pAppWidgetBuffer->__pDisplay.get(), &__xShmSegmentInfo); + + if (__pXImage) + { + XDestroyImage(__pXImage); + __pXImage = null; + } + + if (__xShmSegmentInfo.shmaddr != (void *)-1) + { + shmdt(__xShmSegmentInfo.shmaddr); + } + + if (__xShmSegmentInfo.shmid >= 0) + { + shmctl(__xShmSegmentInfo.shmid, IPC_RMID, 0); + } +} + +void +_AppWidgetBuffer::_Buffer::OnDeleteBuffer(void) +{ + DeleteBuffer(); +} + +void* +_AppWidgetBuffer::_Buffer::OnLockBuffer(void) +{ + return __xShmSegmentInfo.shmaddr; +} + +void +_AppWidgetBuffer::_Buffer::OnUnlockBuffer(void) +{ +// DeleteBuffer(); +} + +_AppWidgetBuffer::_GemBuffer::_GemBuffer(_AppWidgetBuffer* pAppWidgetBuffer) + : _Buffer(pAppWidgetBuffer) + , __pDri2Buffer(null) + , __count(1) + , __outCount(0) + , __pTbmBo(null) + , __pGemBuffer(null) + , __pCompensateBuffer(null) +{ + __attachments[0] = DRI2BufferFrontLeft; +} + +_AppWidgetBuffer::_GemBuffer::~_GemBuffer(void) +{ + DeleteGemBuffer(); +} + +void +_AppWidgetBuffer::_GemBuffer::DeleteGemBuffer(void) +{ + if (__pCompensateBuffer) + { + free(__pCompensateBuffer); + __pCompensateBuffer = null; + } + + if (__pTbmBo) + { + tbm_bo_unref(__pTbmBo); + __pTbmBo = null; + + DRI2DestroyDrawable(__pAppWidgetBuffer->__pDisplay.get(), __pixmap); + } +} + +void +_AppWidgetBuffer::_GemBuffer::OnCreateBuffer(void) +{ + SysLog(NID_SHELL, "[%f %f]", __size.width, __size.height); + + unsigned int pitch = 0; + + DRI2CreateDrawable(__pAppWidgetBuffer->__pDisplay.get(), __pixmap); + + int width = static_cast(__size.width); + int height = static_cast(__size.height); + + __pDri2Buffer = DRI2GetBuffers(__pAppWidgetBuffer->__pDisplay.get(), __pixmap, &width, &height, __attachments, __count, &__outCount); + SysTryCatch(NID_SHELL, __pDri2Buffer && __pDri2Buffer->name, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + __gemSize.width = width; + __gemSize.height = height; + + SysLog(NID_SHELL, "0x%x [%d %d %d] [%d %d]", __pDri2Buffer, __outCount, __pDri2Buffer->name, __pDri2Buffer->pitch, width, height); + + __pTbmBo = tbm_bo_import(__pAppWidgetBuffer->__pBufMgr.get(), __pDri2Buffer->name); + SysTryCatch(NID_SHELL, __pTbmBo, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + pitch = __gemSize.width * __depth; + if (__pDri2Buffer->pitch != pitch) + { + __pCompensateBuffer = calloc(1, pitch * __gemSize.height); + SysTryCatch(NID_SHELL, __pCompensateBuffer, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + SysLog(NID_SHELL, "0x%x [%d %d %d]", __pCompensateBuffer, __depth, __gemSize.width, __gemSize.height); + } + + return; + +CATCH: + + DRI2DestroyDrawable(__pAppWidgetBuffer->__pDisplay.get(), __pixmap); +} + +void +_AppWidgetBuffer::_GemBuffer::OnDeleteBuffer(void) +{ + DeleteGemBuffer(); +} + +void* +_AppWidgetBuffer::_GemBuffer::OnLockBuffer(void) +{ + if (!__pGemBuffer) + { + tbm_bo_handle handle; + handle = tbm_bo_map(__pTbmBo, TBM_DEVICE_CPU, TBM_OPTION_READ | TBM_OPTION_WRITE); + __pGemBuffer = handle.ptr; + } + + return __pCompensateBuffer ? __pCompensateBuffer : __pGemBuffer; +} + +void +_AppWidgetBuffer::_GemBuffer::OnUnlockBuffer(void) +{ + if (__pCompensateBuffer) + { + int* pPixel = (int*)__pCompensateBuffer; + int* pGemPixel = (int*)__pGemBuffer; + int gap = __pDri2Buffer->pitch - (__gemSize.width * __depth); + + for (int y = 0; y < __gemSize.height; y++) + { + for (int x = 0; x < __gemSize.width; x++) + { + *pGemPixel++ = *pPixel++; + } + + pGemPixel = (int*)(((char*)pGemPixel) + gap); + } + } + + tbm_bo_unmap(__pTbmBo); + __pGemBuffer = null; +} + +}} // Tizen::Shell diff --git a/src/FShell_AppWidgetBuffer.h b/src/FShell_AppWidgetBuffer.h new file mode 100644 index 0000000..9532013 --- /dev/null +++ b/src/FShell_AppWidgetBuffer.h @@ -0,0 +1,179 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Flora License, Version 1.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://floralicense.org/license/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/** + * @file FShell_AppWidgetBuffer.h + * @brief This is the header file for the _AppWidgetBuffer class. + * + * This header file contains the declarations of the %_AppWidgetBuffer class. + */ +#ifndef _FSHELL_INTERNAL_APPWIDGET_BUFFER_H_ +#define _FSHELL_INTERNAL_APPWIDGET_BUFFER_H_ + +#include +extern "C" +{ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +} +#include +#include +#include + +namespace Tizen { namespace Graphics +{ +class FloatDimension; +}} // Tizen::Graphics + +namespace Tizen { namespace Shell +{ + +/** + * @class _AppWidgetBuffer + * @brief + * @since 2.1 + */ +class _AppWidgetBuffer +{ +public: + _AppWidgetBuffer(void); + ~_AppWidgetBuffer(void); + + void Initialize(void); + void* AllocBuffer(Pixmap pixmap, const Tizen::Graphics::FloatDimension& size); + void DeallocBuffer(void); + void* LockBuffer(void); + void UnlockBuffer(void); + bool IsGemBufferEnabled(void) const; + Display* GetDisplay(void) const; + GC GetGc(void) const; + XImage* GetXImage(void) const; + +private: + _AppWidgetBuffer(const _AppWidgetBuffer& rhs); + _AppWidgetBuffer& operator =(const _AppWidgetBuffer& rhs); + +private: + class _Buffer + { + public: + _Buffer(_AppWidgetBuffer* pAppWidgetBuffer); + virtual ~_Buffer(void); + void* AllocBuffer(Pixmap pixmap, const Tizen::Graphics::FloatDimension& size); + void DeallocBuffer(void); + void* LockBuffer(void); + void UnlockBuffer(void); + GC GetGc(void) const; + XImage* GetXImage(void) const; + + private: + _Buffer(const _Buffer& rhs); + _Buffer& operator =(const _Buffer& rhs); + void DeleteBuffer(void); + virtual void OnCreateBuffer(void); + virtual void OnDeleteBuffer(void); + virtual void* OnLockBuffer(void); + virtual void OnUnlockBuffer(void); + + protected: + bool __allocated; + bool __locked; + Pixmap __pixmap; + int __depth; + Tizen::Graphics::FloatDimension __size; + _AppWidgetBuffer* __pAppWidgetBuffer; + + private: + GC __gc; + XImage* __pXImage; + XShmSegmentInfo __xShmSegmentInfo; + }; + + class _GemBuffer + : public _Buffer + { + public: + _GemBuffer(_AppWidgetBuffer* pAppWidgetBuffer); + virtual ~_GemBuffer(void); + + private: + _GemBuffer(const _GemBuffer& rhs); + _GemBuffer& operator =(const _GemBuffer& rhs); + void DeleteGemBuffer(void); + virtual void OnCreateBuffer(void); + virtual void OnDeleteBuffer(void); + virtual void* OnLockBuffer(void); + virtual void OnUnlockBuffer(void); + + private: + DRI2Buffer* __pDri2Buffer; + Tizen::Graphics::Dimension __gemSize; + int __count; + int __outCount; + unsigned int __attachments[1]; + tbm_bo __pTbmBo; + void* __pGemBuffer; + void* __pCompensateBuffer; + }; + + Tizen::Graphics::FloatDimension __size; + int __screen; + Visual* __pVisual; + + struct _FileDescriptorDeleter + { + typedef int pointer; + + void operator()(int fileDescriptor) + { + close(fileDescriptor); + } + }; + std::unique_ptr __dri2FileDescriptor; + + struct _DisplayDeleter + { + void operator()(Display* pDisplay) + { + XCloseDisplay(pDisplay); + } + }; + std::unique_ptr __pDisplay; + + struct _TbmBufMgrDeleter + { + typedef tbm_bufmgr pointer; + + void operator()(tbm_bufmgr pBufMgr) + { + tbm_bufmgr_deinit(pBufMgr); + } + }; + std::unique_ptr __pBufMgr; + std::unique_ptr<_Buffer> __pBuffer; +}; + +}} // Tizen::Shell + +#endif // _FSHELL_INTERNAL_APPWIDGET_BUFFER_H_ diff --git a/src/FShell_AppWidgetFrame.cpp b/src/FShell_AppWidgetFrame.cpp index 0fb29df..b126421 100644 --- a/src/FShell_AppWidgetFrame.cpp +++ b/src/FShell_AppWidgetFrame.cpp @@ -85,34 +85,18 @@ _AppWidgetFrame::CreateAppWidgetFrameN(void) result _AppWidgetFrame::Initialize(const FloatDimension& size) { - result r = E_SUCCESS; - - const float DEFAULT_WIDTH = 172.0f; - const float DEFAULT_HEIGHT = 172.0f; - - FloatDimension appwidgetSize(size); - if (appwidgetSize.width <= 0 ) - { - appwidgetSize.width = DEFAULT_WIDTH; - } - - if (appwidgetSize.height <= 0 ) - { - appwidgetSize.height = DEFAULT_HEIGHT; - } - SetSystemWindow(true); __appwidgetSize = size; - r = CreateRootVisualElement(); + result r = __pAppWidgetFramePresenter->Initialize(); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); - FloatRectangle bounds(0.0f, 0.0f, appwidgetSize.width, appwidgetSize.height); - r = SetBounds(bounds); + r = CreateRootVisualElement(); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); - r = __pAppWidgetFramePresenter->Initialize(); + FloatRectangle bounds(0.0f, 0.0f, 1.0f, 1.0f); + r = SetBounds(bounds); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); __pAppWidgetLayer->SetLayerBounds(bounds); @@ -139,6 +123,10 @@ _AppWidgetFrame::SetProviderId(const String& providerId) result r = __pAppWidgetLayer->SetProviderId(providerId); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + FloatRectangle bounds(0.0f, 0.0f, __appwidgetSize.width, __appwidgetSize.height); + r = SetBounds(bounds); + SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + return r; } @@ -188,7 +176,7 @@ _AppWidgetFrame::SetLayerBounds(const FloatRectangle& bounds) result _AppWidgetFrame::CreateLayer(void) { - unique_ptr<_AppWidgetLayer> pLayer(new (std::nothrow) _AppWidgetLayer(__appwidgetSize)); + unique_ptr<_AppWidgetLayer> pLayer(new (std::nothrow) _AppWidgetLayer(GetProviderId(), GetSizeF())); SysTryReturn(NID_SHELL, pLayer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); result r = pLayer->Construct(); diff --git a/src/FShell_AppWidgetLayer.cpp b/src/FShell_AppWidgetLayer.cpp index fe61a42..6cf36a5 100644 --- a/src/FShell_AppWidgetLayer.cpp +++ b/src/FShell_AppWidgetLayer.cpp @@ -34,6 +34,7 @@ #include #include #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 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(bounds.x), static_cast(bounds.y), static_cast(bounds.width), static_cast(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); + SysTryReturn(NID_SHELL, __pTempBuffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); + + pBuffer = __pTempBuffer; + } + else + { + 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(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(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(__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(__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(__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(); } } diff --git a/src/FShell_AppWidgetLayer.h b/src/FShell_AppWidgetLayer.h index 0e42ff0..a00e6ec 100644 --- a/src/FShell_AppWidgetLayer.h +++ b/src/FShell_AppWidgetLayer.h @@ -15,7 +15,7 @@ // limitations under the License. // /** - * @file FShell_AppWidgetFrame.h + * @file FShell_AppWidgetLayer.h * @brief This is the header file for the _AppWidgetLayer class. * * This header file contains the declarations of the %_AppWidgetLayer class. @@ -37,6 +37,8 @@ class _Window; namespace Tizen { namespace Shell { +class _AppWidgetBuffer; + /** * @class _AppWidgetLayer * @brief @@ -47,7 +49,7 @@ class _AppWidgetLayer , public Tizen::Shell::_IAppWidgetTouchEventListener { public: - _AppWidgetLayer(const Tizen::Graphics::FloatDimension& size); + _AppWidgetLayer(const Tizen::Base::String& providerId, const Tizen::Graphics::FloatDimension& size); virtual ~_AppWidgetLayer(void); virtual result OnConstructed(void); @@ -70,7 +72,7 @@ public: private: _AppWidgetLayer(const _AppWidgetLayer& rhs); - _AppWidgetLayer& operator =(const _AppWidgetLayer& rhs); + _AppWidgetLayer& operator =(const _AppWidgetLayer& rhs); virtual void Flush(void); protected: @@ -98,8 +100,10 @@ private: std::unique_ptr __pEvasObject; Tizen::Base::String __providerId; void* __pRenderBuffer; + void* __pTempBuffer; int __bufferSize; int __pixmapId; + std::unique_ptr<_AppWidgetBuffer> __pAppWidgetBuffer; }; }} // Tizen::Shell diff --git a/src/FShell_AppWidgetPopup.cpp b/src/FShell_AppWidgetPopup.cpp index 13945af..4c6ff7f 100644 --- a/src/FShell_AppWidgetPopup.cpp +++ b/src/FShell_AppWidgetPopup.cpp @@ -53,7 +53,7 @@ class _AppWidgetPopupLayer : public _AppWidgetLayer { public: - _AppWidgetPopupLayer(const FloatDimension& size); + _AppWidgetPopupLayer(const Tizen::Base::String& providerId, const FloatDimension& size); virtual ~_AppWidgetPopupLayer(void); private: @@ -66,8 +66,8 @@ private: virtual void ReleasePixmap(void); }; -_AppWidgetPopupLayer::_AppWidgetPopupLayer(const FloatDimension& size) - : _AppWidgetLayer(size) +_AppWidgetPopupLayer::_AppWidgetPopupLayer(const Tizen::Base::String& providerId, const FloatDimension& size) + : _AppWidgetLayer(providerId, size) { } @@ -180,28 +180,31 @@ _AppWidgetPopup::Initialize(const FloatDimension& size) SetSystemWindow(true); - r = CreateRootVisualElement(); - SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); - - FloatRectangle bounds(0.0f, 0.0f, size.width, size.height); - r = SetBounds(bounds); - SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); - r = __pAppWidgetPopupPresenter->Initialize(); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); - __pAppWidgetPopupLayer->SetLayerBounds(bounds); - __pAppWidgetPopupLayer->SetShowState(false); - - __pAppWidgetPopupRootVisualElement->SetImplicitAnimationEnabled(false); - __pAppWidgetPopupRootVisualElement->SetName(L"_AppWidgetPopup"); - __pAppWidgetPopupRootVisualElement->SetBounds(bounds); - __pAppWidgetPopupRootVisualElement->SetShowState(false); - - SetBackgroundColor(Color(0, 0, 0, 0)); - - __pEventManager->RegisterTouchEventHandler(*this); - r = GetLastResult(); + r = CreateRootVisualElement(); + SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + + FloatRectangle bounds(0.0f, 0.0f, 1.0f, 1.0f); + r = SetBounds(bounds); + SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + + r = __pAppWidgetPopupPresenter->Initialize(); + SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + + __pAppWidgetPopupLayer->SetLayerBounds(bounds); + __pAppWidgetPopupLayer->SetShowState(false); + + __pAppWidgetPopupRootVisualElement->SetImplicitAnimationEnabled(false); + __pAppWidgetPopupRootVisualElement->SetName(L"_AppWidgetPopup"); + __pAppWidgetPopupRootVisualElement->SetBounds(bounds); + __pAppWidgetPopupRootVisualElement->SetShowState(false); + + SetBackgroundColor(Color(0, 0, 0, 0)); + + __pEventManager->RegisterTouchEventHandler(*this); + r = GetLastResult(); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); return r; @@ -215,6 +218,10 @@ _AppWidgetPopup::SetProviderId(const String& providerId) result r = __pAppWidgetPopupLayer->SetProviderId(providerId); SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + FloatRectangle bounds(0.0f, 0.0f, __appwidgetSize.width, __appwidgetSize.height); + r = SetBounds(bounds); + SysTryReturn(NID_SHELL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r)); + return r; } @@ -331,7 +338,7 @@ _AppWidgetPopup::UpdateClientBounds(const FloatDimension& size, FloatRectangle& result _AppWidgetPopup::CreateLayer(void) { - unique_ptr<_AppWidgetPopupLayer> pLayer(new (std::nothrow) _AppWidgetPopupLayer(__appwidgetSize)); + unique_ptr<_AppWidgetPopupLayer> pLayer(new (std::nothrow) _AppWidgetPopupLayer(GetProviderId(), GetSizeF())); SysTryReturn(NID_SHELL, pLayer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); result r = pLayer->Construct(); diff --git a/src/FShell_AppWidgetView.cpp b/src/FShell_AppWidgetView.cpp index 32551bc..d87c795 100644 --- a/src/FShell_AppWidgetView.cpp +++ b/src/FShell_AppWidgetView.cpp @@ -716,7 +716,7 @@ _AppWidgetView::OnAppWidgetUpdated(int pixmap) __pPixmapEventHandler.reset(ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY, OnPixmapDamaged, (void*)this)); SysTryReturnVoidResult(NID_SHELL, __pPixmapEventHandler, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient."); */ - SysLog(NID_SHELL, "[0x%x][%d %d]", surface.data.x11.pixmap, absoluteBounds.x, absoluteBounds.y); + SysLog(NID_SHELL, "[0x%x][%f %f]", surface.data.x11.pixmap, absoluteBounds.x, absoluteBounds.y); } SysLog(NID_SHELL, "[%d %d %d %d]", x, y, width, height); diff --git a/src/FShell_AppWidgetViewImpl.cpp b/src/FShell_AppWidgetViewImpl.cpp index 577ca0b..78122e5 100644 --- a/src/FShell_AppWidgetViewImpl.cpp +++ b/src/FShell_AppWidgetViewImpl.cpp @@ -149,7 +149,7 @@ result _AppWidgetViewImpl::AddAppWidgetViewEventListener(IAppWidgetViewEventListener& listener) { bool exist = __pAppWidgetViewEventListenerList->Contains(&listener); - SysTryReturn(NID_SHELL, exist, E_OBJ_ALREADY_EXIST, E_OBJ_ALREADY_EXIST, "[%s] Propagating.", GetErrorMessage(E_OBJ_ALREADY_EXIST)); + SysTryReturn(NID_SHELL, exist == false, E_OBJ_ALREADY_EXIST, E_OBJ_ALREADY_EXIST, "[%s] Propagating.", GetErrorMessage(E_OBJ_ALREADY_EXIST)); __pAppWidgetViewEventListenerList->Add(&listener); -- 2.7.4