NativeImageSource with tbm_surface for tizen 3.0 wayland 17/52517/16
authortaeyoon <taeyoon0.lee@samsung.com>
Tue, 24 Nov 2015 06:00:36 +0000 (15:00 +0900)
committerTaeyoon Lee <taeyoon0.lee@samsung.com>
Mon, 1 Feb 2016 05:03:59 +0000 (21:03 -0800)
 - NativeImageSource uses XPixmap or Ecore Pixmap type in x windows system.
 - Tizen 3.0 wayland doesn't support the pixmap type.
 -> Replaces pixmap to tbm_surface.
 -> Adds handling fragment shader code into ImageRenderer for tbm_surface
 -> Adds UTCs for various scenarios of ImageView (NativeImage vs. Regular image)

Change-Id: Ibe3747dcf5711f11770ae1e54d1ca37577d7ca6f

automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-native-image.h
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/controls/renderers/image/image-renderer.cpp
dali-toolkit/internal/controls/renderers/image/image-renderer.h

index e0e2601..10ef2a0 100644 (file)
@@ -79,6 +79,7 @@ LIST(APPEND TC_SOURCES
    dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
    dali-toolkit-test-utils/test-render-controller.cpp
    dali-toolkit-test-utils/test-trace-call-stack.cpp
    dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
    dali-toolkit-test-utils/test-render-controller.cpp
    dali-toolkit-test-utils/test-trace-call-stack.cpp
+   dali-toolkit-test-utils/test-native-image.cpp
 )
 
 
 )
 
 
index d143d35..d8ad2ba 100644 (file)
@@ -31,6 +31,7 @@ TestNativeImagePointer TestNativeImage::New(int width, int height)
 TestNativeImage::TestNativeImage(int width, int height)
 : mWidth(width), mHeight(height), mExtensionCreateCalls(0), mExtensionDestroyCalls(0), mTargetTextureCalls(0)
 {
 TestNativeImage::TestNativeImage(int width, int height)
 : mWidth(width), mHeight(height), mExtensionCreateCalls(0), mExtensionDestroyCalls(0), mTargetTextureCalls(0)
 {
+  mExtension = new TestNativeImageExtension();
 }
 
 TestNativeImage::~TestNativeImage()
 }
 
 TestNativeImage::~TestNativeImage()
index 4a39cb1..8dc6431 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/public-api/images/native-image-interface.h>
 
 // INTERNAL INCLUDES
 #include <dali/public-api/images/native-image-interface.h>
+#include <dali/devel-api/images/native-image-interface-extension.h>
 
 namespace Dali
 {
 class TestNativeImage;
 typedef IntrusivePtr<TestNativeImage> TestNativeImagePointer;
 
 
 namespace Dali
 {
 class TestNativeImage;
 typedef IntrusivePtr<TestNativeImage> TestNativeImagePointer;
 
+class DALI_IMPORT_API TestNativeImageExtension: public Dali::NativeImageInterface::Extension
+{
+public:
+  inline const char* GetCustomFragmentPreFix(){return "#extension GL_OES_EGL_image_external:require\n";}
+  inline const char* GetCustomSamplerTypename(){return "samplerExternalOES";}
+
+};
+
 class DALI_IMPORT_API TestNativeImage : public Dali::NativeImageInterface
 {
 public:
 class DALI_IMPORT_API TestNativeImage : public Dali::NativeImageInterface
 {
 public:
@@ -38,6 +47,7 @@ public:
   inline virtual unsigned int GetWidth() const {return mWidth;};
   inline virtual unsigned int GetHeight() const {return mHeight;};
   inline virtual bool RequiresBlending() const {return true;};
   inline virtual unsigned int GetWidth() const {return mWidth;};
   inline virtual unsigned int GetHeight() const {return mHeight;};
   inline virtual bool RequiresBlending() const {return true;};
+  inline virtual Dali::NativeImageInterface::Extension* GetExtension() {return mExtension;}
 
 private:
   TestNativeImage(int width, int height);
 
 private:
   TestNativeImage(int width, int height);
@@ -49,6 +59,7 @@ public:
   int mExtensionCreateCalls;
   int mExtensionDestroyCalls;
   int mTargetTextureCalls;
   int mExtensionCreateCalls;
   int mExtensionDestroyCalls;
   int mTargetTextureCalls;
+  TestNativeImageExtension* mExtension;
 };
 
 } // Dali
 };
 
 } // Dali
