Added missing newline chars to logging commands
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / bitmap-texture.cpp
index d3d11cb..58d80c2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
 // CLASS HEADER
 #include <dali/internal/render/gl-resources/bitmap-texture.h>
 
+// EXTERNAL INCLUDES
+#include <cstring>
+
 // INTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/images/buffer-image.h> // For PixelBuffer
 #include <dali/integration-api/debug.h>
-#include <dali/internal/render/common/vertex.h>
 #include <dali/internal/render/common/performance-monitor.h>
 #include <dali/internal/render/gl-resources/context.h>
 #include <dali/internal/render/gl-resources/texture-units.h>
 
+
 namespace Dali
 {
 
@@ -40,11 +45,11 @@ BitmapTexture::BitmapTexture(
            bitmapPackedPixelsProfile->GetBufferWidth(),
            bitmapPackedPixelsProfile->GetBufferHeight(),
            bitmap->GetImageWidth(),
-           bitmap->GetImageHeight(),
-           bitmap->GetPixelFormat()),
+           bitmap->GetImageHeight()),
   mBitmap(bitmap),
-  mClearPixels(false),
-  mDiscardPolicy(policy)
+  mPixelFormat(bitmap->GetPixelFormat()),
+  mDiscardPolicy(policy),
+  mClearPixels(false)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
   DALI_LOG_SET_OBJECT_STRING(this, DALI_LOG_GET_OBJECT_STRING(bitmap));
@@ -59,11 +64,11 @@ BitmapTexture::BitmapTexture(
   ResourcePolicy::Discardable policy)
 : Texture( context,
            width, height,
-           width, height,
-           pixelFormat),
+           width, height),
   mBitmap(NULL),
-  mClearPixels(clearPixels),
-  mDiscardPolicy(policy)
+  mPixelFormat( pixelFormat ),
+  mDiscardPolicy(policy),
+  mClearPixels(clearPixels)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
 }
@@ -76,62 +81,6 @@ BitmapTexture::~BitmapTexture()
   // on the render thread. (And avoiding a potentially problematic virtual call in the destructor)
 }
 
-void BitmapTexture::UploadBitmapArray( const BitmapUploadArray& bitmapArray )
-{
-  DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
-
-  if( mId == 0 )
-  {
-    CreateGlTexture();
-  }
-
-  mContext.ActiveTexture( TextureUnitAsGLenum( TEXTURE_UNIT_UPLOAD ) );  // bind in unused unit so rebind works the first time
-  mContext.Bind2dTexture(mId);
-  mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
-
-  GLenum pixelFormat   = GL_RGBA;
-  GLenum pixelDataType = GL_UNSIGNED_BYTE;
-
-  Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
-
-  // go through each bitmap uploading it
-
-  for( BitmapUploadArray::const_iterator iter =  bitmapArray.begin(), endIter = bitmapArray.end(); iter != endIter ; ++iter)
-  {
-    const BitmapUpload& bitmapItem((*iter));
-
-    DALI_ASSERT_ALWAYS(bitmapItem.mPixelData);
-
-    const unsigned char* pixels = bitmapItem.mPixelData;
-
-    DALI_ASSERT_DEBUG( (pixels!=NULL) && "bitmap has no data \n");
-
-    unsigned int bitmapWidth(bitmapItem.mWidth);
-    unsigned int bitmapHeight(bitmapItem.mHeight);
-
-    DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "upload bitmap to texture :%d y:%d w:%d h:%d\n",
-                            bitmapItem.mXpos,
-                            bitmapItem.mYpos,
-                            bitmapWidth,
-                            bitmapHeight);
-
-    mContext.TexSubImage2D(GL_TEXTURE_2D,
-                           0,                   /* mip map level */
-                           bitmapItem.mXpos,    /* X pos */
-                           bitmapItem.mYpos,    /* Y pos */
-                           bitmapWidth,         /* width */
-                           bitmapHeight,        /* height */
-                           pixelFormat,         /* our bitmap format (should match internal format) */
-                           pixelDataType,       /* pixel data type */
-                           pixels);             /* texture data */
-
-    if( BitmapUpload::DISCARD_PIXEL_DATA == bitmapItem.mDiscard)
-    {
-      delete [] bitmapItem.mPixelData;
-    }
-  }
-}
-
 bool BitmapTexture::HasAlphaChannel() const
 {
   return Pixel::HasAlpha(mPixelFormat);
@@ -159,7 +108,7 @@ void BitmapTexture::AreaUpdated( const RectArea& updateArea, const unsigned char
   GLenum pixelDataType = GL_UNSIGNED_BYTE;
   Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
 
-  mContext.ActiveTexture( TextureUnitAsGLenum( TEXTURE_UNIT_UPLOAD ) );  // bind in unused unit so rebind works the first time
+  mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
 
   mContext.Bind2dTexture(mId);
 
@@ -169,9 +118,8 @@ void BitmapTexture::AreaUpdated( const RectArea& updateArea, const unsigned char
     DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "Update x:%d y:%d w:%d h:%d\n",
                    updateArea.x, updateArea.y, updateArea.width ,updateArea.height );
 
-    // TODO: obtain pitch of source image, obtain pixel depth of source image.
-    const unsigned int pitchPixels = mImageWidth;
-    const unsigned int pixelDepth = sizeof(unsigned int);
+    const unsigned int pitchPixels = mWidth;
+    const unsigned int pixelDepth = Dali::Pixel::GetBytesPerPixel( mPixelFormat );
 
     // If the width of the source update area is the same as the pitch, then can
     // copy the contents in a single contiguous TexSubImage call.
@@ -203,7 +151,6 @@ void BitmapTexture::AreaUpdated( const RectArea& updateArea, const unsigned char
   }
 }
 
-
 void BitmapTexture::AssignBitmap( bool generateTexture, const unsigned char* pixels )
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
@@ -218,7 +165,7 @@ void BitmapTexture::AssignBitmap( bool generateTexture, const unsigned char* pix
   }
   DALI_ASSERT_DEBUG( mId != 0 );
 
-  mContext.ActiveTexture( TextureUnitAsGLenum( TEXTURE_UNIT_UPLOAD ) ); // bind in unused unit so rebind works the first time
+  mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
   mContext.Bind2dTexture(mId);
   Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
 
@@ -227,7 +174,13 @@ void BitmapTexture::AssignBitmap( bool generateTexture, const unsigned char* pix
   mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-  INCREASE_BY( PerformanceMonitor::TEXTURE_DATA_UPLOADED, GetBytesPerPixel(mPixelFormat) * mWidth * mHeight );
+  // If the resource policy is to discard on upload then release buffer
+  DiscardBitmapBuffer();
+
+  if( pixels != NULL )
+  {
+    INCREASE_BY( PerformanceMonitor::TEXTURE_DATA_UPLOADED, GetBytesPerPixel(mPixelFormat) * mWidth * mHeight );
+  }
 }
 
 void BitmapTexture::Update( Integration::Bitmap* bitmap )
@@ -236,7 +189,7 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
   DALI_ASSERT_DEBUG( bitmap != 0 );
   if( !bitmap )
   {
-    DALI_LOG_ERROR( "Passed a null bitmap to update this bitmap texture." );
+    DALI_LOG_ERROR( "Passed a null bitmap to update this bitmap texture.\n" );
     return;
   }
 
@@ -246,7 +199,7 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
   if( !bitmapPackedPixels )
   {
     ///! This should never happen.
-    DALI_LOG_ERROR("Passed an incompatible bitmap type to update this bitmap texture.");
+    DALI_LOG_ERROR("Passed an incompatible bitmap type to update this bitmap texture.\n");
     return;
   }
   mBitmap = bitmap;
@@ -286,6 +239,88 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
   }
 }
 
