Upload PixelData's sub image to Texture
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-texture.cpp
index 2cfa49e..f2bc5a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 #include <math.h> //floor, log2
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
 
 namespace Dali
 {
@@ -106,10 +107,10 @@ constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format)
       return Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK; // no 'punchthrough' format
 
     case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
-      return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to map onto any format
+      return Graphics::Format::ETC2_R8G8B8A8_UNORM_BLOCK;
 
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-      return Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK; // doesn't seem to map onto any format
+      return Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK;
 
     case Pixel::COMPRESSED_RGB8_ETC1:
       return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to be supported at all
@@ -147,7 +148,6 @@ constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format)
     case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
       return Graphics::Format::ASTC_12x12_UNORM_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
-
       return Graphics::Format::ASTC_4x4_SRGB_BLOCK; // not type with alpha, but likely to use SRGB
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
       return Graphics::Format::ASTC_5x4_SRGB_BLOCK;
@@ -175,10 +175,18 @@ constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format)
       return Graphics::Format::ASTC_12x10_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
       return Graphics::Format::ASTC_12x12_SRGB_BLOCK;
+
     case Pixel::RGB16F:
       return Graphics::Format::R16G16B16_SFLOAT;
     case Pixel::RGB32F:
       return Graphics::Format::R32G32B32_SFLOAT;
+    case Pixel::R11G11B10F:
+      return Graphics::Format::R11G11B10_UFLOAT_PACK32;
+
+    case Pixel::CHROMINANCE_U:
+      return Graphics::Format::L8;
+    case Pixel::CHROMINANCE_V:
+      return Graphics::Format::L8;
   }
   return Graphics::Format::UNDEFINED;
 }
@@ -205,7 +213,6 @@ Texture::Texture(Type type, Pixel::Format format, ImageDimensions size)
   mPixelFormat(format),
   mWidth(size.GetWidth()),
   mHeight(size.GetHeight()),
-  mMaxMipMapLevel(0),
   mType(type),
   mHasAlpha(HasAlpha(format))
 {
@@ -219,7 +226,6 @@ Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
   mPixelFormat(Pixel::RGBA8888),
   mWidth(static_cast<uint16_t>(nativeImageInterface->GetWidth())),   // ignoring overflow, not happening in practice
   mHeight(static_cast<uint16_t>(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice
-  mMaxMipMapLevel(0),
   mType(TextureType::TEXTURE_2D),
   mHasAlpha(nativeImageInterface->RequiresBlending())
 {
@@ -272,7 +278,7 @@ void Texture::CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* data, u
 
 void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params)
 {
-  DALI_ASSERT_ALWAYS(mNativeImage == nullptr);
+  DALI_ASSERT_ALWAYS(!mNativeImage);
 
   if(!mGraphicsTexture)
   {
@@ -280,14 +286,59 @@ void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadPara
   }
 
   Graphics::TextureUpdateInfo info{};
+
+  const uint32_t bytePerPixel = Pixel::GetBytesPerPixel(pixelData->GetPixelFormat());
+  const uint32_t srcStride    = pixelData->GetStride();
+  uint32_t       srcOffset    = 0u;
+  uint32_t       srcSize      = pixelData->GetBufferSize();
+
+  const bool requiredSubPixelData = (!Pixel::IsCompressed(pixelData->GetPixelFormat())) &&
+                                    ((params.dataXOffset != 0) ||
+                                     (params.dataYOffset != 0) ||
+                                     (params.dataWidth != pixelData->GetWidth()) ||
+                                     (params.dataHeight != pixelData->GetHeight()));
+
+  if(requiredSubPixelData)
+  {
+    /**
+     * TextureUpdateInfo use byte scaled offset / size.
+     *
+     * To make we only use sub-data of inputed PixelData, make srcOffset as 'start of SubPixelData.
+     *
+     *   |---- dataStrideByte -----|
+     *   |-----| <-- dataXOffsetByte
+     *   ...........................
+     *   ......A-----------+........
+     *   ......|           |........
+     *   ......|           |........
+     *   ......+-----------+C.......
+     *   ......B....................
+     *
+     * A) Start of SubPixelData. offsetByte = dataStrideByte * dataYOffset + dataXOffsetByte.
+     * B) offsetByte = A).offsetByte + dataStrideByte * dataHeight. Note, It can be out of original PixelData boundary.
+     * C) End of SubPixelData. offsetByte = B).offsetByte - dataStrideByte + dataWidthByte.
+     *
+     * srcOffset = A).offsetByte;
+     * srcSize = ( C).offsetByte - A).offsetByte );
+     */
+    const uint32_t dataStrideByte  = (srcStride ? srcStride : static_cast<uint32_t>(params.dataWidth)) * bytePerPixel;
+    const uint32_t dataXOffsetByte = params.dataXOffset * bytePerPixel;
+    const uint32_t dataWidthByte   = static_cast<uint32_t>(params.dataWidth) * bytePerPixel;
+
+    srcOffset = params.dataYOffset * dataStrideByte + dataXOffsetByte;
+    srcSize   = static_cast<uint32_t>(params.dataHeight) * dataStrideByte - (dataStrideByte - dataWidthByte);
+  }
+
   info.dstTexture   = mGraphicsTexture.get();
   info.dstOffset2D  = {params.xOffset, params.yOffset};
   info.layer        = params.layer;
   info.level        = params.mipmap;
   info.srcReference = 0;
-  info.srcExtent2D  = {params.width, params.height};
-  info.srcOffset    = 0;
-  info.srcSize      = pixelData->GetBufferSize();
+  info.srcExtent2D  = {params.dataWidth, params.dataHeight};
+  info.srcOffset    = srcOffset;
+  info.srcSize      = srcSize;
+  info.srcStride    = srcStride;
+  info.srcFormat    = ConvertPixelFormat(pixelData->GetPixelFormat());
 
   Graphics::TextureUpdateSourceInfo updateSourceInfo{};
   updateSourceInfo.sourceType          = Graphics::TextureUpdateSourceInfo::Type::MEMORY;
@@ -308,9 +359,12 @@ bool Texture::HasAlphaChannel() const
 
 void Texture::GenerateMipmaps()
 {
-  mMaxMipMapLevel = 0;
-  DALI_LOG_ERROR("FIXME: GRAPHICS");
-  //@todo Implement with Graphics API
+  if(!mGraphicsTexture)
+  {
+    Create(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE));
+  }
+
+  mGraphicsController->GenerateTextureMipmaps(*mGraphicsTexture.get());
 }
 
 } // namespace Render