Revert "[Tizen] Add to get the status whether window is rotating or not"
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-render-surface.cpp
index 98afcfc..a0523d3 100644 (file)
@@ -79,6 +79,45 @@ void InsertRects(WindowRenderSurface::DamagedRectsContainer& damagedRectsList, c
   }
 }
 
+Rect<int32_t> RecalculateRect0(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  return rect;
+}
+
+Rect<int32_t> RecalculateRect90(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  Rect<int32_t> newRect;
+  newRect.x      = surfaceSize.height - (rect.y + rect.height);
+  newRect.y      = rect.x;
+  newRect.width  = rect.height;
+  newRect.height = rect.width;
+  return newRect;
+}
+
+Rect<int32_t> RecalculateRect180(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  Rect<int32_t> newRect;
+  newRect.x      = surfaceSize.width - (rect.x + rect.width);
+  newRect.y      = surfaceSize.height - (rect.y + rect.height);
+  newRect.width  = rect.width;
+  newRect.height = rect.height;
+  return newRect;
+}
+
+Rect<int32_t> RecalculateRect270(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  Rect<int32_t> newRect;
+  newRect.x      = rect.y;
+  newRect.y      = surfaceSize.width - (rect.x + rect.width);
+  newRect.width  = rect.height;
+  newRect.height = rect.width;
+  return newRect;
+}
+
+using RecalculateRectFunction = Rect<int32_t> (*)(Rect<int32_t>&, const Rect<int32_t>&);
+
+RecalculateRectFunction RecalculateRect[4] = {RecalculateRect0, RecalculateRect90, RecalculateRect180, RecalculateRect270};
+
 } // unnamed namespace
 
 WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any surface, bool isTransparent)
@@ -88,7 +127,7 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su
   mWindowBase(),
   mThreadSynchronization(nullptr),
   mRenderNotification(nullptr),
-  mRotationTrigger(nullptr),
+  mPostRenderTrigger(),
   mFrameRenderedTrigger(),
   mGraphics(nullptr),
   mEGLSurface(nullptr),
@@ -106,7 +145,9 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su
   mWindowRotationFinished(true),
   mScreenRotationFinished(true),
   mResizeFinished(true),
-  mDefaultScreenRotationAvailable(false)
+  mDefaultScreenRotationAvailable(false),
+  mIsImeWindowSurface(false),
+  mNeedWindowRotationAcknowledgement(false)
 {
   DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n");
   Initialize(surface);
@@ -114,10 +155,6 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su
 
 WindowRenderSurface::~WindowRenderSurface()
 {
-  if(mRotationTrigger)
-  {
-    delete mRotationTrigger;
-  }
 }
 
 void WindowRenderSurface::Initialize(Any surface)
@@ -174,22 +211,23 @@ void WindowRenderSurface::SetTransparency(bool transparent)
   mWindowBase->SetTransparency(transparent);
 }
 
-void WindowRenderSurface::RequestRotation(int angle, int width, int height)
+void WindowRenderSurface::RequestRotation(int angle, PositionSize positionSize)
 {
-  if(!mRotationTrigger)
+  if(!mPostRenderTrigger)
   {
-    mRotationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &WindowRenderSurface::ProcessRotationRequest), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
+    mPostRenderTrigger = std::unique_ptr<TriggerEventInterface>(TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &WindowRenderSurface::ProcessPostRender),
+                                                                                                      TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER));
   }
 
-  mPositionSize.width  = width;
-  mPositionSize.height = height;
+  mPositionSize = positionSize;
 
   mWindowRotationAngle    = angle;
   mWindowRotationFinished = false;
+  mResizeFinished         = false;
 
   mWindowBase->SetWindowRotationAngle(mWindowRotationAngle);
 
-  DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: angle = %d screen rotation = %d\n", mWindowRotationAngle, mScreenRotationAngle);
+  DALI_LOG_RELEASE_INFO("angle = %d screen rotation = %d, flag = %d\n", mWindowRotationAngle, mScreenRotationAngle, mWindowRotationFinished);
 }
 
 WindowBase* WindowRenderSurface::GetWindowBase()
