[Tizen] Keep rendered buffer in framebuffer 73/315573/1
authorSeungho Baek <sbsh.baek@samsung.com>
Fri, 15 Nov 2024 06:55:04 +0000 (15:55 +0900)
committerSeungho Baek <sbsh.baek@samsung.com>
Tue, 3 Dec 2024 06:58:13 +0000 (15:58 +0900)
Change-Id: I20d7bdb2541a41eae1a440e25ad96c88e216923d
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
31 files changed:
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h
dali/devel-api/adaptor-framework/capture-devel.h
dali/devel-api/adaptor-framework/native-image-source-devel.cpp
dali/devel-api/adaptor-framework/native-image-source-devel.h
dali/internal/graphics/gles-impl/egl-graphics-controller-debug.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/gles-context.cpp
dali/internal/graphics/gles-impl/gles-context.h
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h
dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.h
dali/internal/imaging/android/native-image-source-impl-android.cpp
dali/internal/imaging/android/native-image-source-impl-android.h
dali/internal/imaging/common/native-image-source-impl.h
dali/internal/imaging/macos/native-image-source-impl-mac.cpp
dali/internal/imaging/macos/native-image-source-impl-mac.h
dali/internal/imaging/tizen/native-image-source-impl-tizen.cpp
dali/internal/imaging/tizen/native-image-source-impl-tizen.h
dali/internal/imaging/ubuntu-x11/native-image-source-impl-x.cpp
dali/internal/imaging/ubuntu-x11/native-image-source-impl-x.h
dali/internal/imaging/windows/native-image-source-impl-win.cpp
dali/internal/imaging/windows/native-image-source-impl-win.h
dali/internal/imaging/x11/native-image-source-impl-x.cpp
dali/internal/imaging/x11/native-image-source-impl-x.h
dali/internal/system/common/capture-impl.cpp
dali/internal/system/common/capture-impl.h
dali/public-api/capture/capture.cpp
dali/public-api/capture/capture.h

index 9df2d0fafca901a7949ac785976274eb2fadffaf..147246f44e8001d97a347ddaeb9abc1e5894104f 100644 (file)
@@ -834,6 +834,10 @@ public:
     mCallStack.PushCall("EndRenderPass", namedParams.str(), namedParams);
   }
 
+  void ReadPixels(uint8_t* buffer) override
+  {
+  }
+
   void ExecuteCommandBuffers(std::vector<const CommandBuffer*>&& commandBuffers) override
   {
     mCommands.emplace_back();
index d69f4fb23cbafe77e418f300adad16e200e678e8..e8b8f7db6ddf738dbb315f2ba09f926b31ba32dd 100644 (file)
@@ -32,6 +32,7 @@ namespace DevelCapture
  * @brief Get PixelBuffer of captured image.
  *
  * @return PixelBuffer Captured result
+ * @note GetCapturedBuffer is only available inside FinishedSignal, otherwise this returns empty handle.
  */
 DALI_ADAPTOR_API Dali::Devel::PixelBuffer GetCapturedBuffer(Dali::Capture capture);
 
index 96d16964fad9740b917daadc3a4bd28f0b7a31f7..29a8fde746a86b7a1d62272aaca23fdffbc073ce 100644 (file)
@@ -40,6 +40,11 @@ bool ReleaseBuffer(NativeImageSource& image, const Rect<uint32_t>& updatedArea)
   return Dali::Internal::Adaptor::NativeImageSource::GetImplementation(image).ReleaseBuffer(updatedArea);\r
 }\r
 \r
