Add ImageUrl Class and reference count for external texture 98/259398/34
authorSunghyun Kim <scholb.kim@samsung.com>
Mon, 7 Jun 2021 07:42:25 +0000 (16:42 +0900)
committertscholb <scholb.kim@samsung.com>
Fri, 16 Jul 2021 03:33:36 +0000 (12:33 +0900)
1.Add ImageUrl Class
ImageUrl is a class for wrapping url that is get from external buffer
the purpose of this class is that manage this external buffer

2.Add reference count for external texturea

Change-Id: I3eb0bb3280d84035db9d981ae73807847e5b74bc

18 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualUrl.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-Image.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageUrl.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
dali-toolkit/internal/controls/web-view/web-view-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/image-loader/image-url-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/image-loader/image-url-impl.h [new file with mode: 0644]
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/internal/visuals/visual-url.cpp
dali-toolkit/internal/visuals/visual-url.h
dali-toolkit/public-api/file.list
dali-toolkit/public-api/image-loader/image-url.cpp [new file with mode: 0644]
dali-toolkit/public-api/image-loader/image-url.h [new file with mode: 0644]
dali-toolkit/public-api/image-loader/image.cpp
dali-toolkit/public-api/image-loader/image.h

index 962ad8e..c57ec89 100644 (file)
@@ -42,6 +42,18 @@ int UtcDaliVisualUrlConstructor(void)
   DALI_TEST_EQUALS( true, visualUrl3.IsValid(), TEST_LOCATION );
   DALI_TEST_EQUALS( visualUrl3.GetType(), VisualUrl::GIF, TEST_LOCATION );
   DALI_TEST_EQUALS( visualUrl3.GetProtocolType(), VisualUrl::LOCAL, TEST_LOCATION );
+
+  VisualUrl visualUrl4("dali://0");
+  visualUrl4 = visualUrl;
+  DALI_TEST_EQUALS( true, visualUrl4.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl4.GetType(), VisualUrl::GIF, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl4.GetProtocolType(), VisualUrl::LOCAL, TEST_LOCATION );
+
+  VisualUrl visualUrl5("dali://1");
+  visualUrl4 = visualUrl5;
+  DALI_TEST_EQUALS( true, visualUrl4.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl4.GetType(), VisualUrl::REGULAR_IMAGE, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl4.GetProtocolType(), VisualUrl::TEXTURE, TEST_LOCATION );
   END_TEST;
 }
 
index 9b2691c..0e984f0 100755 (executable)
@@ -26,6 +26,7 @@ SET(TC_SOURCES
   utc-Dali-Image.cpp
   utc-Dali-ImageView.cpp
   utc-Dali-ImageVisual.cpp
+  utc-Dali-ImageUrl.cpp
   utc-Dali-JsonParser.cpp
   utc-Dali-KeyInputFocusManager.cpp
   utc-Dali-PageTurnView.cpp
index f19d181..37e3b5e 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/rendering/frame-buffer.h>
 #include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -51,9 +52,9 @@ int UtcDaliImageConvertFrameBufferToUrl1(void)
   FrameBuffer frameBuffer = FrameBuffer::New( width, height, FrameBuffer::Attachment::NONE );
 
   DALI_TEST_CHECK( frameBuffer );
-  std::string url = Dali::Toolkit::Image::GenerateUrl( frameBuffer, Pixel::Format::RGBA8888, width, height );
+  ImageUrl url = Dali::Toolkit::Image::GenerateUrl( frameBuffer, Pixel::Format::RGBA8888, width, height );
 
-  DALI_TEST_CHECK( url.size() > 0u );
+  DALI_TEST_CHECK( url.GetUrl().size() > 0u );
 
   END_TEST;
 }
@@ -71,7 +72,7 @@ int UtcDaliImageConvertFrameBufferToUrl2(void)
   Texture texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height );
   frameBuffer.AttachColorTexture( texture );
 
-  DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( frameBuffer, 0 ).size() > 0u );
+  DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( frameBuffer, 0 ).GetUrl().size() > 0u );
 
   END_TEST;
 }
