Added missing newline chars to logging commands
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / bitmap-texture.cpp
index 02759e1..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);
 }
@@ -113,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.
@@ -147,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);
@@ -171,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 )
@@ -180,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;
   }
 
@@ -190,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;
@@ -230,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");
@@ -290,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 );
@@ -332,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();
+    }
   }
 }