+bool SetPixels(NativeImageSource& image, uint8_t* pixbuf, const Pixel::Format& pixelFormat)\r
+{\r
+  return Dali::Internal::Adaptor::NativeImageSource::GetImplementation(image).SetPixels(pixbuf, pixelFormat);\r
+}\r
+\r
 void SetResourceDestructionCallback(NativeImageSource& image, EventThreadCallback* callback)\r
 {\r
   return Dali::Internal::Adaptor::NativeImageSource::GetImplementation(image).SetResourceDestructionCallback(callback);\r
index 1263696e78055dd08330abb320360a66b662836e..06850014d516171ad1bad8e913b08abfc21f7d3f 100644 (file)
@@ -68,6 +68,18 @@ DALI_ADAPTOR_API uint8_t* AcquireBuffer(NativeImageSource& image, uint32_t& widt
  */\r
 DALI_ADAPTOR_API bool ReleaseBuffer(NativeImageSource& image, const Rect<uint32_t>& updatedArea);\r
 \r
+/**\r
+ * @brief Sets PixelBuffers to NativeImageSource\r
+ *\r
+ * @param[in] image The instance of NativeImageSource.\r
+ * @param[in] pixbuf Pixel buffer to copy.\r
+ * @param[in] pixelFormat Pixel format of the pixel buffer\r
+ * @return @c true If the buffer is successfully set.\r
+ * @note The width and height of the input pixel buffer should be same with those of NativeImageSource.\r
+ * @note Only Pixel::Format::RGB888 and Pixel::Format::RGBA8888 are available as a input pixel format.\r
+ */\r
+DALI_ADAPTOR_API bool SetPixels(NativeImageSource& image, uint8_t* pixbuf, const Pixel::Format& pixelFormat);\r
+\r
 /**\r
  * @brief Set the Resource Destruction Callback object\r
  *\r
index e02e188160838f30caf747ab5fb0c7afde820309..574f2a91306295b114545283e6a752d812fa08d6 100644 (file)
@@ -273,6 +273,11 @@ void DumpCommandBuffer(FILE* output, const GLES::CommandBuffer* commandBuffer)
         fprintf(output, "{\"Cmd\":\"END_RENDER_PASS\"}\n");
         break;
       }
+      case GLES::CommandType::READ_PIXELS:
+      {
+        fprintf(output, "{\"Cmd\":\"READ_PIXELS\"}\n");
+        break;
+      }
       case GLES::CommandType::PRESENT_RENDER_TARGET:
       {
         fprintf(output, "{\"Cmd\":\"PRESENT_RENDER_TARGET\"}\n");
index 0c42e7eb4eb95dea252faaa1ac449f5fa6b703e4..6faf8b1e024dafe0d41264368b359725e3bbb9c8 100644 (file)
@@ -736,6 +736,11 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
         }
         break;
       }
+      case GLES::CommandType::READ_PIXELS:
+      {
+        mCurrentContext->ReadPixels(cmd.readPixelsBuffer.buffer);
+        break;
+      }
       case GLES::CommandType::PRESENT_RENDER_TARGET:
       {
         ResolvePresentRenderTarget(cmd.presentRenderTarget.targetToPresent);
index 1cf5c90a4d1221b363390bc91ed617a6517cea92..c6c821f998f04ef9bdfc2f818b1a43bb4507829a 100644 (file)
@@ -930,6 +930,21 @@ void Context::EndRenderPass(GLES::TextureDependencyChecker& dependencyChecker)
   }
 }
 
+void Context::ReadPixels(uint8_t* buffer)
+{
+  if(mImpl->mCurrentRenderTarget)
+  {
+    GLES::Framebuffer* framebuffer = mImpl->mCurrentRenderTarget->GetFramebuffer();
+    auto*              gl          = mImpl->GetGL();
+    if(framebuffer && gl)
+    {
+      gl->Finish(); // To guarantee ReadPixels.
+      gl->ReadPixels(0, 0, framebuffer->GetCreateInfo().size.width, framebuffer->GetCreateInfo().size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+    }
+  }
+}
+
+
 void Context::ClearState()
 {
   mImpl->mCurrentTextureBindings.clear();
index d6273609f4776cd4901adf2572146b5caeea63f5..d9c2047c87ac0578a3fe40aa7346d39a33ee1f4f 100644 (file)
@@ -148,6 +148,12 @@ public:
    */
   void EndRenderPass(TextureDependencyChecker& checker);
 
+  /**
+   * @brief Request to read pixels
+   * @param[out] buffer to load pixel data.
+   */
+  void ReadPixels(uint8_t* buffer);
+
   /**
    * @brief Returns the cache of GL state in the context
    * @return the reference of GL state cache (which can be modified)
index 888c1892d2ebd121f6f27a681945706f29d772d6..41b01799fc9a2aa4603253b5c7c5e64f79ff3fd5 100644 (file)
@@ -407,6 +407,12 @@ void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
   command->endRenderPass.syncObject = static_cast<GLES::SyncObject*>(syncObject);
 }
 
+void CommandBuffer::ReadPixels(uint8_t* buffer)
+{
+  auto command = mCommandPool->AllocateCommand(CommandType::READ_PIXELS);
+  command->readPixelsBuffer.buffer = buffer;
+}
+
 void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
 {
   auto  command    = mCommandPool->AllocateCommand(CommandType::EXECUTE_COMMAND_BUFFERS);
index ebe198d3041d22619782fc4d312b608a08953e26..0f7e81bc46abf94c16b3cb81bfca53dffc611572 100644 (file)
@@ -54,6 +54,7 @@ enum class CommandType
   SET_VIEWPORT,
   BEGIN_RENDERPASS,
   END_RENDERPASS,
+  READ_PIXELS,
   EXECUTE_COMMAND_BUFFERS,
   PRESENT_RENDER_TARGET,
   SET_COLOR_MASK,
@@ -169,6 +170,11 @@ struct Command
       Graphics::SyncObject* syncObject;
     } endRenderPass;
 
+    struct
+    {
+      uint8_t* buffer;
+    } readPixelsBuffer;
+
     struct
     {
       IndirectPtr<const GLES::CommandBuffer*> buffers;
@@ -294,6 +300,11 @@ public:
    */
   void EndRenderPass(Graphics::SyncObject* syncObject) override;
 
+  /**
+   * @copydoc Dali::Graphics::CommandBuffer::ReadPixels
+   */
+  void ReadPixels(uint8_t* buffer) override;
+
   /**
    * @copydoc Dali::Graphics::CommandBuffer::ExecuteCommandBuffers
    */
index b53a6bce0a2937c52783d8cb71f75c1aad2fe63b..061c3da187b05cf00970e5f3d37e2a9afa3db5e4 100644 (file)
@@ -260,6 +260,10 @@ void CommandBufferImpl::EndRenderPass()
   mCommandBuffer.endRenderPass();
 }
 
+void CommandBufferImpl::ReadPixels(uint8_t* buffer)
+{
+}
+
 void CommandBufferImpl::PipelineBarrier(
   vk::PipelineStageFlags               srcStageMask,
   vk::PipelineStageFlags               dstStageMask,
index 98b4db802055a02aac8d7f00bef55fae48915fe9..6d2c04c4b1eae0211f04745d5966efded5ae1c5e 100644 (file)
@@ -92,6 +92,11 @@ public:
    */
   void EndRenderPass();
 
+  /**
+   * Request to read pixels.
+   */
+  void ReadPixels(uint8_t* buffer);
+
   void PipelineBarrier(vk::PipelineStageFlags               srcStageMask,
                        vk::PipelineStageFlags               dstStageMask,
                        vk::DependencyFlags                  dependencyFlags,
index f344178df84b5fdc524213bfd8ddd2efc685823f..d7aa5bf11734e38182e322e76b7843f5764c41f8 100644 (file)
@@ -243,6 +243,11 @@ void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
   mCommandBufferImpl->EndRenderPass();
 }
 
+void CommandBuffer::ReadPixels(uint8_t* buffer)
+{
+  mCommandBufferImpl->ReadPixels(buffer);
+}
+
 void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& gfxCommandBuffers)
 {
   std::vector<vk::CommandBuffer> vkCommandBuffers;
index ea5efe6c2b5cf7ff5c24254154b740783f57ba6c..296faded5655d334f8455621089f5747bbe36fca 100644 (file)
@@ -151,6 +151,11 @@ public:
    */
   void EndRenderPass(Graphics::SyncObject* syncObject) override;
 
+  /**
+   * @copydoc Dali::Graphics::CommandBuffer::ReadPixels
+   */
+  void ReadPixels(uint8_t* buffer) override;
+
   /**
    * @brief Executes a list of secondary command buffers
    *
index 8c6ed5bec43b40997063c9042edede63ec3eaa34..0b6e726eabc0c63ad41d64b16958d657666f44b6 100644 (file)
@@ -208,6 +208,11 @@ bool NativeImageSourceAndroid::GetPixels(std::vector<uint8_t>& pixbuf, uint32_t&
   return success;
 }
 
+bool NativeImageSourceAndroid::SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat)
+{
+  return false;
+}
+
 void NativeImageSourceAndroid::SetSource(Any source)
 {
   if(mPixmap)
index 3da39a8e0c3fc38414bd358674c07c96d007e2d3..331eaac10817788dfee65fb4518d60ee7191ddd9 100644 (file)
@@ -66,6 +66,11 @@ public:
    */
   bool GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& width, uint32_t& height, Pixel::Format& pixelFormat) const override;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) override;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index 6b90eb876054f40a19d78a18e5c0d1d21dd811bf..16d19c868e56a294d331d5e04c68219bbf47e122 100644 (file)
