Merge branch 'devel/master' into tizen
authorSeoyeon Kim <seoyeon2.kim@samsung.com>
Tue, 27 Feb 2024 07:08:23 +0000 (16:08 +0900)
committerSeoyeon Kim <seoyeon2.kim@samsung.com>
Tue, 27 Feb 2024 07:08:23 +0000 (16:08 +0900)
Change-Id: I2d8a0ed4b0483be6184c6f738eddbcebf5f50936

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/imaging/common/animated-image-loading-impl.h
dali/internal/imaging/common/gif-loading.cpp
dali/internal/imaging/common/gif-loading.h
dali/internal/imaging/common/webp-loading.cpp
dali/internal/imaging/common/webp-loading.h
dali/public-api/dali-adaptor-version.cpp
packaging/dali-adaptor.spec

index 3d7979a..a3eb62f 100644 (file)
@@ -695,7 +695,13 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
       {
         auto* info = &cmd.drawNative.drawNativeInfo;
 
-        mCurrentContext->PrepareForNativeRendering();
+        // ISOLATED execution mode will isolate GL graphics context from
+        // DALi renderning pipeline which is the safest way of rendering
+        // the 'injected' code.
+        if(info->executionMode == DrawNativeExecutionMode::ISOLATED)
+        {
+          mCurrentContext->PrepareForNativeRendering();
+        }
 
         if(info->glesNativeInfo.eglSharedContextStoragePointer)
         {
@@ -704,8 +710,21 @@ void EglGraphicsController::ProcessCommandBuffer(const GLES::CommandBuffer& comm
         }
 
         CallbackBase::ExecuteReturn<bool>(*info->callback, info->userData);
-
-        mCurrentContext->RestoreFromNativeRendering();
+        if(info->executionMode == DrawNativeExecutionMode::ISOLATED)
+        {
+          mCurrentContext->RestoreFromNativeRendering();
+        }
+        else
+        {
+          // After native rendering reset all states and caches.
+          // This is going to be called only when DIRECT execution mode is used
+          // and some GL states need to be reset.
+          // This does not guarantee that after execution a custom GL code
+          // the main rendering pipeline will work correctly and it's a responsibility
+          // of developer to make sure the GL states are not interfering with main
+          // rendering pipeline (by restoring/cleaning up GL states after drawing).
+          mCurrentContext->ResetGLESState();
+        }
         break;
       }
     }
@@ -783,12 +802,14 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
           auto                 sourceStride = info.srcStride;
           std::vector<uint8_t> tempBuffer;
 
+          uint8_t* srcBuffer = sourceBuffer;
+
           if(mGlAbstraction->TextureRequiresConverting(srcFormat, destFormat, isSubImage))
           {
             // Convert RGB to RGBA if necessary.
             if(texture->TryConvertPixelData(sourceBuffer, info.srcFormat, createInfo.format, info.srcSize, info.srcStride, info.srcExtent2D.width, info.srcExtent2D.height, tempBuffer))
             {
-              sourceBuffer = &tempBuffer[0];
+              srcBuffer    = &tempBuffer[0];
               sourceStride = 0u; // Converted buffer compacted. make stride as 0.
               srcFormat    = destFormat;
               srcType      = GLES::GLTextureFormatType(createInfo.format).type;
@@ -824,7 +845,7 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
                                          0,
                                          srcFormat,
                                          srcType,
-                                         sourceBuffer);
+                                         srcBuffer);
             }
             else
             {
@@ -835,7 +856,7 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
                                                    info.srcExtent2D.height,
                                                    0,
                                                    info.srcSize,
-                                                   sourceBuffer);
+                                                   srcBuffer);
             }
           }
           else
@@ -850,7 +871,7 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
                                             info.srcExtent2D.height,
                                             srcFormat,
                                             srcType,
-                                            sourceBuffer);
+                                            srcBuffer);
             }
             else
             {
@@ -862,7 +883,7 @@ void EglGraphicsController::ProcessTextureUpdateQueue()
                                                       info.srcExtent2D.height,
                                                       srcFormat,
                                                       info.srcSize,
-                                                      sourceBuffer);
+                                                      srcBuffer);
             }
           }
         }
