Support off-screen buffer rendering in additional windows 65/206765/6
authorRichard Huang <r.huang@samsung.com>
Thu, 23 May 2019 15:11:39 +0000 (16:11 +0100)
committerRichard Huang <r.huang@samsung.com>
Wed, 29 May 2019 17:26:29 +0000 (18:26 +0100)
Change-Id: I7b6bb0d1f6292b786126b5dcb4c38ac232c9fcba

automated-tests/src/dali/utc-Dali-RenderTask.cpp
dali/internal/event/render-tasks/render-task-impl.cpp
dali/internal/render/common/render-manager.cpp

index f6697f0..82d57a9 100644 (file)
@@ -2700,6 +2700,52 @@ int UtcDaliRenderTaskViewportToLocal(void)
 
 }
 
+int UtcDaliRenderTaskOffscreenViewportToLocal(void)
+{
+  TestApplication application;
+  Actor actor = Actor::New();
+  actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+  actor.SetSize( 100.0f, 100.0f );
+  actor.SetPosition( 10.0f, 10.0f );
+  Stage::GetCurrent().Add( actor );
+
+  RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
+  RenderTask task = taskList.CreateTask();
+
+  FrameBufferImage newFrameBuffer = FrameBufferImage::New( 10, 10 );
+  task.SetTargetFrameBuffer( newFrameBuffer );
+  task.SetSourceActor( actor );
+  task.SetScreenToFrameBufferMappingActor( actor );
+
+  CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) );
+  Stage::GetCurrent().Add( offscreenCameraActor );
+  task.SetCameraActor( offscreenCameraActor );
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+  application.Render();
+
+  float localX;
+  float localY;
+
+  float rtLocalX;
+  float rtLocalY;
+
+  float screenX = 50.0f;
+  float screenY = 50.0f;
+
+  DALI_TEST_CHECK( actor.ScreenToLocal(localX, localY, screenX, screenY) );
+
+  DALI_TEST_CHECK( task.ViewportToLocal(actor, screenX, screenY, rtLocalX, rtLocalY ) );
+
+  DALI_TEST_EQUALS(localX, rtLocalX, 0.01f, TEST_LOCATION);
+  DALI_TEST_EQUALS(localY, rtLocalY, 0.01f, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliRenderTaskRequiresSync(void)
 {
   TestApplication application;
index 0bc361f..eb187af 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali/internal/event/actors/camera-actor-impl.h>
 #include <dali/internal/event/common/property-helper.h>
 #include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/common/scene-impl.h>
 #include <dali/internal/event/common/projection.h>
 #include <dali/internal/event/images/frame-buffer-image-impl.h>
 #include <dali/internal/update/nodes/node.h>
@@ -263,6 +264,12 @@ void RenderTask::GetViewport( Viewport& viewPort ) const
       if ( stage )
       {
         Vector2 size( stage->GetSize() );
+        if ( mSourceActor && mSourceActor->OnStage() )
+        {
+          Scene& scene = mSourceActor->GetScene();
+          size = scene.GetSize();
+        }
+
         viewPort.x = viewPort.y = 0;
         viewPort.width = static_cast<int32_t>( size.width ); // truncated
         viewPort.height = static_cast<int32_t>( size.height ); // truncated
@@ -401,19 +408,26 @@ bool RenderTask::TranslateCoordinates( Vector2& screenCoords ) const
     Internal::Actor* inputMappingActor = &GetImplementation( mappingActor );
     CameraActor* localCamera = GetCameraActor();
     StagePtr stage = Stage::GetCurrent();
-    if( stage )
+    if ( stage )
     {
-      CameraActor& defaultCamera = stage->GetDefaultCameraActor();
+      Vector2 size( stage->GetSize() );
+      CameraActor* defaultCamera( &stage->GetDefaultCameraActor() );
+      if ( mSourceActor && mSourceActor->OnStage() )
+      {
+        Scene& scene = mSourceActor->GetScene();
+        size = scene.GetSize();
+        defaultCamera = &scene.GetDefaultCameraActor();
+      }
+
       if( localCamera )
       {
         Viewport viewport;
-        Vector2 size( stage->GetSize() );
         viewport.x = viewport.y = 0;
         viewport.width = static_cast<int32_t>( size.width ); // truncated
         viewport.height = static_cast<int32_t>( size.height ); // truncated
 
         float localX, localY;
-        inside = inputMappingActor->ScreenToLocal(defaultCamera.GetViewMatrix(), defaultCamera.GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
+        inside = inputMappingActor->ScreenToLocal(defaultCamera->GetViewMatrix(), defaultCamera->GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
         Vector3 actorSize = inputMappingActor->GetCurrentSize();
         if( inside && localX >= 0.f && localX <= actorSize.x && localY >= 0.f && localY <= actorSize.y)
         {
index 8fc7c6c..533ab5c 100644 (file)
@@ -561,24 +561,32 @@ void RenderManager::DoRender( RenderInstruction& instruction )
   Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable;
 
   Render::SurfaceFrameBuffer* surfaceFrameBuffer = nullptr;
-  if ( ( instruction.mFrameBuffer != 0 ) && instruction.mFrameBuffer->IsSurfaceBacked() )
+  if ( instruction.mFrameBuffer != 0 )
   {
-    surfaceFrameBuffer = static_cast<Render::SurfaceFrameBuffer*>( instruction.mFrameBuffer );
-
-    if ( mImpl->currentContext->IsSurfacelessContextSupported() )
+    if ( instruction.mFrameBuffer->IsSurfaceBacked() )
     {
-      Context* surfaceContext = surfaceFrameBuffer->GetContext();
-      if ( mImpl->currentContext != surfaceContext )
+      surfaceFrameBuffer = static_cast<Render::SurfaceFrameBuffer*>( instruction.mFrameBuffer );
+
+      if ( mImpl->currentContext->IsSurfacelessContextSupported() )
       {
-        // Switch the correct context if rendering to a surface
-        mImpl->currentContext = surfaceContext;
-        // Clear the current cached program when the context is switched
-        mImpl->programController.ClearCurrentProgram();
+        Context* surfaceContext = surfaceFrameBuffer->GetContext();
+        if ( mImpl->currentContext != surfaceContext )
+        {
+          // Switch the correct context if rendering to a surface
+          mImpl->currentContext = surfaceContext;
+          // Clear the current cached program when the context is switched
+          mImpl->programController.ClearCurrentProgram();
+        }
       }
-    }
 
-    surfaceRect = Rect<int32_t>( 0, 0, static_cast<int32_t>( surfaceFrameBuffer->GetWidth() ), static_cast<int32_t>( surfaceFrameBuffer->GetHeight() ) );
-    backgroundColor = surfaceFrameBuffer->GetBackgroundColor();
+      surfaceRect = Rect<int32_t>( 0, 0, static_cast<int32_t>( surfaceFrameBuffer->GetWidth() ), static_cast<int32_t>( surfaceFrameBuffer->GetHeight() ) );
+      backgroundColor = surfaceFrameBuffer->GetBackgroundColor();
+    }
+    else
+    {
+      // Switch to shared context for off-screen buffer
+      mImpl->currentContext = &mImpl->context;
+    }
   }
 
   DALI_ASSERT_DEBUG( mImpl->currentContext->IsGlContextCreated() );