+void BitmapTexture::Update( Integration::Bitmap* srcBitmap, std::size_t xOffset, std::size_t yOffset )
+{
+  if( NULL != srcBitmap )
+  {
+    Update( srcBitmap->GetBuffer(), srcBitmap->GetImageWidth(), srcBitmap->GetImageHeight(),
+            srcBitmap->GetPixelFormat(), xOffset, yOffset);
+  }
+}
+
+void BitmapTexture::Update( PixelData* srcPixelData, std::size_t xOffset, std::size_t yOffset )
+{
+  if( NULL != srcPixelData )
+  {
+    Update( srcPixelData->GetBuffer(), srcPixelData->GetWidth(), srcPixelData->GetHeight(),
+            srcPixelData->GetPixelFormat(), xOffset, yOffset);
+  }
+}
+
+void BitmapTexture::Update( const unsigned char* pixels, std::size_t width, std::size_t height, Pixel::Format pixelFormat, std::size_t xOffset, std::size_t yOffset )
+{
+
+  GLenum pixelGLFormat = GL_RGBA;
+  GLenum pixelDataType = GL_UNSIGNED_BYTE;
+  Integration::ConvertToGlFormat( mPixelFormat, pixelDataType, pixelGLFormat );
+
+  if( !mId )
+  {
+    mContext.GenTextures( 1, &mId );
+
+    mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
+    mContext.Bind2dTexture( mId );
+    mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+    mContext.TexImage2D( GL_TEXTURE_2D, 0, pixelGLFormat, mWidth, mHeight, 0, pixelGLFormat, pixelDataType, NULL );
+    mContext.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+    mContext.TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+  }
+  else
+  {
+    mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
+    mContext.Bind2dTexture( mId );
+    mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+  }
+
+#if DALI_GLES_VERSION >= 30
+  // For GLES 3.0, uploading sub-image with different format is a valid operation.
+  Integration::ConvertToGlFormat( pixelFormat, pixelDataType, pixelGLFormat );
+#else
+  // Allows RGB888 source bitmap to be added to RGBA8888 texture, need to convert the bitmap format manually.
+  if(pixelFormat == Pixel::RGB888 && mPixelFormat == Pixel::RGBA8888 )
+  {
+    std::size_t size = width * height;
+
+    Vector<PixelBuffer> tempBuffer;
+    tempBuffer.Reserve( size*4u );
+    PixelBuffer* data = tempBuffer.Begin();
+
+    for( std::size_t i=0u; i<size; i++ )
+    {
+      data[i*4u] = pixels[i*3u];
+      data[i*4u+1] = pixels[i*3u+1];
+      data[i*4u+2] = pixels[i*3u+2];
+      data[i*4u+3] = 0xFF;
+    }
+
+    mContext.TexSubImage2D( GL_TEXTURE_2D, 0,
+                            xOffset, yOffset,
+                            width, height,
+                            pixelGLFormat, pixelDataType,
+                            data );
+
+    return;
+  }
+#endif
+
+  mContext.TexSubImage2D( GL_TEXTURE_2D, 0,
+                          xOffset, yOffset,
+                          width, height,
+                          pixelGLFormat, pixelDataType,
+                          pixels );
+}
+
 void BitmapTexture::UpdateArea( const RectArea& updateArea )
 {
   DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::General, "BitmapTexture::UpdateArea()\n");