@@ -234,15 +272,15 @@ int WindowRenderSurface::GetOrientation() const
 
 void WindowRenderSurface::InitializeGraphics()
 {
-  mGraphics = &mAdaptor->GetGraphicsInterface();
+  if(mEGLContext == NULL)
+  {
+    mGraphics = &mAdaptor->GetGraphicsInterface();
 
-  DALI_ASSERT_ALWAYS(mGraphics && "Graphics interface is not created");
+    DALI_ASSERT_ALWAYS(mGraphics && "Graphics interface is not created");
 
-  auto eglGraphics = static_cast<EglGraphics*>(mGraphics);
-  mEGL             = &eglGraphics->GetEglInterface();
+    auto eglGraphics = static_cast<EglGraphics*>(mGraphics);
+    mEGL             = &eglGraphics->GetEglInterface();
 
-  if(mEGLContext == NULL)
-  {
     // Create the OpenGL context for this window
     Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>(*mEGL);
     eglImpl.ChooseConfig(true, mColorDepth);
@@ -277,8 +315,9 @@ void WindowRenderSurface::CreateSurface()
   Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
   mEGLSurface                                   = eglImpl.CreateSurfaceWindow(window, mColorDepth);
 
-  DALI_LOG_RELEASE_INFO("WindowRenderSurface::CreateSurface: WinId (%d), w = %d h = %d angle = %d screen rotation = %d\n",
+  DALI_LOG_RELEASE_INFO("WindowRenderSurface::CreateSurface: WinId (%d), EGLSurface (%p), w = %d h = %d angle = %d screen rotation = %d\n",
                         mWindowBase->GetNativeWindowId(),
+                        mEGLSurface,
                         mPositionSize.width,
                         mPositionSize.height,
                         mWindowRotationAngle,
@@ -338,6 +377,41 @@ bool WindowRenderSurface::ReplaceGraphicsSurface()
   return eglImpl.ReplaceSurfaceWindow(window, mEGLSurface, mEGLContext);
 }
 
+void WindowRenderSurface::UpdatePositionSize(Dali::PositionSize positionSize)
+{
+  bool needToMove   = false;
+  bool needToResize = false;
+
+  // Check moving
+  if((fabs(positionSize.x - mPositionSize.x) >= MINIMUM_DIMENSION_CHANGE) ||
+     (fabs(positionSize.y - mPositionSize.y) >= MINIMUM_DIMENSION_CHANGE))
+  {
+    needToMove = true;
+  }
+
+  // Check resizing
+  if((fabs(positionSize.width - mPositionSize.width) >= MINIMUM_DIMENSION_CHANGE) ||
+     (fabs(positionSize.height - mPositionSize.height) >= MINIMUM_DIMENSION_CHANGE))
+  {
+    needToResize = true;
+  }
+
+  if(needToResize)
+  {
+    mResizeFinished = false;
+    mPositionSize   = positionSize;
+  }
+  else
+  {
+    if(needToMove)
+    {
+      mPositionSize = positionSize;
+    }
+  }
+
+  DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height);
+}
+
 void WindowRenderSurface::MoveResize(Dali::PositionSize positionSize)
 {
   bool needToMove   = false;
@@ -390,6 +464,10 @@ void WindowRenderSurface::StartRender()
 
 bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector<Rect<int>>& damagedRects, Rect<int>& clippingRect)
 {
+  InitializeGraphics();
+
+  mDamagedRects.assign(damagedRects.begin(), damagedRects.end());
+
   Dali::Integration::Scene::FrameCallbackContainer callbacks;
 
   Dali::Integration::Scene scene = mScene.GetHandle();
@@ -454,8 +532,6 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector<Rect
     }
   }
 
-  MakeContextCurrent();
-
   /**
     * wl_egl_window_tizen_set_rotation(SetEglWindowRotation)                -> PreRotation
     * wl_egl_window_tizen_set_buffer_transform(SetEglWindowBufferTransform) -> Screen Rotation
@@ -465,7 +541,7 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector<Rect
     *          because output transform event should be occured before egl window is not created.
     */
 
-  if(resizingSurface || mDefaultScreenRotationAvailable)
+  if(mIsResizing || mDefaultScreenRotationAvailable)
   {
     int totalAngle = (mWindowRotationAngle + mScreenRotationAngle) % 360;
 
@@ -505,19 +581,37 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector<Rect
       mWindowBase->ResizeEglWindow(positionSize);
       mResizeFinished = true;
 
-      DALI_LOG_RELEASE_INFO("WindowRenderSurface::PreRender: Set resize\n");
+      DALI_LOG_RELEASE_INFO("WindowRenderSurface::PreRender: Set resize, totalAngle: %d, x: %d, y: %d, w: %d, h:%d\n", totalAngle, positionSize.x, positionSize.y, positionSize.width, positionSize.height);
     }
 
     SetFullSwapNextFrame();
     mDefaultScreenRotationAvailable = false;
   }
 
-  SetBufferDamagedRects(damagedRects, clippingRect);
+  SetBufferDamagedRects(mDamagedRects, clippingRect);
+
+  if(scene)
+  {
+    Rect<int> surfaceRect = scene.GetCurrentSurfaceRect();
+    if(clippingRect == surfaceRect)
+    {
+      mDamagedRects.assign(1, surfaceRect);
+    }
+    else if(mDamagedRects.empty() && !clippingRect.IsEmpty())
+    {
+      // We will render clippingRect area but mDamagedRects is empty.
+      // So make mDamagedRects same with clippingRect to swap buffers.
+      mDamagedRects.assign(1, clippingRect);
+    }
+  }
+
+  // This is now done when the render pass for the render surface begins
+  //  MakeContextCurrent();
 
   return true;
 }
 