@@ -60,6 +60,11 @@ public:
    */
   virtual bool GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& width, uint32_t& height, Pixel::Format& pixelFormat) const = 0;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  virtual bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) = 0;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index d386b2dc7b7db26d78f5b94f8fffd6fe030572bc..54d0fc652d5aa9062140a1f78faf67223d720b35 100644 (file)
@@ -128,6 +128,11 @@ bool NativeImageSourceCocoa::GetPixels(
   return true;
 }
 
+bool NativeImageSourceCocoa::SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat)
+{
+  return false;
+}
+
 void NativeImageSourceCocoa::SetSource(Any source)
 {
 }
index 576f56d5e0b1004c83227910781dcbc858260aa6..11c39782e3ef683688d785d8d7993a26a1b9aab3 100644 (file)
@@ -61,6 +61,11 @@ public:
     uint32_t&             height,
     Pixel::Format&        pixelFormat) const override;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) override;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index b33a51cfc7ecb0878a0787eab35ee4ea462d39ec..9f4c91c62dc9992c782c33e298e84896466c7c82 100644 (file)
@@ -336,6 +336,116 @@ bool NativeImageSourceTizen::GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& w
   return false;
 }
 
+bool NativeImageSourceTizen::SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat)
+{
+  std::scoped_lock lock(mMutex);
+  if(mTbmSurface != NULL)
+  {
+    tbm_surface_info_s surface_info;
+
+    if(tbm_surface_map(mTbmSurface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &surface_info) != TBM_SURFACE_ERROR_NONE)
+    {
+      DALI_LOG_ERROR("Fail to map tbm_surface\n");
+      return false;
+    }
+    tbm_surface_internal_ref(mTbmSurface);
+
+    if(pixelFormat != Pixel::Format::RGBA8888 && pixelFormat != Pixel::Format::RGB888)
+    {
+      DALI_LOG_ERROR("Not Supported PixelFormat\n");
+      return false;
+    }
+
+    tbm_format format = surface_info.format;
+    uint32_t   stride = surface_info.planes[0].stride;
+    uint8_t*   ptr    = surface_info.planes[0].ptr;
+
+    size_t lineSize;
+    size_t inputBufferLinePixelSize = Dali::Pixel::GetBytesPerPixel(pixelFormat);
+
+    switch(format)
+    {
+      case TBM_FORMAT_RGB888:
+      {
+        lineSize        = mWidth * inputBufferLinePixelSize;
+        uint8_t* bufptr = &pixbuf[0];
+
+        for(uint32_t r = 0; r < mHeight; ++r, bufptr += lineSize)
+        {
+          for(uint32_t c = 0; c < mWidth; ++c)
+          {
+            size_t sOffset  = c * inputBufferLinePixelSize;
+            size_t dOffset  = c * 3;
+            size_t offset          = dOffset + r * stride;
+            ptr[offset + 2] = *(bufptr + sOffset);
+            ptr[offset + 1] = *(bufptr + sOffset + 1);
+            ptr[offset]     = *(bufptr + sOffset + 2);
+          }
+        }
+        break;
+      }
+      case TBM_FORMAT_RGBA8888:
+      {
+        lineSize        = mWidth * inputBufferLinePixelSize;
+        uint8_t* bufptr = &pixbuf[0];
+
+        for(uint32_t r = 0; r < mHeight; ++r, bufptr += lineSize)
+        {
+          for(uint32_t c = 0; c < mWidth; ++c)
+          {
+            size_t sOffset  = c * inputBufferLinePixelSize;
+            size_t dOffset  = c * 4;
+            size_t offset          = dOffset + r * stride;
+            ptr[offset + 3] = *(bufptr + sOffset);
+            ptr[offset + 2] = *(bufptr + sOffset + 1);
+            ptr[offset + 1] = *(bufptr + sOffset + 2);
+            ptr[offset]     = (inputBufferLinePixelSize == 4) ? *(bufptr + sOffset + 3) : 0xFF;
+          }
+        }
+        break;
+      }
+      case TBM_FORMAT_ARGB8888:
+      {
+        lineSize        = mWidth * inputBufferLinePixelSize;
+        uint8_t* bufptr = &pixbuf[0];
+
+        for(uint32_t r = 0; r < mHeight; ++r, bufptr += lineSize)
+        {
+          for(uint32_t c = 0; c < mWidth; ++c)
+          {
+            size_t sOffset  = c * inputBufferLinePixelSize;
+            size_t dOffset  = c * 4;
+            size_t offset          = dOffset + r * stride;
+            ptr[offset + 2] = *(bufptr + sOffset);
+            ptr[offset + 1] = *(bufptr + sOffset + 1);
+            ptr[offset]     = *(bufptr + sOffset + 2);
+            ptr[offset + 3] = (inputBufferLinePixelSize == 4) ? *(bufptr + sOffset + 3) : 0xFF;
+          }
+        }
+        break;
+      }
+      default:
+      {
+        DALI_ASSERT_ALWAYS(0 && "Tbm surface has unsupported pixel format.\n");
+
+        return false;
+      }
+    }
+
+    if(tbm_surface_unmap(mTbmSurface) != TBM_SURFACE_ERROR_NONE)
+    {
+      DALI_LOG_ERROR("Fail to unmap tbm_surface\n");
+    }
+    tbm_surface_internal_unref(mTbmSurface);
+
+    return true;
+  }
+
+  DALI_LOG_WARNING("TBM surface does not exist.\n");
+
+  return false;
+}
+
 void NativeImageSourceTizen::SetSource(Any source)
 {
   std::scoped_lock lock(mMutex);
index 70f0340dd2020f560b67f564a677214ad537a421..9d85dcfa2b4a0909d954d0614723c620c43b0a99 100644 (file)
@@ -67,6 +67,11 @@ public:
    */
   bool GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& width, uint32_t& height, Pixel::Format& pixelFormat) const override;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) override;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index 28be8a293b34dfa933f80292ec49371d92f61bd1..efbeeb592f8d7b2004582c2f593e5bb2eb0f9058 100644 (file)