@@ -318,53 +353,6 @@ void BitmapTexture::UpdateArea( const RectArea& updateArea )
   }
 }
 
-void BitmapTexture::ClearAreas( const BitmapClearArray& areaArray, std::size_t blockSize, uint32_t color )
-{
-  if(mId > 0)
-  {
-    DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
-    DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::Verbose, "BitmapTexture::AreaUpdated()\n");
-
-    GLenum pixelFormat   = GL_RGBA;
-    GLenum pixelDataType = GL_UNSIGNED_BYTE;
-    Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
-
-    mContext.ActiveTexture( TextureUnitAsGLenum( TEXTURE_UNIT_UPLOAD ) );  // bind in unused unit so rebind works the first time
-    mContext.Bind2dTexture(mId);
-
-    size_t numPixels = blockSize*blockSize;
-    size_t bytesPerPixel = Pixel::GetBytesPerPixel(mPixelFormat);
-    char* clearPixels = (char*)malloc(numPixels * bytesPerPixel);
-
-    for(size_t i=0; i<numPixels; i++)
-    {
-      memcpy(&clearPixels[i*bytesPerPixel], &color, bytesPerPixel);
-    }
-
-    for( BitmapClearArray::const_iterator iter =  areaArray.begin(), endIter = areaArray.end(); iter != endIter ; ++iter)
-    {
-      const Vector2& clearPos((*iter));
-
-      mContext.PixelStorei( GL_UNPACK_ALIGNMENT, 1 ); // We always use tightly packed data
-      DALI_LOG_INFO( Debug::Filter::gImage, Debug::General, "Update x:%0.2f y:%0.2f w:%d h:%d\n",
-                     clearPos.x, clearPos.y, blockSize, blockSize );
-
-      mContext.TexSubImage2D(GL_TEXTURE_2D,
-                             0,
-                             clearPos.x,
-                             clearPos.y,
-                             blockSize,
-                             blockSize,
-                             pixelFormat,         /* our bitmap format (should match internal format) */
-                             pixelDataType,       /* pixel data type */
-                             clearPixels);        /* texture data */
-
-      INCREASE_BY( PerformanceMonitor::TEXTURE_DATA_UPLOADED, numPixels * bytesPerPixel );
-    }
-    free(clearPixels);
-  }
-}
-
 bool BitmapTexture::UpdateOnCreate()
 {
   return true;
@@ -393,11 +381,11 @@ bool BitmapTexture::CreateGlTexture()
   else
   {
     const unsigned char* pixels = NULL;
-    std::vector<unsigned char> pixelData;
-    if( ( NULL == pixels ) && ( true == mClearPixels ) )
+    Dali::Vector<unsigned char> pixelData; // Okay to create outside branch as empty vector has no heap allocation.
+    if( true == mClearPixels )
     {
-      unsigned int size = mWidth * mHeight * Pixel::GetBytesPerPixel(mPixelFormat);
-      pixelData.resize(size, 0);
+      unsigned int size = mWidth * mHeight * Pixel::GetBytesPerPixel( mPixelFormat );
+      pixelData.Resize( size, 0 );
       pixels = &pixelData[0];
     }
     AssignBitmap( true, pixels );
@@ -435,12 +423,15 @@ unsigned int BitmapTexture::GetHeight() const
 
 void BitmapTexture::DiscardBitmapBuffer()
 {
-  DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "BitmapTexture::DiscardBitmapBuffer() DiscardPolicy: %s\n", mDiscardPolicy == ResourcePolicy::DISCARD?"DISCARD":"RETAIN");
+  DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "BitmapTexture::DiscardBitmapBuffer() DiscardPolicy: %s\n", mDiscardPolicy == ResourcePolicy::OWNED_DISCARD?"DISCARD":"RETAIN");
 
-  if( ResourcePolicy::DISCARD == mDiscardPolicy )
+  if( ResourcePolicy::OWNED_DISCARD == mDiscardPolicy )
   {
     DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "  Discarding bitmap\n");
-    mBitmap->DiscardBuffer();
+    if ( mBitmap )
+    {
+      mBitmap->DiscardBuffer();
+    }
   }
 }