-void WindowRenderSurface::PostRender(bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector<Rect<int>>& damagedRects)
+void WindowRenderSurface::PostRender()
 {
   // Inform the gl implementation that rendering has finished before informing the surface
   auto eglGraphics = static_cast<EglGraphics*>(mGraphics);
@@ -526,37 +620,51 @@ void WindowRenderSurface::PostRender(bool renderToFbo, bool replacingSurface, bo
     GlImplementation& mGLES = eglGraphics->GetGlesInterface();
     mGLES.PostRender();
 
-    if(renderToFbo)
-    {
-      mGLES.Flush();
-      mGLES.Finish();
-    }
-    else
+    bool needWindowRotationCompleted = false;
+
+    if(!mWindowRotationFinished)
     {
-      if(resizingSurface)
+      if(mNeedWindowRotationAcknowledgement)
       {
-        if(!mWindowRotationFinished)
+        Dali::Integration::Scene scene = mScene.GetHandle();
+        if(scene)
         {
-          if(mThreadSynchronization)
+          if(scene.IsRotationCompletedAcknowledgementSet())
           {
-            // Enable PostRender flag
-            mThreadSynchronization->PostRenderStarted();
+            needWindowRotationCompleted = true;
           }
+        }
+      }
+      else
+      {
+        if(mIsResizing)
+        {
+          needWindowRotationCompleted = true;
+        }
+      }
+    }
 
-          DALI_LOG_RELEASE_INFO("WindowRenderSurface::PostRender: Trigger rotation event\n");
+    if(needWindowRotationCompleted || mIsImeWindowSurface)
+    {
+      if(mThreadSynchronization)
+      {
+        // Enable PostRender flag
+        mThreadSynchronization->PostRenderStarted();
+      }
 
-          mRotationTrigger->Trigger();
+      if(!mWindowRotationFinished || mIsImeWindowSurface)
+      {
+        mPostRenderTrigger->Trigger();
+      }
 
-          if(mThreadSynchronization)
-          {
-            // Wait until the event-thread complete the rotation event processing
-            mThreadSynchronization->PostRenderWaitForCompletion();
-          }
-        }
+      if(mThreadSynchronization)
+      {
+        // Wait until the event-thread complete the rotation event processing
+        mThreadSynchronization->PostRenderWaitForCompletion();
       }
     }
 
-    SwapBuffers(damagedRects);
+    SwapBuffers(mDamagedRects);
 
     if(mRenderNotification)
     {
@@ -604,6 +712,21 @@ Integration::StencilBufferAvailable WindowRenderSurface::GetStencilBufferRequire
   return mGraphics ? mGraphics->GetStencilBufferRequired() : Integration::StencilBufferAvailable::FALSE;
 }
 
+void WindowRenderSurface::InitializeImeSurface()
+{
+  mIsImeWindowSurface = true;
+  if(!mPostRenderTrigger)
+  {
+    mPostRenderTrigger = std::unique_ptr<TriggerEventInterface>(TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &WindowRenderSurface::ProcessPostRender),
+                                                                                                        TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER));
+  }
+}
+
+void WindowRenderSurface::SetNeedsRotationCompletedAcknowledgement(bool needAcknowledgement)
+{
+  mNeedWindowRotationAcknowledgement = needAcknowledgement;
+}
+
 void WindowRenderSurface::OutputTransformed()
 {
   int screenRotationAngle = mWindowBase->GetScreenRotationAngle();
@@ -624,13 +747,19 @@ void WindowRenderSurface::OutputTransformed()
   }
 }
 