@@ -264,6 +264,11 @@ bool NativeImageSourceX::GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& width
   return success;
 }
 
+bool NativeImageSourceX::SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat)
+{
+  return false;
+}
+
 void NativeImageSourceX::SetSource(Any source)
 {
   mPixmap = GetPixmapFromAny(source);
index 6745c6416935572058f03839c0dc23b8cb4e3c95..7105d031e1ddd39bda388a3e0325446e7798c67b 100644 (file)
@@ -64,6 +64,11 @@ public:
    */
   bool GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& width, uint32_t& height, Pixel::Format& pixelFormat) const override;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) override;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index 2eaa812c65e77ac3bef3085c27b7ebfa59e5c237..21a5859812edd9bb07517a8a39cd797e7e8ed840 100644 (file)
@@ -115,6 +115,11 @@ bool NativeImageSourceWin::GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& wid
   return success;
 }
 
+bool NativeImageSourceWin::SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat)
+{
+  return false;
+}
+
 void NativeImageSourceWin::SetSource(Any source)
 {
   mPixmap = GetPixmapFromAny(source);
index 88059d6e4b06dfce025baf9e5c7253cd78f64fd6..4accc7adb4d949bf6f15752ae777d2fdb290c9da 100644 (file)
@@ -62,6 +62,11 @@ public:
    */
   bool GetPixels(std::vector<uint8_t>& pixbuf, uint32_t& width, uint32_t& height, Pixel::Format& pixelFormat) const override;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) override;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index 8eb5d353d71f12d6189847f7cd75cd25818e90cb..32eedc6c9946719aad4c19e0f8ff62a44993b88b 100644 (file)