@@ -89,7 +90,7 @@ int UtcDaliImageConvertPixelDataToUrl(void)
   unsigned char* buffer= reinterpret_cast<unsigned char*>( malloc( bufferSize ) );
   PixelData pixelData = PixelData::New( buffer, bufferSize, width, height, Pixel::RGB888, PixelData::FREE );
 
-  DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( pixelData ).size() > 0u );
+  DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( pixelData ).GetUrl().size() > 0u );
 
   END_TEST;
 }
@@ -106,7 +107,7 @@ int UtcDaliImageConvertNativeImageSourceToUrl(void)
   {
     NativeImageSourcePtr nativeImageSource = NativeImageSource::New(width, height, NativeImageSource::COLOR_DEPTH_DEFAULT );
 
-    DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( nativeImageSource ).size() > 0u );
+    DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( nativeImageSource ).GetUrl().size() > 0u );
   }
   catch(Dali::DaliException& e)
   {
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageUrl.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageUrl.cpp
new file mode 100644 (file)
index 0000000..09cc7cd
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+int UtcImageUrlConstructor(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline(" UtcImageUrlValid ");
+
+  // Test default constructor.
+  ImageUrl imageUrl;
+  DALI_TEST_CHECK( !imageUrl );
+
+  // Test object creation
+  Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 4u, 4u); // test texture
+  imageUrl = ImageUrl::New(image);
+  DALI_TEST_CHECK( imageUrl );
+
+  // Test copy constructor
+  ImageUrl ImageUrlCopy( imageUrl );
+  DALI_TEST_CHECK( ImageUrlCopy );
+
+  // Test down cast
+  BaseHandle baseUrl;
+  baseUrl = imageUrl;
+  ImageUrl downcastUrl = ImageUrl::DownCast( baseUrl );
+  DALI_TEST_CHECK( downcastUrl );
+  END_TEST;
+}
\ No newline at end of file
index fdf1697..40ca439 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include "dummy-control.h"
 
@@ -424,7 +425,8 @@ int UtcDaliImageVisualWithNativeImage(void)
   tet_infoline( "Use Native Image as url" );
 
   NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT);
-  std::string url = Dali::Toolkit::Image::GenerateUrl(nativeImageSource);
+  ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource);
+  std::string url = imageUrl.GetUrl();
 
   VisualFactory factory = VisualFactory::Get();
   DALI_TEST_CHECK( factory );
@@ -462,6 +464,62 @@ int UtcDaliImageVisualWithNativeImage(void)
   END_TEST;
 }
 
+int UtcDaliImageVisualWithNativeImageRemoved(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Use Native Image as url" );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT);
+  ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource);
+  std::string url = imageUrl.GetUrl();
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( ImageVisual::Property::URL,  url );
+
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(  DummyControl::Property::TEST_VISUAL, visual );
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+  application.GetScene().Add( actor );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION );
+
+  tet_infoline( "No delete texture because reference count is not zero" );
+  imageUrl.Reset();
+  application.GetScene().Remove( actor );
+  dummyImpl.UnregisterVisual( DummyControl::Property::TEST_VISUAL );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION );
+
+  tet_infoline( "Delete texture because reference count is zero" );
+  visual.Reset();
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliImageVisualTextureReuse1(void)
 {
   ToolkitTestApplication application;
index 0457186..170495c 100755 (executable)
@@ -52,6 +52,7 @@
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 
 namespace Dali
 {
@@ -634,8 +635,8 @@ Dali::Toolkit::ImageView WebView::CreateImageView(Dali::PixelData pixel) const
     return Dali::Toolkit::ImageView();
   }
 
-  std::string              url       = Dali::Toolkit::Image::GenerateUrl(pixel);
-  Dali::Toolkit::ImageView imageView = Dali::Toolkit::ImageView::New(url);
+  Dali::Toolkit::ImageUrl url       = Dali::Toolkit::Image::GenerateUrl(pixel);
+  Dali::Toolkit::ImageView imageView = Dali::Toolkit::ImageView::New(url.GetUrl());
   imageView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixel.GetWidth(), pixel.GetHeight()));
   return imageView;
 }