index c90b2a8..b7e829b 100644 (file)
@@ -198,7 +198,7 @@ struct Context::Impl
 
   /**
    * Either enables or disables a vertex attribute location in the cache
-   * The cahnges won't take affect until FlushVertexAttributeLocations is called
+   * The changes won't take affect until FlushVertexAttributeLocations is called
    * @param location attribute location
    * @param state attribute state
    */
@@ -1308,6 +1308,27 @@ void Context::PrepareForNativeRendering()
   }
 
   eglMakeCurrent(display, drawSurface, readSurface, mImpl->mNativeDrawContext);
+  // make sure it's current window context
+  eglMakeCurrent(display, mImpl->mCacheDrawWriteSurface, mImpl->mCacheDrawReadSurface, mImpl->mCacheEGLGraphicsContext);
+}
+
+void Context::ResetGLESState()
+{
+  mImpl->mGlStateCache.ResetBufferCache();
+  mImpl->mGlStateCache.ResetTextureCache();
+  mImpl->mCurrentPipeline = nullptr;
+  mImpl->mCurrentUBOBindings.clear();
+  mImpl->mCurrentTextureBindings.clear();
+  mImpl->mCurrentVertexBufferBindings.clear();
+  mImpl->mCurrentRenderTarget = nullptr;
+  mImpl->mCurrentRenderPass = nullptr;
+  mImpl->mVertexBuffersChanged = true;
+  mImpl->mCurrentIndexBufferBinding = {};
+  mImpl->mCurrentSamplerBindings = {};
+  mImpl->mProgramVAOCurrentState = 0;
+
+  ClearState();
+  mImpl->InitializeGlState();
 }
 
 void Context::RestoreFromNativeRendering()
index f4cde6d..d627360 100644 (file)
@@ -223,6 +223,7 @@ public:
   void SetDepthTestEnable(bool depthTestEnable);
   void SetDepthWriteEnable(bool depthWriteEnable);
 
+  void ResetGLESState();
 private:
   /**
    * @brief Clear current state
index a240b1d..a150053 100644 (file)
@@ -82,7 +82,7 @@ public:
                                      Dali::FittingMode::Type  fittingMode,
                                      Dali::SamplingMode::Type samplingMode)
   {
-    Dali::Devel::PixelBuffer pixelBuffer = LoadFrame(frameIndex);
+    Dali::Devel::PixelBuffer pixelBuffer = LoadFrame(frameIndex, size);
     return Dali::Internal::Platform::ApplyAttributesToBitmap(pixelBuffer, size, fittingMode, samplingMode);
   }
 
@@ -119,9 +119,10 @@ private:
    *
    * @note This function will load the entire animated image into memory if not already loaded.
    * @param[in] frameIndex The frame index to load.
+   * @param[in] size The width and height to fit the loaded image to.
    * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
    */
-  virtual Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex) = 0;
+  virtual Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex, ImageDimensions size = ImageDimensions()) = 0;
 };
 
 } // namespace Adaptor
index 7c04fc2..37d8109 100644 (file)
@@ -1576,7 +1576,7 @@ GifLoading::~GifLoading()
   delete mImpl;
 }
 