@@ -268,6 +268,11 @@ bool NativeImageSourceX::GetPixels(std::vector<unsigned char>& pixbuf, unsigned&
   return success;
 }
 
+bool NativeImageSourceX::SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat)
+{
+  return false;
+}
+
 void NativeImageSourceX::SetSource(Any source)
 {
   mPixmap = GetPixmapFromAny(source);
index 68c4126aa74f023084850b82c1beac7ab476d17a..115626fed8077b8fba97ae423bb9e38e3e2062de 100644 (file)
@@ -63,6 +63,11 @@ public:
    */
   bool GetPixels(std::vector<unsigned char>& pixbuf, uint32_t& width, uint32_t& height, Pixel::Format& pixelFormat) const override;
 
+  /**
+   * @copydoc Dali::NativeImageSource::SetPixels()
+   */
+  bool SetPixels(uint8_t* pixbuf, const Pixel::Format& pixelFormat) override;
+
   /**
    * @copydoc Dali::NativeImageSource::SetSource( Any source )
    */
index e4495b90c2486cae1fe8979d00af2b97c16f62ff..4781684f390e8661ce7ef53f25f0a2cc6a9bd6d9 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/pixel-data-integ.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <string.h>
@@ -41,7 +42,6 @@ namespace Adaptor
 namespace
 {
 static constexpr uint32_t ORDER_INDEX_CAPTURE_RENDER_TASK              = 1000;
-constexpr int32_t         SHADER_VERSION_NATIVE_IMAGE_SOURCE_AVAILABLE = 300;
 constexpr uint32_t        TIME_OUT_DURATION                            = 1000;
 constexpr int32_t  GL_VERSION_NATIVE_IMAGE_SOURCE_AVAILABLE = 30;
 } // namespace
@@ -50,7 +50,6 @@ Capture::Capture()
 : mQuality(DEFAULT_QUALITY),
   mTimer(),
   mPath(),
-  mNativeImageSourcePtr(NULL),
   mFileSave(false),
   mUseDefaultCamera(true),
   mSceneOffCameraAfterCaptureFinished(false)
@@ -62,7 +61,6 @@ Capture::Capture(Dali::CameraActor cameraActor)
   mCameraActor(cameraActor),
   mTimer(),
   mPath(),
-  mNativeImageSourcePtr(NULL),
   mFileSave(false),
   mUseDefaultCamera(!cameraActor),
   mSceneOffCameraAfterCaptureFinished(false)
@@ -75,7 +73,6 @@ Capture::~Capture()
   {
     Adaptor::Get().UnregisterProcessorOnce(*this, true);
   }
-  DeleteNativeImageSource();
   mTexture.Reset();
 }
 