index cc62d54..32d987f 100644 (file)
@@ -24,6 +24,9 @@
 #include <dali/devel-api/rendering/material.h>
 #include <dali/devel-api/rendering/renderer.h>
 
 #include <dali/devel-api/rendering/material.h>
 #include <dali/devel-api/rendering/renderer.h>
 
+#include <test-native-image.h>
+#include <sstream>
+
 using namespace Dali;
 using namespace Toolkit;
 
 using namespace Dali;
 using namespace Toolkit;
 
@@ -39,6 +42,35 @@ void utc_dali_toolkit_image_view_cleanup(void)
 
 namespace
 {
 
 namespace
 {
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  varying mediump vec2 vTexCoord;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = aPosition + vec2(0.5);\n
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform lowp vec4 uColor;\n
+  \n
+  void main()\n
+  {\n
+    gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
+  }\n
+);
+
 const char* TEST_IMAGE_FILE_NAME =  "gallery_image_01.jpg";
 const char* TEST_IMAGE_FILE_NAME2 =  "gallery_image_02.jpg";
 
 const char* TEST_IMAGE_FILE_NAME =  "gallery_image_01.jpg";
 const char* TEST_IMAGE_FILE_NAME2 =  "gallery_image_02.jpg";
 
@@ -650,3 +682,290 @@ int UtcDaliImageViewResourceUrlP(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+// Scenarios 1: ImageView from regular image
+int UtcDaliImageViewSetImageBufferImage(void)
+{
+  ToolkitTestApplication application;
+
+  ImageView imageView = ImageView::New();
+  Stage::GetCurrent().Add( imageView );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.EnableTextureCallTrace( true );
+
+  std::vector< GLuint > ids;
+  ids.push_back( 23 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  int width = 300;
+  int height = 400;
+  BufferImage image = CreateBufferImage( width, height, Color::WHITE );
+
+  imageView.SetImage( image );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream params;
+  params << GL_TEXTURE_2D << ", " << 23;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) );
+
+  END_TEST;
+}
+
+// Scenarios 2: ImageView from Native image
+int UtcDaliImageViewSetImageNativeImage(void)
+{
+  ToolkitTestApplication application;
+
+  ImageView imageView = ImageView::New();
+  Stage::GetCurrent().Add( imageView );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.EnableTextureCallTrace( true );
+
+  std::vector< GLuint > ids;
+  ids.push_back( 23 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  int width = 200;
+  int height = 500;
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( width, height );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+
+  imageView.SetImage( nativeImage );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream params;
+  params << GL_TEXTURE_2D << ", " << 23;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) );
+
+  END_TEST;
+}
+
+// Scenarios 3: ImageView initially from regular image but then SetImage called with Native image
+int UtcDaliImageViewSetImageBufferImageToNativeImage(void)
+{
+  ToolkitTestApplication application;
+
+  int width = 300;
+  int height = 400;
+  BufferImage image = CreateBufferImage( width, height, Color::WHITE );
+
+  ImageView imageView = ImageView::New( image );
+  Stage::GetCurrent().Add( imageView );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.EnableTextureCallTrace( true );
+
+  std::vector< GLuint > ids;
+  ids.push_back( 23 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream params;
+  params << GL_TEXTURE_2D << ", " << 23;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) );
+
+  width = 200;
+  height = 500;
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( width, height );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+  imageView.SetImage( nativeImage );
+
+  ids.clear();
+  ids.push_back( 24 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream nextTextureParams;
+  nextTextureParams << GL_TEXTURE_2D << ", " << 24;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", nextTextureParams.str()) );
+
+  END_TEST;
+}
+
+// Scenarios 4: ImageView initially from Native image but then SetImage called with regular image
+int UtcDaliImageViewSetImageNativeImageToBufferImage(void)
+{
+  ToolkitTestApplication application;
+
+  int width = 300;
+  int height = 400;
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( width, height );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+
+  ImageView imageView = ImageView::New( nativeImage );
+  Stage::GetCurrent().Add( imageView );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.EnableTextureCallTrace( true );
+
+  std::vector< GLuint > ids;
+  ids.push_back( 23 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream params;
+  params << GL_TEXTURE_2D << ", " << 23;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) );
+
+  width = 200;
+  height = 500;
+  BufferImage image = CreateBufferImage( width, height, Color::WHITE );
+  imageView.SetImage( image );
+
+  ids.clear();
+  ids.push_back( 24 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream nextTextureParams;
+  nextTextureParams << GL_TEXTURE_2D << ", " << 24;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", nextTextureParams.str()) );
+
+  END_TEST;
+}
+
+// Scenarios 5: ImageView from Native image with custom shader
+int UtcDaliImageViewSetImageNativeImageWithCustomShader(void)
+{
+  ToolkitTestApplication application;
+
+  int width = 300;
+  int height = 400;
+
+  Property::Map customShader;
+  customShader.Insert( "vertexShader", VERTEX_SHADER );
+  customShader.Insert( "fragmentShader", FRAGMENT_SHADER );
+
+  Property::Array shaderHints;
+  shaderHints.PushBack( "requiresSelfDepthTest" );
+  shaderHints.PushBack( "outputIsTransparent" );
+  shaderHints.PushBack( "outputIsOpaque" );
+  shaderHints.PushBack( "modifiesGeometry" );
+
+  customShader.Insert( "hints", shaderHints );
+
+  Property::Map map;
+  map.Insert( "rendererType", "imageRenderer" );
+  map.Insert( "shader", customShader );
+
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( width, height );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+
+  ImageView imageView = ImageView::New( nativeImage );
+  imageView.SetProperty( ImageView::Property::IMAGE, map );
+  Stage::GetCurrent().Add( imageView );
+
+  imageView.SetProperty( ImageView::Property::IMAGE, map );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.EnableTextureCallTrace( true );
+
+  std::vector< GLuint > ids;
+  ids.push_back( 23 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream params;
+  params << GL_TEXTURE_2D << ", " << 23;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) );
+
+  END_TEST;
+}
+
+// Scenarios 6: ImageView initially from regular image with custom shader but then SetImage called with Native
+int UtcDaliImageViewSetImageBufferImageWithCustomShaderToNativeImage(void)
+{
+  ToolkitTestApplication application;
+
+  int width = 300;
+  int height = 400;
+
+  Property::Map customShader;
+  customShader.Insert( "vertexShader", VERTEX_SHADER );
+  customShader.Insert( "fragmentShader", FRAGMENT_SHADER );
+
+  Property::Array shaderHints;
+  shaderHints.PushBack( "requiresSelfDepthTest" );
+  shaderHints.PushBack( "outputIsTransparent" );
+  shaderHints.PushBack( "outputIsOpaque" );
+  shaderHints.PushBack( "modifiesGeometry" );
+
+  customShader.Insert( "hints", shaderHints );
+
+  Property::Map map;
+  map.Insert( "rendererType", "imageRenderer" );
+  map.Insert( "shader", customShader );
+
+  BufferImage image = CreateBufferImage( width, height, Color::WHITE );
+
+  ImageView imageView = ImageView::New( image );
+  imageView.SetProperty( ImageView::Property::IMAGE, map );
+  Stage::GetCurrent().Add( imageView );
+
+  imageView.SetProperty( ImageView::Property::IMAGE, map );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.EnableTextureCallTrace( true );
+
+  std::vector< GLuint > ids;
+  ids.push_back( 23 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream params;
+  params << GL_TEXTURE_2D << ", " << 23;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) );
+
+  TestNativeImagePointer nativeImageInterface = TestNativeImage::New( width, height );
+  NativeImage nativeImage = NativeImage::New( *(nativeImageInterface.Get()) );
+  imageView.SetImage( nativeImage );
+
+  ids.clear();
+  ids.push_back( 24 );
+  application.GetGlAbstraction().SetNextTextureIds( ids );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") );
+
+  std::stringstream nativeImageParams;
+  nativeImageParams << GL_TEXTURE_2D << ", " << 24;
+  DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", nativeImageParams.str()) );
+
+
+  END_TEST;
+}
index 7862d53..b9fcec9 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL HEADER
 #include <cstring> // for strncasecmp
 #include <dali/public-api/images/resource-image.h>
 // EXTERNAL HEADER
 #include <cstring> // for strncasecmp
 #include <dali/public-api/images/resource-image.h>