index 9cab1a6..a661176 100644 (file)
@@ -124,6 +124,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/image-loader/atlas-packer.cpp
    ${toolkit_src_dir}/image-loader/image-atlas-impl.cpp
    ${toolkit_src_dir}/image-loader/image-load-thread.cpp
+   ${toolkit_src_dir}/image-loader/image-url-impl.cpp
    ${toolkit_src_dir}/styling/style-manager-impl.cpp
    ${toolkit_src_dir}/text/bidirectional-support.cpp
    ${toolkit_src_dir}/text/character-set-conversion.cpp
diff --git a/dali-toolkit/internal/image-loader/image-url-impl.cpp b/dali-toolkit/internal/image-loader/image-url-impl.cpp
new file mode 100644 (file)
index 0000000..055738f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include <dali-toolkit/internal/image-loader/image-url-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+ImageUrl::ImageUrl(Texture& texture)
+: mUrl("")
+{
+  mUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
+}
+
+ImageUrl::~ImageUrl()
+{
+  Dali::Toolkit::TextureManager::RemoveTexture(mUrl);
+}
+
+ImageUrlPtr ImageUrl::New(Texture& texture)
+{
+  ImageUrlPtr imageUrlPtr = new ImageUrl(texture);
+  return imageUrlPtr;
+}
+
+const std::string& ImageUrl::GetUrl() const
+{
+  return mUrl;
+}
+
+} // End of namespace Internal
+
+} // End of namespace Toolkit
+
+} // End of namespace Dali
diff --git a/dali-toolkit/internal/image-loader/image-url-impl.h b/dali-toolkit/internal/image-loader/image-url-impl.h
new file mode 100644 (file)
index 0000000..45981b2
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef DALI_TOOLKIT_INTERNAL_IMAGE_URL_H
+#define DALI_TOOLKIT_INTERNAL_IMAGE_URL_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/image-loader/image-url.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+class ImageUrl;
+using ImageUrlPtr = IntrusivePtr<ImageUrl>;
+
+class ImageUrl : public BaseObject
+{
+public:
+  /**
+   * @brief Constructor.
+   */
+  ImageUrl(Texture& texture);
+
+  /**
+   * @copydoc Dali::Toolkit::ImageUrl::New
+   */
+  static ImageUrlPtr New(Texture& texture);
+
+  /**
+   * @copydoc Dali::Toolkit::ImageUrl::GetUrl
+   */
+  const std::string& GetUrl() const;
+
+protected:
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~ImageUrl();
+
+private:
+  // Undefined
+  ImageUrl(const ImageUrl&);
+
+  // Undefined
+  ImageUrl& operator=(const ImageUrl& rhs);
+
+private:
+  std::string mUrl;
+};
+
+} // namespace Internal
+} // namespace Toolkit
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::ImageUrl& GetImpl(Dali::Toolkit::ImageUrl& imageUrl)
+{
+  DALI_ASSERT_ALWAYS(imageUrl && "ImageUrl handle is empty");
+
+  BaseObject& handle = imageUrl.GetBaseObject();
+
+  return static_cast<Toolkit::Internal::ImageUrl&>(handle);
+}
+
+inline const Toolkit::Internal::ImageUrl& GetImpl(const Dali::Toolkit::ImageUrl& imageUrl)
+{
+  DALI_ASSERT_ALWAYS(imageUrl && "ImageUrl handle is empty");
+
+  const BaseObject& handle = imageUrl.GetBaseObject();
+
+  return static_cast<const Toolkit::Internal::ImageUrl&>(handle);
+}
+
+} // End of namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_IMAGE_URL_H
index a449997..b225d8d 100644 (file)
@@ -519,6 +519,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
 void TextureManager::Remove(const TextureManager::TextureId textureId, TextureUploadObserver* observer)
 {
   int textureInfoIndex = GetCacheIndexFromId(textureId);
+
   if(textureInfoIndex != INVALID_INDEX)
   {
     TextureInfo& textureInfo(mTextureInfoContainer[textureInfoIndex]);
@@ -660,6 +661,7 @@ std::string TextureManager::AddExternalTexture(TextureSet& textureSet)
   info.textureId  = GenerateUniqueTextureId();
   info.textureSet = textureSet;
   mExternalTextures.emplace_back(info);
+
   return VisualUrl::CreateTextureUrl(std::to_string(info.textureId));
 }
 
@@ -668,10 +670,9 @@ TextureSet TextureManager::RemoveExternalTexture(const std::string& url)
   if(url.size() > 0u)
   {
     // get the location from the Url
-    VisualUrl parseUrl(url);
-    if(VisualUrl::TEXTURE == parseUrl.GetProtocolType())
+    if(VisualUrl::TEXTURE == VisualUrl::GetProtocolType(url))
     {
-      std::string location = parseUrl.GetLocation();
+      std::string location = VisualUrl::GetLocation(url);
       if(location.size() > 0u)
       {
         TextureId  id  = std::stoi(location);
@@ -681,7 +682,10 @@ TextureSet TextureManager::RemoveExternalTexture(const std::string& url)
           if(iter->textureId == id)
           {
             auto textureSet = iter->textureSet;
-            mExternalTextures.erase(iter);
+            if(--(iter->referenceCount) <= 0)
+            {
+              mExternalTextures.erase(iter);
+            }
             return textureSet;
           }
         }
@@ -691,6 +695,26 @@ TextureSet TextureManager::RemoveExternalTexture(const std::string& url)
   return TextureSet();
 }
 
+void TextureManager::UseExternalTexture(const VisualUrl& url)
+{
+  if(VisualUrl::TEXTURE == url.GetProtocolType())
+  {
+    std::string location = url.GetLocation();
+    if(location.size() > 0u)
+    {
+      TextureId id = std::stoi(location);
+      for(auto&& elem : mExternalTextures)
+      {
+        if(elem.textureId == id)
+        {
+          elem.referenceCount++;
+          return;
+        }
+      }
+    }
+  }
+}
+
 void TextureManager::AddObserver(TextureManager::LifecycleObserver& observer)
 {
   // make sure an observer doesn't observe the same object twice
index 089ae92..c9618a9 100644 (file)
@@ -403,6 +403,12 @@ public:
   TextureSet RemoveExternalTexture(const std::string& url);
 
   /**
+   * @brief Notify that external textures are used.
+   * @param[in] url The URL of the texture to use.
+   */
+  void UseExternalTexture(const VisualUrl& url);
+
+  /**
    * Add an observer to the object.
    * @param[in] observer The observer to add.
    */
@@ -850,6 +856,7 @@ private:
   {
     TextureId  textureId;
     TextureSet textureSet;
+    int16_t    referenceCount{1};
   };
 
 private:
index e498313..1979f78 100644 (file)
 // EXTERNAL HEADERS
 #include <cstring> // for toupper()
 
+// INTERNAL HEADERS
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -209,6 +213,14 @@ VisualUrl::VisualUrl(const std::string& url)
       // TEXTURE location url doesn't need type resolving, REGULAR_IMAGE is fine
       mType = ResolveType(url);
     }
+    else
+    {
+      Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+      if(factory)
+      {
+        GetImplementation(factory).GetTextureManager().UseExternalTexture(*this);
+      }
+    }
   }
 }
 