@@ -120,14 +117,15 @@ void Capture::Start(Dali::Actor source, const Dali::Vector2& position, const Dal
   // Increase the reference count focely to avoid application mistake.
   Reference();
 
+  UnsetResources();
+  SetupResources(position, size, clearColor, source);
+
   mPath = path;
   if(!mPath.empty())
   {
     mFileSave = true;
   }
-
-  UnsetResources();
-  SetupResources(position, size, clearColor, source);
+  mRenderTask.KeepRenderResult();
 
   mInCapture = true;
   Adaptor::Get().RegisterProcessorOnce(*this, true);
@@ -155,9 +153,24 @@ bool Capture::IsExclusive() const
   return mIsExclusive;
 }
 
-Dali::NativeImageSourcePtr Capture::GetNativeImageSource() const
+Dali::NativeImageSourcePtr Capture::GetNativeImageSource()
 {
-  return mNativeImageSourcePtr;
+  Dali::NativeImageSourcePtr result;
+  if(mRenderTask)
+  {
+    Dali::PixelData pixelData = mRenderTask.GetRenderResult();
+    if(pixelData)
+    {
+      auto pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+      NativeImageSourcePtr nativeImageSourcePtr = Dali::NativeImageSource::New(pixelData.GetWidth(), pixelData.GetHeight(), Dali::NativeImageSource::COLOR_DEPTH_32);  // Texture pixel format is RGBA8888
+
+      if(Dali::DevelNativeImageSource::SetPixels(*nativeImageSourcePtr, pixelDataBuffer.buffer, pixelData.GetPixelFormat()))
+      {
+        result = nativeImageSourcePtr;
+      }
+    }
+  }
+  return result;
 }
 
 Dali::Texture Capture::GetTexture() const