+#include <dali/public-api/images/native-image.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL HEADER
 #include <dali/integration-api/debug.h>
 
 // INTERNAL HEADER
@@ -79,6 +80,8 @@ const std::string ALPHA_BLENDING_UNIFORM_NAME = "uAlphaBlending";
 
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
 
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
+const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
+
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform mediump mat4 uMvpMatrix;\n
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform mediump mat4 uMvpMatrix;\n
@@ -110,6 +113,7 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
   }\n
 );
 
+
 Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices )
 {
   Property::Map vertexFormat;
 Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices )
 {
   Property::Map vertexFormat;
@@ -207,7 +211,9 @@ ImageRenderer::ImageRenderer( RendererFactoryCache& factoryCache, ImageAtlasMana
   mDesiredSize(),
   mFittingMode( FittingMode::DEFAULT ),
   mSamplingMode( SamplingMode::DEFAULT ),
   mDesiredSize(),
   mFittingMode( FittingMode::DEFAULT ),
   mSamplingMode( SamplingMode::DEFAULT ),
-  mIsAlphaPreMultiplied( false )
+  mIsAlphaPreMultiplied( false ),
+  mNativeFragmentShaderCode( ),
+  mNativeImageFlag( false )
 {
 }
 
 {
 }
 
@@ -336,6 +342,13 @@ void ImageRenderer::DoInitialize( Actor& actor, const Property::Map& propertyMap
     }
   }
 
     }
   }
 