@@ -217,15 +229,53 @@ VisualUrl::VisualUrl(const VisualUrl& url)
   mType(url.mType),
   mLocation(url.mLocation)
 {
+  if(VisualUrl::TEXTURE == mLocation)
+  {
+    Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+    if(factory)
+    {
+      GetImplementation(factory).GetTextureManager().UseExternalTexture(*this);
+    }
+  }
+}
+
+VisualUrl::~VisualUrl()
+{
+  if(VisualUrl::TEXTURE == mLocation)
+  {
+    Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+    if(factory)
+    {
+      GetImplementation(factory).GetTextureManager().RemoveExternalTexture(mUrl);
+    }
+  }
 }
 
 VisualUrl& VisualUrl::operator=(const VisualUrl& url)
 {
   if(&url != this)
   {
+    if(VisualUrl::TEXTURE == mLocation)
+    {
+      Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+      if(factory)
+      {
+        GetImplementation(factory).GetTextureManager().RemoveExternalTexture(mUrl);
+      }
+    }
+
     mUrl      = url.mUrl;
     mType     = url.mType;
     mLocation = url.mLocation;
+
+    if(VisualUrl::TEXTURE == mLocation)
+    {
+      Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+      if(factory)
+      {
+        GetImplementation(factory).GetTextureManager().UseExternalTexture(*this);
+      }
+    }
   }
   return *this;
 }