@@ -167,19 +180,18 @@ Dali::Texture Capture::GetTexture() const
 
 Dali::Devel::PixelBuffer Capture::GetCapturedBuffer()
 {
-  if(!mPixelBuffer || (mPixelBuffer && !mPixelBuffer.GetBuffer()))
+  Devel::PixelBuffer pixelBuffer;
+  if(mRenderTask)
   {
-    std::vector<uint8_t> buffer;
-    uint32_t             width, height;
-    Dali::Pixel::Format  pixelFormat;
-    if(!mNativeImageSourcePtr->GetPixels(buffer, width, height, pixelFormat))
+    Dali::PixelData pixelData = mRenderTask.GetRenderResult();
+    if(pixelData)
     {
-      return Dali::Devel::PixelBuffer();
+      auto pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+      pixelBuffer          = Dali::Devel::PixelBuffer::New(pixelData.GetWidth(), pixelData.GetHeight(), pixelData.GetPixelFormat());
+      memcpy(pixelBuffer.GetBuffer(), pixelDataBuffer.buffer, pixelDataBuffer.bufferSize);
     }
-    mPixelBuffer = Dali::Devel::PixelBuffer::New(width, height, pixelFormat);
-    memcpy(mPixelBuffer.GetBuffer(), &buffer[0], width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat));
   }
-  return mPixelBuffer;
+  return pixelBuffer;
 }
 
 Dali::Capture::CaptureFinishedSignalType& Capture::FinishedSignal()
@@ -189,19 +201,7 @@ Dali::Capture::CaptureFinishedSignalType& Capture::FinishedSignal()
 
 void Capture::CreateTexture(const Vector2& size)
 {
-  if(!mNativeImageSourcePtr)
-  {
-    mNativeImageSourcePtr = Dali::NativeImageSource::New(size.width, size.height, Dali::NativeImageSource::COLOR_DEPTH_DEFAULT);
-    mTexture              = Dali::Texture::New(*mNativeImageSourcePtr);
-  }
-}
-
-void Capture::DeleteNativeImageSource()
-{
-  if(mNativeImageSourcePtr)
-  {
-    mNativeImageSourcePtr.Reset();
-  }
+  mTexture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height));
 }
 
 void Capture::CreateFrameBuffer()