+  NativeImage nativeImage = NativeImage::DownCast( mImage );
+
+  if( nativeImage )
+  {
+    SetNativeFragmentShaderCode( nativeImage );
+  }
+
   // if actor is on stage, create new renderer and apply to actor
   if( actor && actor.OnStage() )
   {
   // if actor is on stage, create new renderer and apply to actor
   if( actor && actor.OnStage() )
   {
@@ -387,9 +400,17 @@ Renderer ImageRenderer::CreateRenderer() const
   Geometry geometry;
   Shader shader;
 
   Geometry geometry;
   Shader shader;
 
+  // If mImage is nativeImage with custom sampler or prefix, mNativeFragmentShaderCode will be applied.
+  // Renderer can't be shared between NativeImage and other image types.
+  if( !mNativeFragmentShaderCode.empty() )
+  {
+    return CreateNativeImageRenderer();
+  }
+
   if( !mImpl->mCustomShader )
   {
     geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
   if( !mImpl->mCustomShader )
   {
     geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
+
     shader = GetImageShader(mFactoryCache);
   }
   else
     shader = GetImageShader(mFactoryCache);
   }
   else
@@ -417,6 +438,45 @@ Renderer ImageRenderer::CreateRenderer() const
   return Renderer::New( geometry, material );
 }
 
   return Renderer::New( geometry, material );
 }
 