-Dali::Devel::PixelBuffer GifLoading::LoadFrame(uint32_t frameIndex)
+Dali::Devel::PixelBuffer GifLoading::LoadFrame(uint32_t frameIndex, ImageDimensions desiredSize)
 {
   int                      error;
   Dali::Devel::PixelBuffer pixelBuffer;
index 2de8ead..dbc564a 100644 (file)
@@ -75,7 +75,7 @@ public:
    * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
    */
 
-  Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex) override;
+  Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex, ImageDimensions size) override;
 
   /**
    * @brief Get the size of a gif image.
index 1903d2c..0dd3c85 100644 (file)
@@ -307,7 +307,7 @@ WebPLoading::~WebPLoading()
   delete mImpl;
 }
 
-Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex)
+Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex, ImageDimensions desiredSize)
 {
   Dali::Devel::PixelBuffer pixelBuffer;
 
@@ -334,22 +334,71 @@ Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex)
       {
         uint32_t channelNumber = (features.has_alpha) ? 4 : 3;
         uint8_t* frameBuffer   = nullptr;
-        if(channelNumber == 4)
+
+        if(desiredSize.GetWidth() > 0 && desiredSize.GetHeight() > 0)
         {
-          frameBuffer = WebPDecodeRGBA(mImpl->mBuffer, mImpl->mBufferSize, &width, &height);
+          const int desiredWidth = desiredSize.GetWidth();
+          const int desiredHeight = desiredSize.GetHeight();
+
+          WebPDecoderConfig config;
+          if(!DALI_LIKELY(WebPInitDecoderConfig(&config)))
+          {
+            DALI_LOG_ERROR("WebPInitDecoderConfig is failed");
+            return pixelBuffer;
+          }
+
+          // Apply config for scaling
+          config.options.use_scaling = 1;
+          config.options.scaled_width = desiredWidth;
+          config.options.scaled_height = desiredHeight;
+
+          if(channelNumber == 4)
+          {
+            config.output.colorspace = MODE_RGBA;
+          }
+          else
+          {
+            config.output.colorspace = MODE_RGB;
+          }
+
+          if(WebPDecode(mImpl->mBuffer, mImpl->mBufferSize, &config) == VP8_STATUS_OK)
+          {
+            frameBuffer = config.output.u.RGBA.rgba;
+          }
+          else
+          {
+            DALI_LOG_ERROR("Webp Decoding with scaled size is failed \n");
+          }
+
+          if(frameBuffer != nullptr)
+          {
+            Pixel::Format                     pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
+            int32_t                           bufferSize  = desiredWidth * desiredHeight * Dali::Pixel::GetBytesPerPixel(pixelFormat);
+            pixelBuffer  = Dali::Devel::PixelBuffer::New(desiredWidth, desiredHeight, pixelFormat);
+            memcpy(pixelBuffer.GetBuffer(), frameBuffer, bufferSize);
+          }
+
+          WebPFreeDecBuffer(&config.output);
         }
         else
         {
-          frameBuffer = WebPDecodeRGB(mImpl->mBuffer, mImpl->mBufferSize, &width, &height);
-        }
+          if(channelNumber == 4)
+          {
+            frameBuffer = WebPDecodeRGBA(mImpl->mBuffer, mImpl->mBufferSize, &width, &height);
+          }
+          else
+          {
+            frameBuffer = WebPDecodeRGB(mImpl->mBuffer, mImpl->mBufferSize, &width, &height);
+          }
 
-        if(frameBuffer != nullptr)
-        {
-          Pixel::Format                     pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
-          int32_t                           bufferSize  = width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat);
-          Internal::Adaptor::PixelBufferPtr internal =
+          if(frameBuffer != nullptr)
+          {
+            Pixel::Format                     pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
+            int32_t                           bufferSize  = width * height * Dali::Pixel::GetBytesPerPixel(pixelFormat);
+            Internal::Adaptor::PixelBufferPtr internal =
             Internal::Adaptor::PixelBuffer::New(frameBuffer, bufferSize, width, height, width, pixelFormat);
-          pixelBuffer = Devel::PixelBuffer(internal.Get());
+            pixelBuffer = Devel::PixelBuffer(internal.Get());
+          }
         }
       }
     }
index 5a232fb..74eed61 100644 (file)
@@ -92,7 +92,7 @@ public:
    * @param[in] frameIndex The frame counter to load. Will usually be the next frame.
    * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
    */
-  Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex) override;
+  Dali::Devel::PixelBuffer LoadFrame(uint32_t frameIndex, ImageDimensions size) override;
 
   /**
    * @brief Get the size of a webp image.
index c5265f9..4c8b325 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const unsigned int ADAPTOR_MAJOR_VERSION = 2;
 const unsigned int ADAPTOR_MINOR_VERSION = 3;
-const unsigned int ADAPTOR_MICRO_VERSION = 11;
+const unsigned int ADAPTOR_MICRO_VERSION = 12;
 const char* const  ADAPTOR_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index cc82170..770f68b 100644 (file)
@@ -17,7 +17,7 @@
 
 Name:       dali2-adaptor
 Summary:    The DALi Tizen Adaptor
-Version:    2.3.11
+Version:    2.3.12
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT