Merge "Fixing Jira issue N_SE-48642 and N_SE-48736." into tizen_2.2
[platform/framework/native/uifw.git] / src / ui / controls / FUiCtrl_OverlayAgent.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FUiCtrl_OverlayAgent.cpp
20  * @brief               This file contains implementation of _OverlayAgent class
21  */
22
23 #include <new>
24 #include <sys/shm.h>
25 #include <unique_ptr.h>
26 #include <Ecore_Evas.h>
27
28 #include <FBaseResult.h>
29 #include <FUiIOrientationEventListener.h>
30 #include <FUiAnimDisplayContext.h>
31 #include <FGrp_BufferInfoImpl.h>
32 #include <FGrp_Screen.h>
33 #include <FIo_RegistryImpl.h>
34 #include <FMedia_ImageUtil.h>
35 #include "FUi_Control.h"
36 #include "FUi_CoordinateSystemUtils.h"
37 #include "FUi_EcoreEvas.h"
38 #include "FUi_EcoreEvasMgr.h"
39 #include "FUi_Window.h"
40 #include "FUiAnim_EflNode.h"
41 #include "FUiAnim_ControlVisualElement.h"
42 #include "FUiAnim_VisualElementSurfaceImpl.h"
43 #include "FUiAnim_VisualElementImpl.h"
44 #include "FUiCtrl_OverlayAgent.h"
45
46 #define B(c,s) ((((unsigned int)(c)) & 0xff) << (s))
47 #define FOURCC(a,b,c,d) (B(d,24) | B(c,16) | B(b,8) | B(a,0))
48
49 using namespace std;
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Collection;
52 using namespace Tizen::Base::Runtime;
53 using namespace Tizen::Graphics;
54 using namespace Tizen::Io;
55 using namespace Tizen::Media;
56 using namespace Tizen::System;
57 using namespace Tizen::Ui::Controls;
58 using namespace Tizen::Ui::Animations;
59
60 namespace
61 {
62 bool
63 CheckXvExtension(Display* pDisplay, int* pFirstPort, int* pCountPort)
64 {
65         unsigned int version = 0;
66         unsigned int release = 0;
67         unsigned int requestBase = 0;
68         unsigned int eventBase = 0;
69         unsigned int errorBase = 0;
70
71         // Query and print Xvideo properties
72         int returnValue = XvQueryExtension(pDisplay, &version, &release, &requestBase, &eventBase, &errorBase);
73         if (returnValue != Success)
74         {
75                 if (returnValue == XvBadExtension)
76                 {
77                         SysSecureLog(NID_UI_CTRL, "XvBadExtension returned at XvQueryExtension!");
78                 }
79                 else if (returnValue == XvBadAlloc)
80                 {
81                         SysSecureLog(NID_UI_CTRL, "XvBadAlloc returned at XvQueryExtension!");
82                 }
83                 else
84                 {
85                         SysSecureLog(NID_UI_CTRL, "Other error happened at XvQueryExtension!");
86                 }
87
88                 return false;
89         }
90
91         unsigned int adaptors = 0;
92         XvAdaptorInfo* pAdaptorInfo = null;
93         returnValue = XvQueryAdaptors(pDisplay, DefaultRootWindow(pDisplay), &adaptors, &pAdaptorInfo);
94         if (returnValue != Success)
95         {
96                 if (returnValue == XvBadExtension)
97                 {
98                         SysSecureLog(NID_UI_CTRL, "XvBadExtension returned at XvQueryExtension.");
99                 }
100                 else if (returnValue == XvBadAlloc)
101                 {
102                         SysSecureLog(NID_UI_CTRL, "XvBadAlloc returned at XvQueryExtension.");
103                 }
104                 else
105                 {
106                         SysSecureLog(NID_UI_CTRL, "Other error happaned at XvQueryAdaptors.");
107                 }
108
109                 if (pAdaptorInfo != null)
110                 {
111                         XvFreeAdaptorInfo(pAdaptorInfo);
112                 }
113
114                 return false;
115         }
116
117         int port = -1;
118         if (adaptors > 0 && pAdaptorInfo != null)
119         {
120                 for (unsigned int i = 0; i < adaptors; i++)
121                 {
122                         for (unsigned int j = 0; j < pAdaptorInfo[i].num_formats; j++)
123                         {
124                                 SysSecureLog(NID_UI_CTRL, "The current value of depth is %d and visual is %ld.", pAdaptorInfo[i].formats[j].depth, pAdaptorInfo[i].formats[j].visual_id);
125                         }
126                 }
127
128                 port = pAdaptorInfo[0].base_id;
129
130                 *pFirstPort = port;
131                 *pCountPort = pAdaptorInfo[0].num_ports;
132                 SysSecureLog(NID_UI_CTRL, "The current value of port is %d", port);
133         }
134
135         if (pAdaptorInfo != null)
136         {
137                 XvFreeAdaptorInfo(pAdaptorInfo);
138         }
139
140         if (port == -1)
141         {
142                 return false;
143         }
144
145         return true;
146 }
147
148 Eina_Bool
149 OnPixmapDamaged(void* pData, int type, void* pEvent)
150 {
151         Ecore_X_Event_Damage* pDamageEvent = (Ecore_X_Event_Damage*)pEvent;
152         SysTryReturn(NID_UI_CTRL, pDamageEvent != null, ECORE_CALLBACK_PASS_ON, E_INVALID_DATA, "[E_INVALID_DATA] The current value of DamageEvent is invalid.");
153
154         Tizen::Ui::Controls::_OverlayAgent* pOverlayAgent = static_cast<Tizen::Ui::Controls::_OverlayAgent*>(pData);
155         SysTryReturn(NID_UI_CTRL, pOverlayAgent != null, ECORE_CALLBACK_PASS_ON, E_INVALID_DATA, "[E_INVALID_DATA] Failed to get OverlayAgent from DamagedEvent.");
156
157         if (pDamageEvent->drawable != pOverlayAgent->GetPixmap())
158         {
159                 return ECORE_CALLBACK_PASS_ON;
160         }
161
162         pOverlayAgent->SetRendererFlushNeeded();
163
164         return ECORE_CALLBACK_DONE;
165 }
166
167 void
168 OnEvasImageDamaged(void* pData, Evas_Object* pImageObject)
169 {
170         Tizen::Ui::Controls::_OverlayAgent* pOverlayAgent = static_cast<Tizen::Ui::Controls::_OverlayAgent*>(pData);
171         SysTryReturnVoidResult(NID_UI_CTRL, pOverlayAgent != null, E_INVALID_DATA, "[E_INVALID_DATA] Failed to get OverlayAgent from DamagedEvent.");
172
173         Evas_Object* pRendererImageObject = pOverlayAgent->GetRendererImageObject();
174         SysTryReturnVoidResult(NID_UI_CTRL, pRendererImageObject != null, E_INVALID_DATA, "[E_INVALID_DATA] Failed to get Renderer ImageObject of OverlayAgent.");
175
176         if (pRendererImageObject != pImageObject)
177         {
178                 return;
179         }
180
181         Dimension newImageSize(0,0);
182         evas_object_image_size_get(pImageObject, &newImageSize.width, &newImageSize.height);
183
184         Dimension rendererImageSize(0,0);
185         evas_object_image_size_get(pRendererImageObject, &rendererImageSize.width, &rendererImageSize.height);
186
187         if (!newImageSize.Equals(rendererImageSize))
188         {
189                 SysSecureLog(NID_UI_CTRL,"newImageSize [%d, %d] rendererImageSize [%d, %d]", newImageSize.width, newImageSize.height, rendererImageSize.width, rendererImageSize.height);
190                 pOverlayAgent->SetDestination(FloatDimension(static_cast<float>(newImageSize.width), static_cast<float>(newImageSize.height)));
191         }
192 }
193 } // Anonymous
194
195 namespace Tizen { namespace Ui { namespace Controls
196 {
197
198 int _OverlayAgent::__baseXvPort = 0;
199 bool _OverlayAgent::__isPortGrabbed[]={false,};
200
201 int _OverlayAgent::__overlayAgentCount = 0;
202 int _OverlayAgent::__dstRectMinWidth = -1;
203 int _OverlayAgent::__dstRectMinHegith = -1;
204 int _OverlayAgent::__srcRectMinWidth = -1;
205 int _OverlayAgent::__srcRectMinHegith = -1;
206 int _OverlayAgent::__overlayWidthUnit = -1;
207 int _OverlayAgent::__overlayHeightUnit = -1;
208 int _OverlayAgent::__overlayMaxCount = -1;
209 bool _OverlayAgent::__OverlayAgentBufferPixelFormat[] = {false, };
210
211 struct visualElementDeleter
212 {
213         void operator()(_VisualElement* pVisualElement)
214         {
215                 pVisualElement->Destroy();
216         }
217 };
218
219 _OverlayAgent::_OverlayVisualElement::_OverlayVisualElement(void)
220         : __pTimer(null)
221         , __pImageObject(null)
222         , __showStateChanged(false)
223 {
224 }
225
226 _OverlayAgent::_OverlayVisualElement::_OverlayVisualElement(const _OverlayVisualElement& rhs)
227         : _VisualElement(rhs)
228         , __pTimer(null)
229         , __pImageObject(rhs.__pImageObject)
230         , __showStateChanged(rhs.__showStateChanged)
231 {
232 }
233
234 _OverlayAgent::_OverlayVisualElement::~_OverlayVisualElement(void)
235 {
236         if (__pTimer)
237         {
238                 __pTimer->Cancel();
239                 delete __pTimer;
240                 __pTimer = null;
241         }
242
243         if (__pImageObject)
244         {
245                 evas_object_event_callback_del(__pImageObject, EVAS_CALLBACK_SHOW, OnImageObjectShown);
246                 evas_object_event_callback_del(__pImageObject, EVAS_CALLBACK_HIDE, OnImageObjectHidden);
247         }
248 }
249
250 result
251 _OverlayAgent::_OverlayVisualElement::Construct(void)
252 {
253         if (!__pTimer)
254         {
255                 __pTimer = new (nothrow) Timer();
256                 __pTimer->Construct(*this);
257         }
258
259         return _VisualElement::Construct();
260 }
261
262 Evas_Object*
263 _OverlayAgent::_OverlayVisualElement::GetImageObject(void) const
264 {
265         return __pImageObject;
266 }
267
268 void
269 _OverlayAgent::_OverlayVisualElement::SetImageObject(Evas_Object* pImageObject)
270 {
271         if (__pImageObject)
272         {
273                 evas_object_event_callback_del(__pImageObject, EVAS_CALLBACK_SHOW, OnImageObjectShown);
274                 evas_object_event_callback_del(__pImageObject, EVAS_CALLBACK_HIDE, OnImageObjectHidden);
275         }
276
277         __pImageObject = pImageObject;
278
279         if (__pImageObject)
280         {
281                 evas_object_event_callback_add(__pImageObject, EVAS_CALLBACK_SHOW, OnImageObjectShown, this);
282                 evas_object_event_callback_add(__pImageObject, EVAS_CALLBACK_HIDE, OnImageObjectHidden, this);
283         }
284 }
285
286 void
287 _OverlayAgent::_OverlayVisualElement::SetImageObjectShowStateChanged(void)
288 {
289         __showStateChanged = true;
290
291         __pTimer->Start(0);
292 }
293
294 void
295 _OverlayAgent::_OverlayVisualElement::OnImageObjectShown(void* pData, Evas *pEvas, Evas_Object *pImageObject, void *event_info)
296 {
297         _OverlayVisualElement* pOverlayVE = reinterpret_cast<_OverlayVisualElement*>(pData);
298         if (pOverlayVE)
299         {
300                 pOverlayVE->SetImageObjectShowStateChanged();
301                 SysSecureLog(NID_UI_CTRL, "The show state of Renderer VisualElement is set to SHOW");
302         }
303 }
304
305 void
306 _OverlayAgent::_OverlayVisualElement::OnImageObjectHidden(void* pData, Evas *pEvas, Evas_Object *pImageObject, void *event_info)
307 {
308         _OverlayVisualElement* pOverlayVE = reinterpret_cast<_OverlayVisualElement*>(pData);
309         if (pOverlayVE)
310         {
311                 pOverlayVE->SetImageObjectShowStateChanged();
312                 SysSecureLog(NID_UI_CTRL, "The show state of Renderer VisualElement is set to HIDE");
313         }
314 }
315
316 VisualElement*
317 _OverlayAgent::_OverlayVisualElement::CloneN(void) const
318 {
319         return new (nothrow) _OverlayVisualElement(*this);
320 }
321
322 void
323 _OverlayAgent::_OverlayVisualElement::OnTimerExpired(Timer& timer)
324 {
325         if (__showStateChanged && __pImageObject)
326         {
327                 SetShowState(evas_object_visible_get(__pImageObject));
328                 __showStateChanged = false;
329                 SysSecureLog(NID_UI_CTRL, "Updates show state of Renderer VisualElement");
330         }
331 }
332
333 _OverlayAgent*
334 _OverlayAgent::CreateInstanceN(_OverlayAgentStyle style, const _Control& parentControl, const FloatRectangle& logicalBounds, const Rectangle& physicalBounds)
335 {
336         unique_ptr<_OverlayAgent> pOverlayAgent(new (nothrow) _OverlayAgent(style, parentControl, logicalBounds, physicalBounds));
337         SysTryReturn(NID_UI_CTRL, pOverlayAgent != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory is insufficient.");
338
339         result r = GetLastResult();
340         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
341
342         return pOverlayAgent.release();
343 }
344
345 _OverlayAgent::_OverlayAgent(_OverlayAgentStyle style, const _Control& parentControl, const FloatRectangle& logicalBounds, const Rectangle& physicalBounds)
346         : __pRendererVE(null)
347         , __pParentVE(null)
348         , __pImageObject(null)
349         , __style(style)
350         , __currentRotation(_OVERLAY_AGENT_ROTATION_NONE)
351         , __savedColorFormat(FOURCC('R','G','B','4'))
352         , __currentColorFormat(_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888)
353         , __currentSourceBufferSize(0,0)
354         , __standardRendererBounds(0.0f, 0.0f, 0.0f, 0.0f)
355         , __standardParentBounds(0.0f, 0.0f, 0.0f, 0.0f)
356         , __needToRellaocImage(false)
357         , __pCurrentSourceBuffer(null)
358         , __pConvertedSourceBuffer(null)
359         , __pixmapDamageHandle(0)
360         , __pPixmapEventHandler(null)
361         , __pixmap(0)
362         , __xvPort(-1)
363         , __pXvImage(null)
364         , __pShmInfo(null)
365 {
366         result r = CreateRendererVisualElement(parentControl, logicalBounds, physicalBounds);
367
368         SysTryReturnVoidResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
369         SysTryReturnVoidResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "[E_SYSTEM] The Renderer VisualElement is null.");
370         SysTryReturnVoidResult(NID_UI_CTRL, __pImageObject!= null, E_SYSTEM, "[E_SYSTEM] The Renderder ImageObject is null.");
371
372         __overlayAgentCount++;
373         SysLog(NID_UI_CTRL, "The current count of OverlayAgent is %d", __overlayAgentCount);
374 }
375
376 _OverlayAgent::~_OverlayAgent(void)
377 {
378         SysLog(NID_UI_CTRL, "The %dth OverlayAgent is deleted.", __overlayAgentCount);
379         __overlayAgentCount--;
380
381         if (__xvPort > 0)
382         {
383                 UngrabXvPort();
384         }
385
386         if (__pPixmapEventHandler)
387         {
388                 ecore_event_handler_del(__pPixmapEventHandler);
389                 __pPixmapEventHandler = null;
390         }
391
392         if (__pixmapDamageHandle)
393         {
394                 ecore_x_damage_free(__pixmapDamageHandle);
395                 __pixmapDamageHandle = 0;
396         }
397
398         if (__pixmap != 0)
399         {
400                 XFreePixmap((Display*)ecore_x_display_get(), __pixmap);
401                 __pixmap = 0;
402         }
403
404         if (__pShmInfo)
405         {
406                 XShmDetach((Display*)ecore_x_display_get(), __pShmInfo);
407                 shmdt(__pShmInfo->shmaddr);
408                 shmctl(__pShmInfo->shmid, IPC_RMID, NULL);
409                 __pShmInfo = null;
410         }
411
412         if (__pXvImage)
413         {
414                 XFree(__pXvImage);
415                 __pXvImage = null;
416         }
417
418         if (__pConvertedSourceBuffer)
419         {
420                 delete __pConvertedSourceBuffer;
421                 __pConvertedSourceBuffer = null;
422         }
423
424         if (__pCurrentSourceBuffer)
425         {
426                 delete __pCurrentSourceBuffer;
427                 __pCurrentSourceBuffer = null;
428         }
429
430         if (__pRendererVE != null)
431         {
432                 __pRendererVE->SetSurface(null);
433                 __pRendererVE->Destroy();
434                 __pRendererVE = null;
435         }
436
437         if (__pImageObject)
438         {
439                 evas_object_del(__pImageObject);
440                 __pImageObject = null;
441         }
442 }
443
444 result
445 _OverlayAgent::GetBufferInfo(BufferInfo& bufferInfo) const
446 {
447         SysTryReturnResult(NID_UI_CTRL, __pImageObject != null, E_SYSTEM, "The Renderer ImageObject is null.");
448         SysTryReturnResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "The Renderer Visual Element is null.");
449
450         int width = 0;
451         int height = 0;
452         evas_object_geometry_get(__pImageObject, NULL, NULL, &width, &height);
453
454         bufferInfo.width = width;
455         bufferInfo.pitch = width;
456         bufferInfo.height = height;
457         bufferInfo.bitsPerPixel = 32;
458         bufferInfo.pixelFormat = PIXEL_FORMAT_ARGB8888;
459
460         _BufferInfoImpl* pBufferInfoImpl = _BufferInfoImpl::GetInstance(bufferInfo);
461         SysTryReturnResult(NID_UI_CTRL, pBufferInfoImpl != null, E_SYSTEM, "Failed to get instance of buffer info.");
462
463         result r = E_SUCCESS;
464
465         if(__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_PANEL_SW)
466         {
467                 pBufferInfoImpl->SetHandle(_BufferInfoImpl::HANDLE_TYPE_VE_SURFACE, reinterpret_cast<Handle>(__pImageObject));
468                 SysSecureLog(NID_UI_CTRL,"The returned handle of BufferInfo is a evas image object (HANDLE_TYPE_VE_SURFACE)");
469         }
470         else
471         {
472                 pBufferInfoImpl->SetHandle(_BufferInfoImpl::HANDLE_TYPE_OVERLAY_REGION, __pixmap);
473                 SysSecureLog(NID_UI_CTRL,"The returned handle of BufferInfo is a pixmap (HANDLE_TYPE_OVERLAY_REGION)");
474         }
475
476         pBufferInfoImpl->SetBounds(Rectangle(0, 0, width, height));
477
478         return r;
479 }
480
481 result
482 _OverlayAgent::SetInputBuffer(const ByteBuffer& srcBuffer, const Dimension& srcDim, _OverlayAgentBufferPixelFormat srcFormat)
483 {
484         SysTryReturnResult(NID_UI_CTRL, srcBuffer.GetPointer() != null, E_INVALID_ARG, "The current value of input source buffer is invalid.");
485         SysTryReturnResult(NID_UI_CTRL, srcBuffer.GetCapacity() > 0, E_INVALID_ARG, "The current size of input source buffer is invalid.");
486         SysTryReturnResult(NID_UI_CTRL, srcDim.width >= GetSrcRectMinWidth(), E_INVALID_ARG, "The width of dimension [%d] is under the minimum size.", srcDim.width);
487         SysTryReturnResult(NID_UI_CTRL, srcDim.height >= GetSrcRectMinHeight(), E_INVALID_ARG, "The height of dimension [%d] is under the minimum size.", srcDim.height);
488
489         if (__currentColorFormat != srcFormat)
490         {
491                 unsigned int colorFormat = 0;
492
493                 switch (srcFormat)
494                 {
495                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888:
496                         colorFormat = FOURCC('R','G','B','4');
497                         break;
498                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_RGB565:
499                         colorFormat = FOURCC('R','G','B','P');
500                         break;
501                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_YCbCr420_PLANAR:
502                         colorFormat = FOURCC('I','4','2','0');
503                         break;
504                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_NV12:
505                         colorFormat = FOURCC('N','V','1','2');
506                         break;
507                 case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY:
508                         colorFormat = FOURCC('U','Y','V','Y');
509                         break;
510                 default:
511                         SysLogException(NID_UI_CTRL, E_UNSUPPORTED_FORMAT, "The specified pixel format is not supported.");
512                         return E_UNSUPPORTED_FORMAT;
513                 }
514
515                 __savedColorFormat = colorFormat;
516                 __currentColorFormat = srcFormat;
517                 __needToRellaocImage = true;
518         }
519
520         if (!srcDim.Equals(__currentSourceBufferSize))
521         {
522                 __currentSourceBufferSize.width = srcDim.width;
523                 __currentSourceBufferSize.height = srcDim.height;
524                 __needToRellaocImage = true;
525         }
526
527         __pCurrentSourceBuffer = &srcBuffer;
528
529         if (__needToRellaocImage)
530         {
531                 SysSecureLog(NID_UI_CTRL,"The current buffer pointer is %x, size is %d, color format is %d",
532                         __pCurrentSourceBuffer->GetPointer(), __pCurrentSourceBuffer->GetCapacity(), __savedColorFormat);
533         }
534
535         return E_SUCCESS;
536 }
537
538 result
539 _OverlayAgent::Draw(void)
540 {
541         SysTryReturnResult(NID_UI_CTRL, __pCurrentSourceBuffer->GetPointer() != null, E_SYSTEM, "The current input user buffer is null. (nothing to draw)");
542
543         result r = E_SUCCESS;
544
545         if(__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_PANEL_SW)
546         {
547                 r = PutEvasImage();
548         }
549         else
550         {
551                 r = PutXvImage();
552         }
553
554         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "Propagating.");
555
556         return r;
557 }
558
559
560 result
561 _OverlayAgent::GrabXvPort(void)
562 {
563         Display* pDisplay = (Display*)ecore_x_display_get();
564         SysTryReturnResult(NID_UI_CTRL, pDisplay != null, E_SYSTEM, "The current value of Display is null");
565
566         int baseXvPort = -1;
567         int portCount = -1;
568         if (!CheckXvExtension(pDisplay, &baseXvPort, &portCount))
569         {
570                 SysTryReturnResult(NID_UI_CTRL, false, E_SYSTEM, "Failed to check XvExtension");
571         }
572
573         SysTryReturnResult(NID_UI_CTRL, baseXvPort > 0, E_SYSTEM, "The current value of base XvPort is invalid.");
574         SysTryReturnResult(NID_UI_CTRL, portCount >= 1 && portCount <= _OVERLAYAGENT_XV_PORT, E_SYSTEM, "The current count of available XvPort[%d] is invalid.", portCount);
575
576         _OverlayAgent::__baseXvPort = baseXvPort;
577
578         for (int index = 0; index < portCount; index++)
579         {
580                 if(!__isPortGrabbed[index])
581                 {
582                         int tempPort = __baseXvPort + index;
583                         if (XvGrabPort(pDisplay, tempPort, 0) != Success)
584                         {
585                                 SysSecureLog(NID_UI_CTRL, "The current XvPort[%d] has been alreadly used by another process", tempPort);
586                         }
587                         else
588                         {
589                                 __xvPort = tempPort;
590                                 __isPortGrabbed[index] = true;
591                                 break;
592                         }
593                 }
594         }
595
596         SysTryReturnResult(NID_UI_CTRL, __xvPort > 0, E_SYSTEM, "Failed to grab pixmap[%d]", __pixmap);
597         SysSecureLog(NID_UI_CTRL, "The current value of grabbed XvPort is [%d] and pixmap is [%d]", __xvPort, __pixmap);
598
599         return E_SUCCESS;
600 }
601
602 void
603 _OverlayAgent::UngrabXvPort(void)
604 {
605         ClearLastResult();
606
607         if (__xvPort > 0 && (__xvPort - __baseXvPort) >= 0 && __isPortGrabbed[__xvPort - __baseXvPort])
608         {
609                 Display* pDisplay = (Display*) ecore_x_display_get();
610                 Atom atom = XInternAtom(pDisplay, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False);
611                 XvSetPortAttribute(pDisplay, __xvPort, atom, 1);
612                 XvUngrabPort(pDisplay, __xvPort, 0);
613
614                 SysSecureLog(NID_UI_CTRL, "The current value of ungrabbed XvPort is %d, and pixmap is %d", __xvPort, __pixmap);
615
616                 __isPortGrabbed[__xvPort - __baseXvPort] = false;
617                 __xvPort = -1;
618         }
619 }
620
621 result
622 _OverlayAgent::PutXvImage(void)
623 {
624         SysTryReturnResult(NID_UI_CTRL, __pixmap != 0, E_SYSTEM, "The current value of pixmap is null");
625
626         Display* pDisplay = (Display*)ecore_x_display_get();
627         SysTryReturnResult(NID_UI_CTRL, pDisplay != null, E_SYSTEM, "The current value of Display is null");
628
629         if (__pXvImage == null || __needToRellaocImage)
630                 //||(__pXvImage && __pXvImage->data_size != currentSourceBufferSize->GetCapacity()) )
631         {
632                 if (__xvPort != -1)
633                 {
634                         UngrabXvPort();
635                 }
636
637                 if (__pXvImage != null)
638                 {
639                         if (__pShmInfo)
640                         {
641                                 XShmDetach(pDisplay, __pShmInfo);
642                                 shmdt(__pShmInfo->shmaddr);
643                                 shmctl(__pShmInfo->shmid, IPC_RMID, NULL);
644                                 delete __pShmInfo;
645                                 __pShmInfo = null;
646                         }
647
648                         if (__pXvImage)
649                         {
650                                 XFree(__pXvImage);
651                                 __pXvImage = null;
652                         }
653                 }
654         }
655
656         if (__xvPort == -1)
657         {
658                 result r = GrabXvPort();
659                 SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, E_SYSTEM, "Propagating.");
660         }
661
662         if (__needToRellaocImage)
663         {
664                 XShmSegmentInfo* pShmInfo = new (std::nothrow) XShmSegmentInfo();
665                 SysTryReturnResult(NID_UI_CTRL, pShmInfo != null, E_SYSTEM, "Failed to create XShmSegmentInfo");
666
667                 XvImage* pXvImage = XvShmCreateImage(pDisplay, __xvPort, __savedColorFormat, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height, pShmInfo);
668                 SysTryReturnResult(NID_UI_CTRL, pXvImage != null, E_SYSTEM, "Failed to create XvImage");
669
670                 pShmInfo->shmid = shmget(IPC_PRIVATE, pXvImage->data_size, IPC_CREAT | 0777);
671                 pShmInfo->shmaddr = pXvImage->data = (char*)shmat(pShmInfo->shmid, 0, 0);
672                 pShmInfo->readOnly = False;
673
674                 if (!XShmAttach(pDisplay, pShmInfo))
675                 {
676                         XFree(pXvImage);
677                         SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Failed to XShmAttach.");
678                         return E_SYSTEM;
679                 }
680
681                 __pXvImage = pXvImage;
682                 __pShmInfo = pShmInfo;
683         }
684
685         if (__pXvImage == null)
686         {
687                 SysLogException(NID_UI_CTRL, E_SYSTEM, "[E_SYSTEM] Failed to get XvImage");
688                 return E_SYSTEM;
689         }
690
691         memcpy(__pXvImage->data, __pCurrentSourceBuffer->GetPointer(), __pXvImage->data_size);
692         __pCurrentSourceBuffer = null;
693
694         int imageWidth = 0;
695         int imageHeight = 0;
696         evas_object_image_size_get(__pImageObject, &imageWidth, &imageHeight);
697
698         GC gc= DefaultGCOfScreen(DefaultScreenOfDisplay(pDisplay));
699         XvShmPutImage(pDisplay, __xvPort, __pixmap, gc, __pXvImage, 0, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height, 0, 0, imageWidth, imageHeight, False);
700         XSync(pDisplay, 0);
701
702         if (__needToRellaocImage)
703         {
704                 SysSecureLog(NID_UI_CTRL, "The current value of source buffer size is [%d,%d]", __currentSourceBufferSize.width, __currentSourceBufferSize.height);
705                 SysSecureLog(NID_UI_CTRL, "The current value of destination XvImage size is [%d,%d]", imageWidth, imageHeight);
706                 __needToRellaocImage = false;
707         }
708
709         result r = __pRendererVE->SetFlushNeeded();
710         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r,"[%s] Propagating.", GetErrorMessage(r));
711
712         return r;
713 }
714
715 result
716 _OverlayAgent::PutEvasImage(void)
717 {
718         SysTryReturnResult(NID_UI_CTRL, __pImageObject != null, E_SYSTEM, "The current value of Renderer ImageObject is null");
719         SysTryReturnResult(NID_UI_CTRL, __pCurrentSourceBuffer->GetPointer() != null, E_SYSTEM, "The current value of Renderer byte buffer is null");
720
721         result r = E_SUCCESS;
722
723         // Create new buffer to convert pixel format
724         if (__needToRellaocImage || __pConvertedSourceBuffer == null ||
725                 !(__pConvertedSourceBuffer && (__pConvertedSourceBuffer->GetCapacity() == __pCurrentSourceBuffer->GetCapacity())))
726         {
727                 if (__pConvertedSourceBuffer != null)
728                 {
729                         __pConvertedSourceBuffer->SetPosition(0);
730                         delete __pConvertedSourceBuffer;
731                         __pConvertedSourceBuffer = null;
732                 }
733
734                 __pConvertedSourceBuffer = new (std::nothrow) ByteBuffer;
735                 SysTryReturnResult(NID_UI_CTRL, __pConvertedSourceBuffer != null, E_OUT_OF_MEMORY, "Failed to create a ByteBuffer for Evas Image Object.");
736
737                 r = __pConvertedSourceBuffer->Construct(__currentSourceBufferSize.width * __currentSourceBufferSize.height * 4);
738                 if (r != E_SUCCESS)
739                 {
740                         delete __pConvertedSourceBuffer;
741                         __pConvertedSourceBuffer = null;
742                         SysLogException(NID_UI_CTRL, r, "[%s] Failed to construct a byte buffer for EvasImageObject.", GetErrorMessage(r));
743
744                         return r;
745                 }
746         }
747
748         __pConvertedSourceBuffer->SetPosition(0);
749
750         switch (__currentColorFormat)
751         {
752         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888:
753                 r = __pConvertedSourceBuffer->SetArray(__pCurrentSourceBuffer->GetPointer(), 0, __pConvertedSourceBuffer->GetCapacity());
754                 break;
755         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_RGB565:
756                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_RGB565LE, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
757                 break;
758         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_YCbCr420_PLANAR:
759                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_YUV420P, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
760                 break;
761         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_NV12:
762                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_NV12, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
763                 break;
764         case _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY:
765                 r = _ImageUtil::ConvertPixelFormat(*__pCurrentSourceBuffer, MEDIA_PIXEL_FORMAT_UYVY422, __currentSourceBufferSize.width, __currentSourceBufferSize.height, *__pConvertedSourceBuffer, MEDIA_PIXEL_FORMAT_BGRA8888);
766                 break;
767         default:
768                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The specified pixel format is not supported.");
769                 return E_UNSUPPORTED_FORMAT;
770         }
771
772         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r,"Propagating.");
773
774         __pCurrentSourceBuffer = null;
775         void* pImageData = (void*)(__pConvertedSourceBuffer->GetPointer());
776         SysTryReturnResult(NID_UI_CTRL, pImageData != null, E_SYSTEM, "The converted image data for Overlay Renderer VisualElement is invalid.");
777
778         evas_object_image_size_set(__pImageObject, __currentSourceBufferSize.width, __currentSourceBufferSize.height);
779         evas_object_image_data_set(__pImageObject, pImageData);
780         evas_object_image_data_update_add(__pImageObject, 0, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height);
781         evas_object_show(__pImageObject);
782
783         if (__needToRellaocImage)
784         {
785                 SysSecureLog(NID_UI_CTRL, "The current value of source buffer bounds is [%d,%d,%d, %d]", 0, 0, __currentSourceBufferSize.width, __currentSourceBufferSize.height);
786                 __needToRellaocImage = false;
787         }
788
789         r = __pRendererVE->SetFlushNeeded();
790         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r,"[%s] Propagating.", GetErrorMessage(r));
791
792         return r;
793 }
794
795 result
796 _OverlayAgent::SetRendererFlushNeeded(void)
797 {
798         return __pRendererVE->SetFlushNeeded();
799 }
800
801 result
802 _OverlayAgent::SetRotation(_OverlayAgentRotation rotation)
803 {
804         SysTryReturnResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "The Renderer Visual Element is null");
805         SysTryReturnResult(NID_UI_CTRL, rotation < _OVERLAY_AGENT_ROTATION_MAX, E_INVALID_ARG, "The value of input rotation [%d] is invalid.", rotation);
806
807         if (rotation == __currentRotation)
808         {
809                 return E_SUCCESS;
810         }
811
812         float initialZAngle = __pRendererVE->GetProperty(L"transform.rotation.z").ToFloat();
813         float rotatedZAngle = initialZAngle;
814
815         switch (rotation)
816         {
817         case _OVERLAY_AGENT_ROTATION_NONE: // fall through
818         case _OVERLAY_AGENT_ROTATION_NONE_LR: // fall through
819         case _OVERLAY_AGENT_ROTATION_NONE_UD:
820                 rotatedZAngle = 0.0f;
821                 break;
822
823         case _OVERLAY_AGENT_ROTATION_90: // fall through
824         case _OVERLAY_AGENT_ROTATION_90_LR: // fall through
825         case _OVERLAY_AGENT_ROTATION_90_UD:
826                 rotatedZAngle = 90.0f;
827                 break;
828
829         case _OVERLAY_AGENT_ROTATION_180: // fall through
830         case _OVERLAY_AGENT_ROTATION_180_LR: // fall through
831         case _OVERLAY_AGENT_ROTATION_180_UD:
832                 rotatedZAngle = 180.0f;
833                 break;
834
835         case _OVERLAY_AGENT_ROTATION_270: // fall through
836         case _OVERLAY_AGENT_ROTATION_270_LR: // fall through
837         case _OVERLAY_AGENT_ROTATION_270_UD:
838                 rotatedZAngle = 270.0f;
839                 break;
840
841         default:
842                 break;
843         }
844
845         //Set bounds of rotated renderer
846         FloatRectangle rendererBounds = __standardRendererBounds;
847         if (rotatedZAngle == 90.0f || rotatedZAngle == 270.0f )
848         {
849                 rendererBounds.x = __standardRendererBounds.x - ((__standardRendererBounds.height - __standardRendererBounds.width) / 2.0f);
850                 rendererBounds.y = __standardRendererBounds.y + ((__standardRendererBounds.height - __standardRendererBounds.width) / 2.0f);
851                 std::swap(rendererBounds.height, rendererBounds.width);
852         }
853
854         result r = __pRendererVE->SetBounds(rendererBounds);
855         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
856
857         r = __pRendererVE->SetProperty(L"transform.rotation.z", rotatedZAngle);
858         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
859         SysLog(NID_UI_CTRL, "The current Overlay Renderer is rotated (%d -> %d)", static_cast<int>(initialZAngle), static_cast<int>(rotatedZAngle));
860
861         switch (rotation)
862         {
863         case _OVERLAY_AGENT_ROTATION_NONE: // fall through
864         case _OVERLAY_AGENT_ROTATION_90: // fall through
865         case _OVERLAY_AGENT_ROTATION_180: // fall through
866         case _OVERLAY_AGENT_ROTATION_270:
867                 r = __pRendererVE->SetProperty(L"transform.rotation.x", 0.0f);
868                 r = __pRendererVE->SetProperty(L"transform.rotation.y", 0.0f);
869                 break;
870
871         case _OVERLAY_AGENT_ROTATION_NONE_UD: // fall through
872         case _OVERLAY_AGENT_ROTATION_180_UD: // fall through
873         case _OVERLAY_AGENT_ROTATION_90_LR: // fall through
874         case _OVERLAY_AGENT_ROTATION_270_LR:
875                 r = __pRendererVE->SetProperty(L"transform.rotation.x", 180.0f);
876                 r = __pRendererVE->SetProperty(L"transform.rotation.y", 0.0f);
877                 SysLog(NID_UI_CTRL, "The current Overlay Renderer is flipped over up side down.");
878                 break;
879
880         case _OVERLAY_AGENT_ROTATION_NONE_LR: // fall through
881         case _OVERLAY_AGENT_ROTATION_180_LR: // fall through
882         case _OVERLAY_AGENT_ROTATION_90_UD: // fall through
883         case _OVERLAY_AGENT_ROTATION_270_UD:
884                 r = __pRendererVE->SetProperty(L"transform.rotation.x", 0.0f);
885                 r = __pRendererVE->SetProperty(L"transform.rotation.y", 180.0f);
886                 SysLog(NID_UI_CTRL, "The current Overlay Renderer is flipped over left side right.");
887                 break;
888
889         default:
890                 break;
891         }
892         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
893
894         __currentRotation = rotation;
895
896         r = __pRendererVE->SetFlushNeeded();
897         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
898
899         return r;
900 }
901
902 result
903 _OverlayAgent::SetDestination(const FloatDimension& dimension)
904 {
905         SysTryReturnResult(NID_UI_CTRL, __pParentVE != null, E_SYSTEM, "The Renderer Visual Element is null");
906         SysTryReturnResult(NID_UI_CTRL, __pRendererVE != null, E_SYSTEM, "The Renderer Visual Element is null");
907         if (__standardRendererBounds.width == dimension.width && __standardRendererBounds.height == dimension.height &&
908                 __standardParentBounds.width == __pParentVE->GetBounds().width && __standardParentBounds.height == __pParentVE->GetBounds().height)
909         {
910                 return E_SUCCESS;
911         }
912
913         //Set bounds of saved renderer
914         FloatRectangle parentBounds= __pParentVE->GetBounds();
915
916         if (parentBounds.width >= dimension.width)
917         {
918                 __standardRendererBounds.x = (parentBounds.width - dimension.width) / 2.0f;
919                 __standardRendererBounds.width = dimension.width;
920         }
921         else
922         {
923                 __standardRendererBounds.x = 0.0f;
924                 __standardRendererBounds.width = parentBounds.width;
925         }
926
927         if (parentBounds.height >= dimension.height)
928         {
929                 __standardRendererBounds.y = (parentBounds.height - dimension.height) / 2.0f;
930                 __standardRendererBounds.height = dimension.height;
931         }
932         else
933         {
934                 __standardRendererBounds.y = 0.0f;
935                 __standardRendererBounds.height = parentBounds.height;
936         }
937
938         //Set bounds of resizing renderer
939         float parentWidth = parentBounds.width;
940         float parentHeight = parentBounds.height;
941         FloatDimension inputDimension(dimension.width, dimension.height);
942
943         Variant rotationAngle = __pRendererVE->GetProperty(L"transform.rotation.z");
944         if(rotationAngle.ToFloat() == 90.0f || rotationAngle.ToFloat() == 270.0f)
945         {
946                 std::swap(parentWidth, parentHeight);
947                 std::swap(inputDimension.width, inputDimension.height);
948         }
949
950         FloatRectangle rendererBounds = __standardRendererBounds;
951
952         if (parentWidth >= inputDimension.width)
953         {
954                 rendererBounds.x = (parentBounds.width - inputDimension.width) / 2.0f;
955                 rendererBounds.width = inputDimension.width;
956         }
957         else
958         {
959                 rendererBounds.x = 0.0f;
960                 rendererBounds.width = parentBounds.width;
961         }
962
963         if (parentHeight >= inputDimension.height)
964         {
965                 rendererBounds.y = (parentBounds.height - inputDimension.height) / 2.0f;
966                 rendererBounds.height = inputDimension.height;
967         }
968         else
969         {
970                 rendererBounds.y = 0.0f;
971                 rendererBounds.height = parentBounds.height;
972         }
973         SysLog(NID_UI_CTRL, "The current bounds of resized renderer is [%.3f, %.3f, %.3f, %.3f]",
974                 __standardRendererBounds.x, __standardRendererBounds.y, __standardRendererBounds.width, __standardRendererBounds.height);
975
976         result r = __pRendererVE->SetBounds(rendererBounds);
977         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
978
979         r = __pRendererVE->SetFlushNeeded();
980         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
981
982         __standardParentBounds = __pParentVE->GetBounds();
983
984         return r;
985 }
986
987 result
988 _OverlayAgent::SetAspectRatio(bool enable)
989 {
990         return E_SUCCESS;
991 }
992
993 FloatRectangle
994 _OverlayAgent::GetBounds(void) const
995 {
996         SysTryReturn(NID_UI_CTRL, __pRendererVE != null, FloatRectangle(0.0f, 0.0f, 0.1f, 0.1f), E_SYSTEM, "The Renderer Visual Element is null");
997         return __standardRendererBounds;
998 }
999
1000 result
1001 _OverlayAgent::CreateRendererVisualElement(const _Control& parentControl, const FloatRectangle& logicalBounds, const Rectangle& physicalBounds)
1002 {
1003
1004         //Create new VisualElement and insert it to Parent's VisualElement
1005         unique_ptr<_OverlayVisualElement, visualElementDeleter> pRendererVE(new (std::nothrow) _OverlayVisualElement());
1006         SysTryReturnResult(NID_UI_CTRL, pRendererVE != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
1007
1008         result r = pRendererVE->Construct();
1009         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1010
1011         pRendererVE->SetName("OverlayRenderer");
1012         pRendererVE->SetShowState(true);
1013         //pRendererVE->SetImplicitAnimationEnabled(true);
1014         pRendererVE->SetImplicitAnimationEnabled(false);
1015         pRendererVE->SetZOrderGroup(_CONTROL_LAYER_OVERLAY);
1016
1017         FloatPoint logicalPoint(0.0f, 0.0f);
1018         if(__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_REGION_GL)
1019         {
1020                 logicalPoint.x = logicalBounds.x;
1021                 logicalPoint.y = logicalBounds.y;
1022         }
1023         pRendererVE->SetBounds(FloatRectangle(logicalPoint.x, logicalPoint.y, logicalBounds.width, logicalBounds.height));
1024
1025
1026         __pParentVE = parentControl.GetVisualElement();
1027         SysTryReturnResult(NID_UI_CTRL, __pParentVE != null, E_SYSTEM, "[E_SYSTEM] The current value of OverlayPanel's VisualElement is null.");
1028
1029         __pParentVE->SetName("OverlayPanel");
1030         r = __pParentVE->InsertChild(pRendererVE.get(), null, true);
1031         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1032
1033         r = __pParentVE->SetSurfaceOpaque(true);
1034         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1035
1036
1037         // Get and Set ImageObject of Renderer VisualElement
1038         _EflNode* pEflNode = dynamic_cast<_EflNode*>(pRendererVE->GetNativeNode());
1039         SysTryReturnResult(NID_UI_CTRL, pEflNode != null, E_SYSTEM, "Failed to get EflNode from Renderer VisualElement.");
1040
1041         Evas_Object* pSmartObject = (Evas_Object*) pEflNode->GetGroupContainer();
1042         SysTryReturnResult(NID_UI_CTRL, pSmartObject != null, E_SYSTEM, "Failed to get Group Container of Renderer VisualElement.");
1043
1044         Evas* pEvas = evas_object_evas_get(pSmartObject);
1045         SysTryReturnResult(NID_UI_CTRL, pEvas != null, E_SYSTEM, "Failed to get Evas of Renderer VisualElement.");
1046
1047         Ecore_Evas* pEcoreEvas = ecore_evas_ecore_evas_get(pEvas);
1048         SysTryReturnResult(NID_UI_CTRL, pEcoreEvas != null, E_SYSTEM, "Failed to get Ecore Evas of Renderer VisualElement.");
1049
1050         __pImageObject = evas_object_image_add(pEvas);
1051         SysTryReturnResult(NID_UI_CTRL, __pImageObject != null, E_SYSTEM, "Failed to get Renderer Image Object.");
1052
1053         evas_object_name_set(__pImageObject, "OverlayRenderer");
1054         evas_object_image_size_set(__pImageObject, physicalBounds.width, physicalBounds.height);
1055         evas_object_image_alpha_set(__pImageObject, false);
1056         evas_object_image_filled_set(__pImageObject, EINA_TRUE);
1057         evas_object_resize(__pImageObject, physicalBounds.width, physicalBounds.height);
1058         evas_object_move(__pImageObject, physicalBounds.x, physicalBounds.y);
1059         evas_object_show(__pImageObject);
1060         pRendererVE->SetImageObject(__pImageObject);
1061
1062
1063         DisplayContext* pDisplayContext = parentControl.GetRootWindow()->GetDisplayContext();
1064         SysTryReturnResult(NID_UI_CTRL, pDisplayContext != null, E_SYSTEM, "[E_SYSTEM] The current value of RootWindow's DisplayContext is null.");
1065
1066         unique_ptr<VisualElementSurface> pRendererSurface(_VisualElementSurfaceImpl::CreateSurfaceUsingExistingObjectN(*pDisplayContext, (Handle)__pImageObject, Dimension(physicalBounds.width, physicalBounds.height)));
1067         SysTryReturnResult(NID_UI_CTRL, pRendererSurface != null, E_SYSTEM, "[E_SYSTEM] The current value of RootWindow's DisplayContext is null.");
1068
1069         r = pRendererVE->SetSurface(pRendererSurface.release());
1070         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1071
1072         r = pRendererVE->SetFlushNeeded();
1073         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1074
1075         pRendererVE->SetAnchor(FloatPoint(0.5f, 0.5f));
1076         __pRendererVE = pRendererVE.release();
1077         __standardRendererBounds = __pRendererVE->GetBounds();
1078
1079         if (__style == _OVERLAY_AGENT_STYLE_REGION_SW || __style == _OVERLAY_AGENT_STYLE_PANEL_SW)
1080         {
1081                 evas_object_image_pixels_get_callback_set(__pImageObject, OnEvasImageDamaged,(void*)this);
1082         }
1083
1084         return r;
1085 }
1086
1087 result
1088 _OverlayAgent::CreatePixmap(const Rectangle& physicalBounds)
1089 {
1090         //Set size of pixmap
1091         Dimension pixmapSize(physicalBounds.width, physicalBounds.height);
1092         SysTryReturnResult(NID_UI_CTRL, (pixmapSize.width >= GetDstRectMinWidth()) && (pixmapSize.height >= GetDstRectMinHeight()),
1093                 E_SYSTEM, "input size (%d, %d) is too small to create a pixmap",pixmapSize.width, pixmapSize.height);
1094
1095         // Create pixmap
1096         Display *pDisplay = (Display*)ecore_x_display_get();
1097         SysTryReturnResult(NID_UI_CTRL, pDisplay != null, E_SYSTEM, "The current value of Display is null");
1098
1099         __pixmap = XCreatePixmap(pDisplay, DefaultRootWindow(pDisplay), pixmapSize.width, pixmapSize.height, DefaultDepth(pDisplay, DefaultScreen(pDisplay)));
1100         SysTryReturnResult(NID_UI_CTRL, __pixmap != 0, E_SYSTEM, "Failed to create a pixmap of Overlay Agent");
1101
1102         GC gc = XCreateGC(pDisplay, __pixmap, 0,0);
1103         SysTryReturnResult(NID_UI_CTRL, gc > 0, E_SYSTEM, "Failed to create Graphic Contexts");
1104
1105         //Set initial color
1106         XSetForeground(pDisplay, gc, (long unsigned int)(Color(0xff000000).GetRGB32()));
1107         XFillRectangle(pDisplay, __pixmap, gc, 0, 0, pixmapSize.width, pixmapSize.height);
1108         XSync(pDisplay, 0);
1109         XFreeGC(pDisplay, gc);
1110
1111         //Set evas native surface
1112         Evas_Native_Surface evasNativeSuface = {0,};
1113
1114         evasNativeSuface.version = EVAS_NATIVE_SURFACE_VERSION;
1115         evasNativeSuface.type = EVAS_NATIVE_SURFACE_X11;
1116         evasNativeSuface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get());
1117         evasNativeSuface.data.x11.pixmap = __pixmap;
1118
1119         evas_object_lower(__pImageObject);
1120         evas_object_image_native_surface_set(__pImageObject, &evasNativeSuface);
1121
1122         __pixmapDamageHandle = ecore_x_damage_new(__pixmap, ECORE_X_DAMAGE_REPORT_RAW_RECTANGLES);
1123         SysTryCatch(NID_UI_CTRL, __pixmapDamageHandle != 0, , E_SYSTEM, "[E_SYSTEM] Failed to create a damage object");
1124
1125         __pPixmapEventHandler = ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY, OnPixmapDamaged, (void*)this);
1126         SysTryCatch(NID_UI_CTRL, __pPixmapEventHandler != null, , E_SYSTEM, "[E_SYSTEM] Failed to add a pixmap damage event handle");
1127
1128         return E_SUCCESS;
1129
1130 CATCH:
1131         if (__pPixmapEventHandler)
1132         {
1133                 ecore_event_handler_del(__pPixmapEventHandler);
1134                 __pPixmapEventHandler = null;
1135         }
1136
1137         if (__pixmapDamageHandle)
1138         {
1139                 ecore_x_damage_free(__pixmapDamageHandle);
1140                 __pixmapDamageHandle = 0;
1141         }
1142
1143         if (__pixmap)
1144         {
1145                 XFreePixmap((Display*)ecore_x_display_get(), __pixmap);
1146                 __pixmap = 0;
1147         }
1148
1149         return E_SYSTEM;
1150 }
1151
1152 Pixmap
1153 _OverlayAgent::GetPixmap(void) const
1154 {
1155         return __pixmap;
1156 }
1157
1158 Evas_Object*
1159 _OverlayAgent::GetRendererImageObject(void) const
1160 {
1161         return __pImageObject;
1162 }
1163
1164 bool
1165 _OverlayAgent::IsValidDestinationDimension(const FloatDimension& dimension) const
1166 {
1167         FloatDimension physicalDimensionF = _CoordinateSystemUtils::Transform(dimension);
1168         Dimension physicalDimension = _CoordinateSystemUtils::ConvertToInteger(physicalDimensionF);
1169         SysTryReturn(NID_UI_CTRL, (physicalDimension.width >= GetDstRectMinWidth() && physicalDimension.height >= GetDstRectMinHeight()), false, E_INVALID_ARG,
1170                         "[E_INVALID_ARG] The size of input dimension (logical size : [%.3f, %.3f], physical size : [%d,%d]) is under minimun size."
1171                         ,dimension.width, dimension.height, physicalDimension.width, physicalDimension.height);
1172
1173         FloatRectangle parentBounds = __pParentVE->GetBounds();
1174         SysTryReturn(NID_UI_CTRL, (dimension.width <= parentBounds.width || dimension.height <= parentBounds.height), false, E_INVALID_ARG,
1175                         "[E_INVALID_ARG] The size of input dimension[%.3f, %.3f] is over maximum size[%.3f,%.3f]."
1176                         ,dimension.width, dimension.height, parentBounds.width, parentBounds.height);
1177
1178         return true;
1179 }
1180
1181 int
1182 _OverlayAgent::GetOverlayAgentCount(void)
1183 {
1184         return __overlayAgentCount;
1185 }
1186
1187 IListT<bool>*
1188 _OverlayAgent::GetPixelFormatListN(void)
1189 {
1190         if (!__OverlayAgentBufferPixelFormat[0])
1191         {
1192                 const wchar_t* _UI_REGISTRY_PATH = L"/usr/etc/system-info.ini";
1193                 const wchar_t* _UI_INFO_SESSION = L"UiControlInfo";
1194
1195                 _RegistryImpl registry;
1196                 result r = registry.Construct(_UI_REGISTRY_PATH, REG_OPEN_READ_ONLY, null);
1197                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1198
1199                 String pixelFormatList(null);
1200                 r = registry.GetValue(_UI_INFO_SESSION, L"OverlayRegionBufferPixelFormat", pixelFormatList);
1201                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1202
1203                 bool set = false;
1204                 if (pixelFormatList.Contains(L"ARGB8888"))
1205                 {
1206                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888] = true;
1207                         set = true;
1208                 }
1209
1210                 if (pixelFormatList.Contains(L"RGB565"))
1211                 {
1212                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_RGB565] = true;
1213                         set = true;
1214                 }
1215
1216                 if (pixelFormatList.Contains(L"YCbCr420P"))
1217                 {
1218                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_YCbCr420_PLANAR] = true;
1219                         set = true;
1220                 }
1221
1222                 if (pixelFormatList.Contains(L"NV12"))
1223                 {
1224                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_NV12] = true;
1225                         set = true;
1226                 }
1227
1228                 if (pixelFormatList.Contains(L"UYVY"))
1229                 {
1230                         __OverlayAgentBufferPixelFormat[_OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY] = true;
1231                         set = true;
1232                 }
1233
1234                 SysAssertf(set, "The registry file is an invalid.");
1235
1236                 __OverlayAgentBufferPixelFormat[0] = set;
1237         }
1238
1239         std::unique_ptr< ArrayListT<bool> > pFormatList( new (std::nothrow) ArrayListT<bool>());
1240         SysTryReturn(NID_UI_CTRL, pFormatList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] failed to create a list instance");
1241
1242         result r = pFormatList->Construct();
1243         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1244
1245         for (int index = _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_ARGB8888; index <= _OVERLAY_AGENT_BUFFER_PIXEL_FORMAT_UYVY; index++)
1246         {
1247                 r = pFormatList->Add(__OverlayAgentBufferPixelFormat[index]);
1248         }
1249         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1250
1251         return pFormatList.release();
1252 }
1253
1254 result
1255 _OverlayAgent::EvaluateBounds(OverlayAgentEvaluationOption option, FloatRectangle& rect, bool& modified)
1256 {
1257         modified = false;
1258         SysTryReturnResult(NID_UI_CTRL, rect.width > 0.0f && rect.height > 0.0f,
1259                 E_INVALID_ARG, "The size of input rectangle(%.3f, %.3f) is invalid.", rect.width, rect.height);
1260
1261         Rectangle logicalEvaluatingBounds = _CoordinateSystemUtils::ConvertToInteger(rect);
1262         SysTryReturnResult(NID_UI_CTRL, logicalEvaluatingBounds.width > 0 && logicalEvaluatingBounds.height > 0,
1263                 E_INVALID_ARG, "The size of logical rectangle(%d, %d) is invalid.", logicalEvaluatingBounds.width, logicalEvaluatingBounds.height);
1264
1265         Rectangle physicalRect(_CoordinateSystemUtils::Transform(logicalEvaluatingBounds));
1266         SysTryReturnResult(NID_UI_CTRL, physicalRect.width > 0 && physicalRect.height > 0,
1267                 E_INVALID_ARG, "The size of physical rectangle(%d, %d) is invalid.", physicalRect.width, physicalRect.height);
1268
1269         int physicalMinWidth = GetDstRectMinWidth();
1270         int physicalMinHeight = GetDstRectMinHeight();
1271         SysTryReturnResult(NID_UI_CTRL, physicalMinWidth > 0 && physicalMinHeight > 0, E_SYSTEM, "The value of overlay control's Min width and Min height are invalid.");
1272
1273         const int widthUnit = GetWidthUnit();
1274         const int heightUnit = GetHeightUnit();
1275         SysTryReturnResult(NID_UI_CTRL, widthUnit > 0 && heightUnit > 0, E_SYSTEM, "The value of overlay control's width Unit and height Unit are invalid.");
1276
1277         int screenWidth = _Screen::GetWidth();
1278         int screenHeight = _Screen::GetHeight();
1279         SysTryReturnResult(NID_UI_CTRL, screenWidth > 0 && screenHeight > 0, E_SYSTEM, "The value of screen size is invalid.");
1280
1281         //If orientation status of screen is landscape mode, swap width and height.
1282         {
1283                 _EcoreEvas* pEcoreEvas = GetEcoreEvasMgr()->GetEcoreEvas();
1284                 int orientation = ecore_evas_rotation_get(pEcoreEvas->GetEcoreEvas());
1285
1286                 if (orientation == 90 || orientation == 270)
1287                 {
1288                         int temp = screenWidth;
1289                         screenWidth = screenHeight;
1290                         screenHeight = temp;
1291                         SysSecureLog(NID_UI_CTRL, "The current value of device screen width is %d, device screen height is %d and orientation is %d", screenWidth, screenHeight, orientation);
1292                 }
1293         }
1294
1295         int physicalMaxWidth= screenWidth - (screenWidth % widthUnit);
1296         int physicalMaxHeight = screenHeight - (screenHeight % heightUnit);
1297         int logicalMaxWidth = _CoordinateSystemUtils::InverseHorizontalTransform(physicalMaxWidth);
1298         int logicalMaxHeight = _CoordinateSystemUtils::InverseVerticalTransform(physicalMaxHeight);
1299
1300         int widthReminder = physicalRect.width % widthUnit;
1301         int heightReminder = physicalRect.height % heightUnit;
1302
1303         //Fix one pixel error when coordinate system transform
1304         if (widthReminder == 1)
1305         {
1306                 physicalRect.width -= 1;
1307                 widthReminder = physicalRect.width % widthUnit;
1308         }
1309
1310         if (heightReminder == 1)
1311         {
1312                 physicalRect.height -= 1;
1313                 heightReminder = physicalRect.height % heightUnit;
1314         }
1315
1316         switch (option)
1317         {
1318         case OVERLAY_AGENT_EVALUATION_OPTION_GREATER_THAN:
1319                 {
1320                         if (logicalEvaluatingBounds.width > logicalMaxWidth || logicalEvaluatingBounds.height > logicalMaxHeight)
1321                         {
1322                                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The size of input rect exceeds logical maximun size.");
1323                                 return E_UNSUPPORTED_OPTION;
1324                         }
1325
1326                         if (physicalRect.width > physicalMaxWidth || physicalRect.height > physicalMaxHeight)
1327                         {
1328                                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The size of input rect exceeds physical maximun size.");
1329                                 return E_UNSUPPORTED_OPTION;
1330                         }
1331
1332                         if (widthReminder != 0)
1333                         {
1334                                 widthReminder -= widthUnit;
1335                         }
1336
1337                         if (heightReminder != 0)
1338                         {
1339                                 heightReminder -= heightUnit;
1340                         }
1341
1342                         physicalRect.width -= widthReminder;
1343                         physicalRect.height -= heightReminder;
1344
1345                         if (physicalRect.width < physicalMinWidth)
1346                         {
1347                                 physicalRect.width = physicalMinWidth;
1348                         }
1349
1350                         if (physicalRect.height < physicalMinHeight)
1351                         {
1352                                 physicalRect.height = physicalMinHeight;
1353                         }
1354                 }
1355                 break;
1356         case OVERLAY_AGENT_EVALUATION_OPTION_LESS_THAN:
1357                 {
1358                         if (physicalRect.width < physicalMinWidth || physicalRect.height < physicalMinHeight)
1359                         {
1360                                 SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The size of input rect is under minimun size.");
1361
1362                                 return E_UNSUPPORTED_OPTION;
1363                         }
1364
1365                         if (physicalRect.width > physicalMaxWidth)
1366                         {
1367                                 physicalRect.width = physicalMaxWidth + widthReminder;
1368                         }
1369
1370                         if (physicalRect.height > physicalMaxHeight)
1371                         {
1372                                 physicalRect.height = physicalMaxHeight + heightReminder;
1373                         }
1374
1375                         physicalRect.width -= widthReminder;
1376                         physicalRect.height -= heightReminder;
1377                 }
1378                 break;
1379         default:
1380                 {
1381                         SysLogException(NID_UI_CTRL, E_UNSUPPORTED_OPTION, "[E_UNSUPPORTED_OPTION] The input option is an invalid.");
1382
1383                         return E_UNSUPPORTED_OPTION;
1384                 }
1385         }
1386
1387         FloatRectangle originalInputRect(rect);
1388         rect = _CoordinateSystemUtils::ConvertToFloat(_CoordinateSystemUtils::InverseTransform(physicalRect));
1389
1390         if (rect != originalInputRect)
1391         {
1392                 modified = true;
1393                 SysLog(NID_UI_CTRL, "The input bounds [%.3f, %.3f, %.3f, %.3f] is modified to [%.3f, %.3f, %.3f, %.3f]",
1394                                 originalInputRect.x, originalInputRect.y, originalInputRect.width, originalInputRect.height,
1395                                 rect.x, rect.y, rect.width, rect.height);
1396         }
1397         else
1398         {
1399                 SysLog(NID_UI_CTRL, "The evaluated bounds [%.3f, %.3f, %.3f, %.3f] is valid.",
1400                         rect.x, rect.y, rect.width, rect.height);
1401         }
1402
1403         result r = GetLastResult();
1404         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "Propagating.");
1405
1406         return r;
1407 }
1408
1409 int
1410 _OverlayAgent::GetValueFromRegistry(const String& key)
1411 {
1412         const wchar_t* _UI_REGISTRY_PATH = L"/usr/etc/system-info.ini";
1413         const wchar_t* _UI_INFO_SESSION = L"UiControlInfo";
1414
1415         _RegistryImpl registry;
1416         result r = registry.Construct(_UI_REGISTRY_PATH, REG_OPEN_READ_ONLY, null);
1417         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
1418
1419         String strValue(null);
1420         r = registry.GetValue(_UI_INFO_SESSION, key, strValue);
1421         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
1422
1423         int value;
1424         r = Integer::Parse(strValue, value);
1425         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
1426
1427         return value;
1428 }
1429
1430 int
1431 _OverlayAgent::GetDstRectMinWidth(void)
1432 {
1433         if (__dstRectMinWidth < 0)
1434         {
1435                 int value = GetValueFromRegistry(L"OverlayDstMinWidth");
1436                 SysTryReturn(NID_UI_CTRL, value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1437
1438                 __dstRectMinWidth = value;
1439                 SysLog(NID_UI_CTRL, "The overlay control's minimum width of destination is [%d]", __dstRectMinWidth);
1440         }
1441
1442         SetLastResult(E_SUCCESS);
1443
1444         return __dstRectMinWidth;
1445 }
1446
1447 int
1448 _OverlayAgent::GetDstRectMinHeight(void)
1449 {
1450         if (__dstRectMinHegith < 0)
1451         {
1452                 int value = GetValueFromRegistry(L"OverlayDstMinHeight");
1453                 SysTryReturn(NID_UI_CTRL, value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1454
1455                 __dstRectMinHegith = value;
1456                 SysLog(NID_UI_CTRL, "The overlay control's minimum height of destination is [%d]", __dstRectMinHegith);
1457         }
1458
1459         SetLastResult(E_SUCCESS);
1460
1461         return __dstRectMinHegith;
1462 }
1463
1464 int
1465 _OverlayAgent::GetSrcRectMinWidth(void)
1466 {
1467         if (__srcRectMinWidth < 0)
1468         {
1469                 int value = GetValueFromRegistry(L"OverlaySrcMinWidth");
1470                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1471
1472                 __srcRectMinWidth = value;
1473                 SysLog(NID_UI_CTRL, "The overlay control's minimum width of source buffer is [%d]", __srcRectMinWidth);
1474         }
1475
1476         SetLastResult(E_SUCCESS);
1477
1478         return __srcRectMinWidth;
1479 }
1480
1481 int
1482 _OverlayAgent::GetSrcRectMinHeight(void)
1483 {
1484         if (__srcRectMinHegith < 0)
1485         {
1486                 int value = GetValueFromRegistry(L"OverlaySrcMinHeight");
1487                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1488
1489                 __srcRectMinHegith = value;
1490                 SysLog(NID_UI_CTRL, "The overlay control's minimum height of source buffer is [%d]", __srcRectMinHegith);
1491         }
1492
1493         SetLastResult(E_SUCCESS);
1494
1495         return __srcRectMinHegith;
1496 }
1497
1498 int
1499 _OverlayAgent::GetWidthUnit(void)
1500 {
1501         if (__overlayWidthUnit < 0)
1502         {
1503                 int value = GetValueFromRegistry(L"OverlayRegionWidthUnit");
1504                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1505
1506                 __overlayWidthUnit = value;
1507                 SysLog(NID_UI_CTRL, "The overlay control's unit width is [%d]", __overlayWidthUnit);
1508         }
1509
1510         SetLastResult(E_SUCCESS);
1511
1512         return __overlayWidthUnit;
1513 }
1514
1515 int
1516 _OverlayAgent::GetHeightUnit(void)
1517 {
1518         if (__overlayHeightUnit < 0)
1519         {
1520                 int value = GetValueFromRegistry(L"OverlayRegionHeightUnit");
1521                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1522
1523                 __overlayHeightUnit = value;
1524                 SysLog(NID_UI_CTRL, "The overlay control's unit height is [%d]", __overlayHeightUnit);
1525         }
1526
1527         SetLastResult(E_SUCCESS);
1528
1529         return __overlayHeightUnit;
1530 }
1531
1532 int
1533 _OverlayAgent::GetMaxCount(void)
1534 {
1535         if (__overlayMaxCount < 0)
1536         {
1537                 int value = GetValueFromRegistry(L"MaxOverlayRegionCount");
1538                 SysTryReturn(NID_UI_CTRL,  value > 0, -1, E_SYSTEM, "[E_SYSTEM] Failed to get Overlay info from registry");
1539
1540                 __overlayMaxCount = value;
1541                 SysLog(NID_UI_CTRL, "The overlay control's maximum count is [%d]", __overlayMaxCount);
1542         }
1543
1544         SetLastResult(E_SUCCESS);
1545
1546         return __overlayMaxCount;
1547 }
1548 }}} // Tizen::Ui
1549