@@ -257,12 +307,7 @@ bool VisualUrl::IsLocalResource() const
 
 std::string VisualUrl::GetLocation() const
 {
-  const auto location = mUrl.find("://");
-  if(std::string::npos != location)
-  {
-    return mUrl.substr(location + 3u); // 3 characters forwards from the start of ://
-  }
-  return mUrl;
+  return GetLocation(mUrl);
 }
 
 std::string VisualUrl::CreateTextureUrl(const std::string& location)
@@ -270,6 +315,22 @@ std::string VisualUrl::CreateTextureUrl(const std::string& location)
   return "dali://" + location;
 }
 
+VisualUrl::ProtocolType VisualUrl::GetProtocolType(const std::string& url)
+{
+  return ResolveLocation(url);
+}
+
+std::string VisualUrl::GetLocation(const std::string& url)
+{
+  const auto location = url.find("://");
+  if(std::string::npos != location)
+  {
+    return url.substr(location + 3u); // 3 characters forwards from the start of ://
+  }
+  return url;
+}
+
+
 } // namespace Internal
 
 } // namespace Toolkit
index 8857184..a772bd1 100644 (file)
@@ -55,8 +55,16 @@ public:
   VisualUrl();
 
   /**
+   * Default Destructor.
+   * Delete an external texture if if protocolType is TEXTURE.
+   */
+  ~VisualUrl();
+
+  /**
    * Constructor.
    * Determines type of visual and whether the url is local or remote
+   * Notify that it is using an external texture if if protocolType is TEXTURE.
+   *
    * @param[in] url The URL to store and resolve
    */
   VisualUrl(const std::string& url);
@@ -114,6 +122,19 @@ public:
    */
   static std::string CreateTextureUrl(const std::string& location);
 
+  /**
+   * Helper to get a ProtocolType from url
+   * @param url the url of the texture
+   * @return the protocol type
+   */
+  static VisualUrl::ProtocolType GetProtocolType(const std::string& url);
+
+  /**
+   * Helper to get a location from url
+   * @param url the location of the texture
+   * @return the location
+   */
+  static std::string GetLocation(const std::string& url);
 private:
   std::string  mUrl;
   Type         mType;