-void WindowRenderSurface::ProcessRotationRequest()
+void WindowRenderSurface::ProcessPostRender()
 {
-  mWindowRotationFinished = true;
-
-  mWindowBase->WindowRotationCompleted(mWindowRotationAngle, mPositionSize.width, mPositionSize.height);
+  if(!mWindowRotationFinished)
+  {
+    mWindowBase->WindowRotationCompleted(mWindowRotationAngle, mPositionSize.width, mPositionSize.height);
+    DALI_LOG_RELEASE_INFO("WindowRenderSurface::ProcessPostRender: Rotation Done\n");
+    mWindowRotationFinished = true;
+  }
 
-  DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessRotationRequest: Rotation Done\n");
+  if(mIsImeWindowSurface)
+  {
+    mWindowBase->ImeWindowReadyToRender();
+  }
 
   if(mThreadSynchronization)
   {
@@ -695,28 +824,32 @@ void WindowRenderSurface::SetBufferDamagedRects(const std::vector<Rect<int>>& da
   auto eglGraphics = static_cast<EglGraphics*>(mGraphics);
   if(eglGraphics)
   {
-    Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
-    if(!eglImpl.IsPartialUpdateRequired())
+    // If scene is not exist, just use stored mPositionSize.
+    Rect<int> surfaceRect(0, 0, mPositionSize.width, mPositionSize.height);
+
+    Dali::Integration::Scene scene = mScene.GetHandle();
+    if(scene)
     {
-      return;
+      surfaceRect = scene.GetCurrentSurfaceRect();
     }
 
-    Rect<int> surfaceRect(0, 0, mPositionSize.width, mPositionSize.height);
-
-    if(mFullSwapNextFrame)
+    Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+    if(!eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame)
     {
       InsertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
-      clippingRect = Rect<int>();
+      clippingRect = surfaceRect;
       return;
     }
 
+    mGraphics->ActivateSurfaceContext(this);
+
     EGLint bufferAge = eglImpl.GetBufferAge(mEGLSurface);
 
     // Buffer age 0 means the back buffer in invalid and requires full swap
-    if(!damagedRects.size() || bufferAge == 0)
+    if(bufferAge == 0)
     {
       InsertRects(mBufferDamagedRects, std::vector<Rect<int>>(1, surfaceRect));
-      clippingRect = Rect<int>();
+      clippingRect = surfaceRect;
       return;
     }
 
@@ -734,14 +867,24 @@ void WindowRenderSurface::SetBufferDamagedRects(const std::vector<Rect<int>>& da
     if(!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * FULL_UPDATE_RATIO)
     {
       // clipping area too big or doesn't intersect surface rect
-      clippingRect = Rect<int>();
+      clippingRect = surfaceRect;
       return;
     }
 
-    std::vector<Rect<int>> damagedRegion;
-    damagedRegion.push_back(clippingRect);
+    if(!clippingRect.IsEmpty())
+    {
+      std::vector<Rect<int>> damagedRegion;
+      if(scene)
+      {
+        damagedRegion.push_back(RecalculateRect[std::min(scene.GetCurrentSurfaceOrientation() / 90, 3)](clippingRect, scene.GetCurrentSurfaceRect()));
+      }
+      else
+      {
+        damagedRegion.push_back(clippingRect);
+      }
 
-    eglImpl.SetDamageRegion(mEGLSurface, damagedRegion);
+      eglImpl.SetDamageRegion(mEGLSurface, damagedRegion);
+    }
   }
 }
 
@@ -750,11 +893,19 @@ void WindowRenderSurface::SwapBuffers(const std::vector<Rect<int>>& damagedRects
   auto eglGraphics = static_cast<EglGraphics*>(mGraphics);
   if(eglGraphics)
   {
-    Rect<int> surfaceRect(0, 0, mPositionSize.width, mPositionSize.height);
+    Rect<int32_t> surfaceRect;
+    int32_t       orientation = 0;
+
+    Dali::Integration::Scene scene = mScene.GetHandle();
+    if(scene)
+    {
+      surfaceRect = scene.GetCurrentSurfaceRect();
+      orientation = std::min(scene.GetCurrentSurfaceOrientation() / 90, 3);
+    }
 
     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
 
-    if(!eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame || !damagedRects.size() || (damagedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO))
+    if(!eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame || (damagedRects.size() != 0 && damagedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO))
     {
       mFullSwapNextFrame = false;
       eglImpl.SwapBuffers(mEGLSurface);
@@ -796,7 +947,7 @@ void WindowRenderSurface::SwapBuffers(const std::vector<Rect<int>>& damagedRects
     {
       if(!mergedRects[i].IsEmpty())
       {
-        mergedRects[j++] = mergedRects[i];
+        mergedRects[j++] = RecalculateRect[orientation](mergedRects[i], surfaceRect);
       }
     }
 
@@ -807,6 +958,8 @@ void WindowRenderSurface::SwapBuffers(const std::vector<Rect<int>>& damagedRects
 
     if(!mergedRects.size() || (mergedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO))
     {
+      // In normal cases, WindowRenderSurface::SwapBuffers() will not be called if mergedRects.size() is 0.
+      // For exceptional cases, swap full area.
       eglImpl.SwapBuffers(mEGLSurface);
     }
     else