+Renderer ImageRenderer::CreateNativeImageRenderer() const
+{
+  Geometry geometry;
+  Shader shader;
+
+  if( !mImpl->mCustomShader )
+  {
+    geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
+
+    shader  = Shader::New( VERTEX_SHADER, mNativeFragmentShaderCode );
+    shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT );
+    shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+    shader.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 1.f );
+  }
+  else
+  {
+    geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize );
+    if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() )
+    {
+      shader  = Shader::New( VERTEX_SHADER, mNativeFragmentShaderCode );
+    }
+    else
+    {
+      shader  = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader,
+                             mNativeFragmentShaderCode,
+                             mImpl->mCustomShader->mHints );
+      if( mImpl->mCustomShader->mVertexShader.empty() )
+      {
+        shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT );
+        shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+        shader.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 1.f );
+      }
+    }
+  }
+
+  Material material = Material::New( shader );
+  return Renderer::New( geometry, material );
+}
+
 void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
 {
   if( imageUrl.empty() )
 void ImageRenderer::InitializeRenderer( const std::string& imageUrl )
 {
   if( imageUrl.empty() )
@@ -669,11 +729,35 @@ void ImageRenderer::SetImage( Actor& actor, const Image& image )
 {
   if( mImage != image )
   {
 {
   if( mImage != image )
   {
+    NativeImage newNativeImage = NativeImage::DownCast( image );
+    bool newRendererFlag = true;
+
+    if( newNativeImage && !mNativeImageFlag )
+    {
+      SetNativeFragmentShaderCode( newNativeImage );
+    }
+
+    if( ( newNativeImage && mNativeImageFlag ) || ( !newNativeImage && !mNativeImageFlag ) )
+    {
+      newRendererFlag = false;
+    }
+
+    if( newNativeImage )
+    {
+      mNativeImageFlag = true;
+    }
+    else
+    {
+      mNativeFragmentShaderCode.clear();
+      mNativeImageFlag = false;
+    }
+
     mImage = image;
 
     if( mImpl->mRenderer )
     {
     mImage = image;
 
     if( mImpl->mRenderer )
     {
-      if( GetIsFromCache() ) // if renderer is from cache, remove the old one
+      // if renderer is from cache, remove the old one, and create new renderer
+      if( GetIsFromCache() )
       {
         //remove old renderer
         if( actor )
       {
         //remove old renderer
         if( actor )
@@ -693,6 +777,20 @@ void ImageRenderer::SetImage( Actor& actor, const Image& image )
           SetOnStage(actor);
         }
       }
           SetOnStage(actor);
         }
       }
+      // if input image is nativeImage and mImage is regular image or the reverse, remove the old one, and create new renderer
+      else if( newRendererFlag )
+      {
+        //remove old renderer
+        if( actor )
+        {
+          actor.RemoveRenderer( mImpl->mRenderer );
+        }
+
+        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
+        {
+          SetOnStage(actor);
+        }
+      }
       else // if renderer is not from cache, reuse the same renderer and only change the texture
       {
         ApplyImageToSampler( image );
       else // if renderer is not from cache, reuse the same renderer and only change the texture
       {
         ApplyImageToSampler( image );
@@ -787,6 +885,33 @@ void ImageRenderer::CleanCache(const std::string& url)
   }
 }
 
   }
 }
 
+void ImageRenderer::SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage )
+{
+  const char* fragmentPreFix = nativeImage.GetCustomFragmentPreFix();
+  const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename();
+
+  if( fragmentPreFix )
+  {
+    mNativeFragmentShaderCode = fragmentPreFix;
+    mNativeFragmentShaderCode += "\n";
+  }
+
+  if( mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty() )
+  {
+    mNativeFragmentShaderCode += mImpl->mCustomShader->mFragmentShader;
+  }
+  else
+  {
+    mNativeFragmentShaderCode += FRAGMENT_SHADER;
+  }
+
+  if( customSamplerTypename )
+  {
+    mNativeFragmentShaderCode.replace( mNativeFragmentShaderCode.find( DEFAULT_SAMPLER_TYPENAME ), strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename );
+  }
+
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 4b73fc6..b208b44 100644 (file)
@@ -30,6 +30,8 @@
 namespace Dali
 {
 
 namespace Dali
 {
 
+class NativeImage;
+
 namespace Toolkit
 {
 
 namespace Toolkit
 {
 
@@ -200,6 +202,13 @@ private:
   Renderer CreateRenderer() const;
 
   /**
   Renderer CreateRenderer() const;
 
   /**
+   * @brief Creates the Dali::Renderer for NativeImage with custom sampler type and prefix, initializing it
+   *
+   * @return Returns the created Dali::Renderer
+   */
+  Renderer CreateNativeImageRenderer() const;
+
+  /**
    * Callback function of image resource loading succeed
    * @param[in] image The Image content that we attempted to load from mImageUrl
    */
    * Callback function of image resource loading succeed
    * @param[in] image The Image content that we attempted to load from mImageUrl
    */
@@ -216,6 +225,11 @@ private:
    */
   void CleanCache(const std::string& url);
 
    */
   void CleanCache(const std::string& url);
 
+  /**
+   * Set shader code for nativeimage if it exists
+   */
+  void SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage );
+
 private:
   Image mImage;
   ImageAtlasManager& mAtlasManager;
 private:
   Image mImage;
   ImageAtlasManager& mAtlasManager;
@@ -226,6 +240,8 @@ private:
   Dali::SamplingMode::Type mSamplingMode;
   bool mIsAlphaPreMultiplied;
 
   Dali::SamplingMode::Type mSamplingMode;
   bool mIsAlphaPreMultiplied;
 
+  std::string mNativeFragmentShaderCode;
+  bool mNativeImageFlag;
 };
 
 } // namespace Internal
 };
 
 } // namespace Internal