index 15e202b..212dba7 100644 (file)
@@ -28,6 +28,7 @@ SET( public_api_src_files
   ${public_api_src_dir}/controls/video-view/video-view.cpp
   ${public_api_src_dir}/controls/camera-view/camera-view.cpp
   ${public_api_src_dir}/image-loader/image.cpp
+  ${public_api_src_dir}/image-loader/image-url.cpp
   ${public_api_src_dir}/image-loader/async-image-loader.cpp
   ${public_api_src_dir}/image-loader/sync-image-loader.cpp
   ${public_api_src_dir}/styling/style-manager.cpp
@@ -84,6 +85,7 @@ SET( public_api_item_view_header_files
 
 SET( public_api_image_loader_header_files
   ${public_api_src_dir}/image-loader/image.h
+  ${public_api_src_dir}/image-loader/image-url.h
   ${public_api_src_dir}/image-loader/async-image-loader.h
   ${public_api_src_dir}/image-loader/sync-image-loader.h
 )
diff --git a/dali-toolkit/public-api/image-loader/image-url.cpp b/dali-toolkit/public-api/image-loader/image-url.cpp
new file mode 100644 (file)
index 0000000..65b9601
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/public-api/image-loader/image-url.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/image-loader/image-url-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+ImageUrl::ImageUrl()
+{
+}
+
+ImageUrl::~ImageUrl()
+{
+}
+
+ImageUrl ImageUrl::New(Texture& texture)
+{
+  Toolkit::Internal::ImageUrlPtr internal = Toolkit::Internal::ImageUrl::New(texture);
+  return ImageUrl(internal.Get());
+}
+
+ImageUrl ImageUrl::DownCast(BaseHandle handle)
+{
+  return ImageUrl(dynamic_cast<Toolkit::Internal::ImageUrl*>(handle.GetObjectPtr()));
+}
+
+ImageUrl::ImageUrl(const ImageUrl& rhs) = default;
+
+ImageUrl& ImageUrl::operator=(const ImageUrl& url) = default;
+
+ImageUrl::ImageUrl(ImageUrl&& rhs) = default;
+
+ImageUrl& ImageUrl::operator=(ImageUrl&& rhs) = default;
+
+const std::string& ImageUrl::GetUrl() const
+{
+  return GetImpl(*this).GetUrl();
+}
+
+ImageUrl::ImageUrl(Toolkit::Internal::ImageUrl* internal)
+: BaseHandle(internal)
+{
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/public-api/image-loader/image-url.h b/dali-toolkit/public-api/image-loader/image-url.h
new file mode 100644 (file)
index 0000000..819198b
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef DALI_TOOLKIT_IMAGE_URL_H
+#define DALI_TOOLKIT_IMAGE_URL_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <dali/public-api/rendering/texture.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal DALI_INTERNAL
+{
+class ImageUrl;
+}
+/**
+ * @brief ImageUrl can be used to wrap an external buffer.
+ *
+ * An instance of ImageUrl can be created from Image::GenerateUrl().
+ * Application can get url from ImageUrl.
+ * When application does not use this anymore, the destructor of the ImageUrl is called.
+ * At this time, the buffer is deleted from the texture manager.
+ */
+class DALI_TOOLKIT_API ImageUrl : public BaseHandle
+{
+public:
+  /**
+   * Default Constructor.
+   * Resulting URL is not valid
+   */
+  ImageUrl();
+
+  /**
+   * Destructor
+   */
+  ~ImageUrl();
+
+  /**
+   * @brief Create an initialized ImageUrl.
+   *
+   * @param[in] texture The texture url is got from external buffer.
+   * @return A handle to a newly allocated Dali resource.
+   */
+  static ImageUrl New(Texture& texture);
+
+  /**
+   * @brief Downcast an Object handle to ImageUrl handle.
+   *
+   * If handle points to a ImageUrl object the downcast produces valid
+   * handle. If not the returned handle is left uninitialized.
+   *
+   * @param[in] handle to An object.
+   * @return handle to a ImageUrl object or an uninitialized handle.
+   */
+  static ImageUrl DownCast(BaseHandle handle);
+
+  /**
+   * Copy constructor
+   * @param[in] url The url to copy
+   */
+  ImageUrl(const ImageUrl& url);
+
+  /**
+   * Assignment operator
+   * @param[in] url The url to copy
+   */
+  ImageUrl& operator=(const ImageUrl& url);
+
+  /**
+   * @brief Move constructor.
+   * @param[in] rhs A reference to the moved handle
+   */
+  ImageUrl(ImageUrl&& rhs);
+
+  /**
+   * @brief Move assignment operator.
+   * @param[in] rhs A reference to the moved handle
+   * @return A reference to this handle
+   */
+  ImageUrl& operator=(ImageUrl&& rhs);
+
+  /**
+   * Get the url
+   * @return Returns url's string
+   */
+  const std::string& GetUrl() const;
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief This constructor is used by New() methods.
+   *
+   * @param[in] internal A pointer to a newly allocated Dali resource.
+   */
+  explicit DALI_INTERNAL ImageUrl(Toolkit::Internal::ImageUrl* internal);
+  /// @endcond
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_IMAGE_URL_H */
index 2dc20c8..b44061e 100644 (file)
@@ -19,6 +19,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/rendering/frame-buffer-devel.h>
@@ -29,30 +30,34 @@ namespace Toolkit
 {
 namespace Image
 {
-std::string GenerateUrl(Dali::FrameBuffer frameBuffer, Pixel::Format pixelFormat, uint32_t width, uint32_t height)
+Dali::Toolkit::ImageUrl GenerateUrl(Dali::FrameBuffer frameBuffer, Pixel::Format pixelFormat, uint32_t width, uint32_t height)
 {
   Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelFormat, width, height);
   frameBuffer.AttachColorTexture(texture, 0u, 0u);
-  return Dali::Toolkit::TextureManager::AddTexture(texture);
+  Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::ImageUrl::New(texture);
+  return imageUrl;
 }
 
-std::string GenerateUrl(const Dali::FrameBuffer frameBuffer, uint8_t index)
+Dali::Toolkit::ImageUrl GenerateUrl(const Dali::FrameBuffer frameBuffer, uint8_t index)
 {
   Texture texture = Dali::DevelFrameBuffer::GetColorTexture(frameBuffer, index);
-  return Dali::Toolkit::TextureManager::AddTexture(texture);
+  Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::ImageUrl::New(texture);
+  return imageUrl;
 }
 
-std::string GenerateUrl(const Dali::PixelData pixelData)
+Dali::Toolkit::ImageUrl GenerateUrl(const Dali::PixelData pixelData)
 {
   Texture texture = Texture::New(TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
   texture.Upload(pixelData);
-  return Dali::Toolkit::TextureManager::AddTexture(texture);
+  Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::ImageUrl::New(texture);
+  return imageUrl;
 }
 
-std::string GenerateUrl(const Dali::NativeImageSourcePtr nativeImageSource)
+Dali::Toolkit::ImageUrl GenerateUrl(const Dali::NativeImageSourcePtr nativeImageSource)
 {
   Texture texture = Dali::Texture::New(*nativeImageSource);
-  return Dali::Toolkit::TextureManager::AddTexture(texture);
+  Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::ImageUrl::New(texture);
+  return imageUrl;
 }
 
 } // namespace Image
index 6fb2816..ad2f56e 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/dali-toolkit-common.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 
 namespace Dali
 {
@@ -44,9 +45,9 @@ namespace Image
  * @param[in] pixelFormat the pixel format for this frame buffer
  * @param[in] width the width for this frame buffer
  * @param[in] height the height for this frame buffer
- * @return the Url string representing this frame buffer
+ * @return the ImageUrl representing this frame buffer
  */
-DALI_TOOLKIT_API std::string GenerateUrl(const Dali::FrameBuffer frameBuffer, Pixel::Format pixelFormat, uint32_t width, uint32_t height);
+DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::FrameBuffer frameBuffer, Pixel::Format pixelFormat, uint32_t width, uint32_t height);
 
 /**
  * @brief Generate a Url from frame buffer.
@@ -55,27 +56,27 @@ DALI_TOOLKIT_API std::string GenerateUrl(const Dali::FrameBuffer frameBuffer, Pi
  * This method does not check for duplicates, If same frame buffer is entered multiple times, a different URL is returned each time.
  * @param[in] frameBuffer the frame buffer to converted to Url
  * @param[in] index the index of the attached color texture.
- * @return the Url string representing this frame buffer
+ * @return the ImageUrl representing this frame buffer
  */
-DALI_TOOLKIT_API std::string GenerateUrl(const Dali::FrameBuffer frameBuffer, uint8_t index);
+DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::FrameBuffer frameBuffer, uint8_t index);
 
 /**
  * @brief Generate a Url from Pixel data.
  * This Url can be used in visuals to render the pixel data.
  * @note This method does not check for duplicates, If same pixel data is entered multiple times, a different URL is returned each time.
  * @param[in] pixelData the pixel data to converted to Url
- * @return the Url string representing this pixel data
+ * @return the ImageUrl representing this pixel data
  */
-DALI_TOOLKIT_API std::string GenerateUrl(const Dali::PixelData pixelData);
+DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::PixelData pixelData);
 
 /**
  * @brief Generate a Url from native image source.
  * This Url can be used in visuals to render the native image source.
  * @note This method does not check for duplicates, If same native image source is entered multiple times, a different URL is returned each time.
  * @param[in] nativeImageSource the native image source to converted to Url
- * @return the Url string representing this native image source
+ * @return the ImageUrl representing this native image source
  */
-DALI_TOOLKIT_API std::string GenerateUrl(const Dali::NativeImageSourcePtr nativeImageSource);
+DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::NativeImageSourcePtr nativeImageSource);
 
 } // namespace Image