Allow new texture to be created from native images 30/74230/8
authorFerran Sole <ferran.sole@samsung.com>
Mon, 13 Jun 2016 08:59:10 +0000 (09:59 +0100)
committerFerran Sole <ferran.sole@samsung.com>
Tue, 14 Jun 2016 13:51:33 +0000 (06:51 -0700)
* Added new constructor to Textures so they can be created from a native image

Change-Id: Id040668bbd37b864fa24935452cb786b4ad79f07

dali/devel-api/rendering/texture.cpp
dali/devel-api/rendering/texture.h
dali/internal/event/rendering/texture-impl.cpp
dali/internal/event/rendering/texture-impl.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-texture.cpp
dali/internal/render/renderers/render-texture.h

index dd33866..6959544 100644 (file)
@@ -31,6 +31,12 @@ Texture Texture::New( TextureType::Type type, Pixel::Format format, unsigned int
   return Texture( texture.Get() );
 }
 
+Texture Texture::New( NativeImageInterface& nativeImageInterface )
+{
+  Internal::NewTexturePtr texture = Internal::NewTexture::New( nativeImageInterface );
+  return Texture( texture.Get() );
+}
+
 Texture::Texture()
 {
 }
index 876dbce..072897a 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/images/native-image-interface.h>
 #include <dali/public-api/images/pixel.h>
 #include <dali/devel-api/images/pixel-data.h>
 
@@ -76,6 +77,15 @@ public:
   static Texture New( TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height );
 
   /**
+   * @brief Creates a new Texture object from a native image
+   * @param[in] nativeImageInterface A native image
+   * @return A handle to a newly allocated Texture
+   * @note It is not possible to upload data to textures created from a native image using Upload methods
+   * although there might be platform specific APIs to upload data to a native image.
+   */
+  static Texture New( NativeImageInterface& nativeImageInterface );
+
+  /**
    * @brief Default constructor, creates an empty handle
    */
   Texture();
index 5d3f4c5..1fe7657 100644 (file)
@@ -34,6 +34,12 @@ NewTexturePtr NewTexture::New(TextureType::Type type, Pixel::Format format, unsi
   return texture;
 }
 