@@ -313,8 +313,10 @@ void Capture::UnsetRenderTask()
     Dali::RenderTaskList taskList = sceneHolder.GetRenderTaskList();
     taskList.RemoveTask(mRenderTask);
   }
+  mRenderTask.ClearRenderResult();
   mRenderTask.Reset();
   mSource.Reset();
+  mTexture.Reset();
   mSceneHolderHandle.Reset();
 }
 
@@ -398,9 +400,11 @@ bool Capture::OnTimeOut()
 
 bool Capture::SaveFile()
 {
-  if(mNativeImageSourcePtr)
+  Dali::PixelData pixelData = mRenderTask.GetRenderResult();
+  if(pixelData)
   {
-    return Dali::DevelNativeImageSource::EncodeToFile(*mNativeImageSourcePtr, mPath, mQuality);
+    auto pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+    return Dali::EncodeToFile(pixelDataBuffer.buffer, mPath, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight(), mQuality);
   }
 
   return false;
index 446e7d8da53bdbc7b0b9321aa983096558e11a87..402fd0b639948ea6e760d6e42b3d1e83dc11a136 100644 (file)
@@ -96,7 +96,7 @@ public:
   /**
    * @copydoc Dali::Capture::GetNativeImageSource
    */
-  Dali::NativeImageSourcePtr GetNativeImageSource() const;
+  Dali::NativeImageSourcePtr GetNativeImageSource();
 
   /**
    * @copydoc Dali::Capture::GetCapturedBuffer
@@ -125,11 +125,6 @@ private:
    */
   void CreateTexture(const Dali::Vector2& size);
 
-  /**
-   * @brief Delete native image source.
-   */
-  void DeleteNativeImageSource();
-
   /**
    * @brief Create frame buffer.
    */
@@ -239,8 +234,6 @@ private:
   Dali::Timer                                      mTimer; ///< For timeout.
   Dali::Capture::CaptureFinishedSignalType         mFinishedSignal;
   std::string                                      mPath;
-  Dali::NativeImageSourcePtr                       mNativeImageSourcePtr; ///< pointer to surface image
-  Dali::Devel::PixelBuffer                         mPixelBuffer;
   bool                                             mInCapture{false};
   bool                                             mIsExclusive{false};
   bool                                             mFileSave;
index 4c96a617b51c673d96be4a870b95c3240f0fa557..0915a103d43e3dc203ff8e784096852010e516f5 100644 (file)
@@ -93,7 +93,7 @@ bool Capture::IsExclusive() const
   return GetImpl(*this).IsExclusive();
 }
 
-Dali::NativeImageSourcePtr Capture::GetNativeImageSource() const
+Dali::NativeImageSourcePtr Capture::GetNativeImageSource()
 {
   return GetImpl(*this).GetNativeImageSource();
 }
index 6f133da644b25f27c18f1d058c0be339a9f81ed9..c719e477c5bf489e0196c8034b85facae7d4d716 100644 (file)
@@ -271,13 +271,15 @@ public:
    * @SINCE_1_9.10
    *
    * @return NativeImageSourcePtr Captured result that can be rendered with DALi
+   * @note GetNativeImageSource is only available inside FinishedSignal.
    */
-  Dali::NativeImageSourcePtr GetNativeImageSource() const;
+  Dali::NativeImageSourcePtr GetNativeImageSource();
 
   /**
    * @brief Get Texture of captured image.
    *
    * @return Texture Captured result
+   * @note GetTexture is only available inside FinishedSignal.
    */
   Dali::Texture GetTexture() const;