+NewTexturePtr NewTexture::New( NativeImageInterface& nativeImageInterface )
+{
+  NewTexturePtr texture( new NewTexture( &nativeImageInterface ) );
+  texture->Initialize();
+  return texture;
+}
 
 Render::NewTexture* NewTexture::GetRenderObject() const
 {
@@ -43,6 +49,7 @@ Render::NewTexture* NewTexture::GetRenderObject() const
 NewTexture::NewTexture(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height )
 : mEventThreadServices( *Stage::GetCurrent() ),
   mRenderObject( NULL ),
+  mNativeImage(),
   mType( type ),
   mFormat( format ),
   mWidth( width ),
@@ -50,9 +57,28 @@ NewTexture::NewTexture(TextureType::Type type, Pixel::Format format, unsigned in
 {
 }
 
+NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface )
+: mEventThreadServices( *Stage::GetCurrent() ),
+  mRenderObject( NULL ),
+  mNativeImage( nativeImageInterface ),
+  mType( TextureType::TEXTURE_2D ),
+  mFormat( Pixel::RGB888 ),
+  mWidth( nativeImageInterface->GetWidth() ),
+  mHeight( nativeImageInterface->GetHeight() )
+{
+}
+
 void NewTexture::Initialize()
 {
-  mRenderObject = new Render::NewTexture( mType, mFormat, mWidth, mHeight );
+  if( mNativeImage )
+  {
+    mRenderObject = new Render::NewTexture( mNativeImage );
+  }
+  else
+  {
+    mRenderObject = new Render::NewTexture( mType, mFormat, mWidth, mHeight );
+  }
+
   AddTexture( mEventThreadServices.GetUpdateManager(), *mRenderObject );
 }
 
@@ -66,7 +92,12 @@ NewTexture::~NewTexture()
 
 bool NewTexture::CheckUploadParametres( const Vector<unsigned char>& buffer, const UploadParams& parameters ) const
 {
-  if(  buffer.Size() < GetBytesPerPixel( mFormat ) * parameters.width * parameters.height )
+  if( mNativeImage )
+  {
+    DALI_LOG_ERROR( "Error: Uploading data to a native texture");
+    return false;
+  }
+  else if(  buffer.Size() < GetBytesPerPixel( mFormat ) * parameters.width * parameters.height )
   {
     DALI_LOG_ERROR( "Error: Buffer of an incorrect size when trying to update texture");
     return false;
index 5e56c53..852e952 100644 (file)
@@ -67,6 +67,13 @@ public:
   static NewTexturePtr New(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height);
 
   /**
+   * @brief Creates a new Texture from a native image
+   * @param[in] nativeImageInterface The native image
+   * @return A smart-pointer to the newly allocated Texture.
+   */
+  static NewTexturePtr New( NativeImageInterface& nativeImageInterface );
+
+  /**
    * @brief Get the texture render object
    *
    * @return the texture render object
@@ -106,10 +113,20 @@ private: // implementation
 
   /**
    * Constructor
+   * @param[in] type The type of the texture
+   * @param[in] format The format of the pixel data
+   * @param[in] width The width of the texture
+   * @param[in] height The height of the texture
    */
   NewTexture(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height );
 
   /**
+   * Constructor from native image
+   * @param[in] nativeImageInterface The native image
+   */
+  NewTexture( NativeImageInterfacePtr nativeImageInterface );
+
+  /**
    * Second stage initialization of the Texture
    */
   void Initialize();
@@ -137,6 +154,7 @@ private: // data
   Internal::EventThreadServices& mEventThreadServices;    ///<Used to send messages to the render thread via update thread
   Internal::Render::NewTexture* mRenderObject;            ///<The Render::Texture associated to this texture
 
+  NativeImageInterfacePtr mNativeImage; ///< Pointer to native image
   Dali::TextureType::Type mType;      ///< Texture type (cached)
   Pixel::Format mFormat;              ///< Pixel format
   unsigned int mWidth;                ///< Width of the texture
index ab65304..9e83849 100644 (file)
@@ -362,48 +362,44 @@ bool Renderer::BindTextures( Context& context, SceneGraph::TextureCache& texture
   std::vector<Render::Sampler*>& samplers( mRenderDataProvider->GetSamplers() );
 
   std::vector<Render::Texture>& textures( mRenderDataProvider->GetTextures() );
+  GLint uniformLocation(-1);
   for( size_t i(0); result && i<textures.size(); ++i )
   {
     ResourceId textureId = textures[i].GetTextureId();
     Internal::Texture* texture = textureCache.GetTexture( textureId );
     if( texture )
     {
-      result = textureCache.BindTexture( texture, textureId, GL_TEXTURE_2D, (TextureUnit)textureUnit );
+      result = program.GetSamplerUniformLocation( i, uniformLocation ) &&
+               textureCache.BindTexture( texture, textureId, GL_TEXTURE_2D, (TextureUnit)textureUnit );
 
-      if( result )
+      if( result && Program::UNIFORM_UNKNOWN != uniformLocation )
       {
-        GLint uniformLocation;
+        program.SetUniform1i( uniformLocation, textureUnit );
 
-        bool result = program.GetSamplerUniformLocation( i, uniformLocation );
-        if( result && Program::UNIFORM_UNKNOWN != uniformLocation )
+        unsigned int samplerBitfield(ImageSampler::DEFAULT_BITFIELD);
+        const Render::Sampler* sampler(  samplers[i] );
+        if( sampler )
         {
-          program.SetUniform1i( uniformLocation, textureUnit );
-
-          unsigned int samplerBitfield(ImageSampler::DEFAULT_BITFIELD);
-          const Render::Sampler* sampler(  samplers[i] );
-          if( sampler )
-          {
-            samplerBitfield = sampler->mBitfield;
-          }
+          samplerBitfield = sampler->mBitfield;
+        }
 
-          texture->ApplySampler( (TextureUnit)textureUnit, samplerBitfield );
+        texture->ApplySampler( (TextureUnit)textureUnit, samplerBitfield );
 
-          ++textureUnit;
-        }
+        ++textureUnit;
       }
     }
   }
 
   std::vector<Render::NewTexture*>& newTextures( mRenderDataProvider->GetNewTextures() );
-  GLint uniformLocation(0);
   for( size_t i(0); result && i<newTextures.size(); ++i )
   {
     if( newTextures[i] )
     {
-      bool result = program.GetSamplerUniformLocation( i, uniformLocation );
+      result = program.GetSamplerUniformLocation( i, uniformLocation ) &&
+               newTextures[i]->Bind(context, textureUnit, samplers[i] );
+
       if( result )
       {
-        newTextures[i]->Bind(context, textureUnit, samplers[i] );
         program.SetUniform1i( uniformLocation, textureUnit );
         ++textureUnit;
       }
index 1fd3d78..3c87296 100644 (file)
@@ -518,16 +518,30 @@ void PixelFormatToGl( Pixel::Format pixelformat, unsigned& pixelDataType, unsign
 NewTexture::NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height )
 :mId( 0 ),
  mType( type ),
+ mSampler(),
+ mNativeImage(),
  mInternalFormat(GL_RGB),
  mPixelDataType(GL_UNSIGNED_BYTE),
  mWidth( width ),
  mHeight( height ),
- mSampler(),
  mHasAlpha( HasAlpha( format ) )
 {
   PixelFormatToGl( format, mPixelDataType, mInternalFormat );
 }
 
+NewTexture::NewTexture( NativeImageInterfacePtr nativeImageInterface )
+:mId( 0 ),
+ mType( TextureType::TEXTURE_2D ),
+ mSampler(),
+ mNativeImage( nativeImageInterface ),
+ mInternalFormat(GL_RGB),
+ mPixelDataType(GL_UNSIGNED_BYTE),
+ mWidth( nativeImageInterface->GetWidth() ),
+ mHeight( nativeImageInterface->GetHeight() ),
+ mHasAlpha( nativeImageInterface->RequiresBlending() )
+{
+}
+
 NewTexture::~NewTexture()
 {}
 
@@ -541,41 +555,63 @@ void NewTexture::Destroy( Context& context )
 
 void NewTexture::Initialize(Context& context)
 {
-  context.GenTextures( 1, &mId );
-
-  if( mType == TextureType::TEXTURE_2D )
+  if( mNativeImage )
   {
-    //Creates the texture and reserves memory for the first mipmap level.
-    context.Bind2dTexture( mId );
-    context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
+    if( mNativeImage->GlExtensionCreate() )
+    {
+      context.GenTextures( 1, &mId );
+      context.Bind2dTexture( mId );
+      context.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
 
-    //Apply default sampling parameters
-    context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
+      //Apply default sampling parameters
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
 
+      // platform specific implementation decides on what GL extension to use
+      mNativeImage->TargetTexture();
+    }
   }
-  else if( mType == TextureType::TEXTURE_CUBE )
+  else
   {
-    //Creates the texture and reserves memory for the first mipmap level.
-    context.BindCubeMapTexture( mId );
-    for( unsigned int i(0); i<6; ++i )
+    context.GenTextures( 1, &mId );
+
+    if( mType == TextureType::TEXTURE_2D )
     {
-      context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
+      //Creates the texture and reserves memory for the first mipmap level.
+      context.Bind2dTexture( mId );
+      context.TexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
+
+      //Apply default sampling parameters
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
     }
+    else if( mType == TextureType::TEXTURE_CUBE )
+    {
+      //Creates the texture and reserves memory for the first mipmap level.
+      context.BindCubeMapTexture( mId );
+      for( unsigned int i(0); i<6; ++i )
+      {
+        context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mInternalFormat, mWidth, mHeight, 0, mInternalFormat, mPixelDataType, 0 );
+      }
 
-    //Apply default sampling parameters
-    context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
-    context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
+      //Apply default sampling parameters
+      context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT );
+      context.TexParameteri( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT );
+    }
   }
 }
 
 void NewTexture::Upload( Context& context, Vector<unsigned char>& buffer, const Internal::NewTexture::UploadParams& params  )
 {
+  DALI_ASSERT_ALWAYS( mNativeImage == NULL );
+
   if( mType == TextureType::TEXTURE_2D )
   {
     context.Bind2dTexture( mId );
@@ -618,20 +654,27 @@ void NewTexture::Upload( Context& context, Vector<unsigned char>& buffer, const
   }
 }
 
-void NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
+bool NewTexture::Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler )
 {
-  context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
-
-  if( mType == TextureType::TEXTURE_2D )
-  {
-    context.Bind2dTexture( mId );
-  }
-  else if( mType == TextureType::TEXTURE_CUBE )
+  if( mId != 0 )
   {
-    context.BindCubeMapTexture( mId );
+    context.ActiveTexture( static_cast<TextureUnit>(textureUnit) );
+
+    if( mType == TextureType::TEXTURE_2D )
+    {
+      context.Bind2dTexture( mId );
+    }
+    else if( mType == TextureType::TEXTURE_CUBE )
+    {
+      context.BindCubeMapTexture( mId );
+    }
+
+    ApplySampler( context, sampler );
+
+    return true;
   }
 
-  ApplySampler( context, sampler );
+  return false;
 }
 
 void NewTexture::ApplySampler( Context& context, Render::Sampler* sampler )
index 8b02123..bdf9d2f 100644 (file)
@@ -109,12 +109,23 @@ class NewTexture
 public:
 
   typedef Dali::TextureType::Type Type;
+
   /**
    * Constructor
+   * @param[in] type The type of the texture
+   * @param[in] format The format of the pixel data
+   * @param[in] width The width of the texture
+   * @param[in] height The height of the texture
    */
   NewTexture( Type type, Pixel::Format format, unsigned int width, unsigned int height );
 
   /**
+   * Constructor from native image
+   * @param[in] nativeImageInterface The native image
+   */
+  NewTexture( NativeImageInterfacePtr nativeImageInterface );
+
+  /**
    * Destructor
    */
   ~NewTexture();
@@ -145,8 +156,9 @@ public:
    * @param[in] context The GL context
    * @param[in] textureUnit the texture unit
    * @param[in] sampler The sampler to be used with the texture
+   * @return true if the bind succeeded, false otherwise
    */
-  void Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler );
+  bool Bind( Context& context, unsigned int textureUnit, Render::Sampler* sampler );
 
   /**
    * Auto generates mipmaps for the texture
@@ -205,14 +217,14 @@ private:
    */
   void ApplySampler( Context& context, Render::Sampler* sampler );
 
-
   GLuint mId;                         ///<Id of the texture
   Type mType;                         ///<Type of the texture
+  Render::Sampler mSampler;           ///<The current sampler state
+  NativeImageInterfacePtr mNativeImage; ///<Pointer to native image
   GLenum mInternalFormat;             ///<The format of the pixel data
   GLenum mPixelDataType;              ///<The data type of the pixel data
   unsigned int mWidth;                ///<Widht of the texture
   unsigned int mHeight;               ///<Height of the texture
-  Render::Sampler mSampler;           ///<The current sampler state
   bool mHasAlpha : 1;                 ///<Whether the format has an alpha channel
 };