Merge "Removed bogus consts and fixed out-of-line definitions." into tizen
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / bitmap-texture.cpp
index 8b2b013..e6967ce 100644 (file)
 // CLASS HEADER
 #include <dali/internal/render/gl-resources/bitmap-texture.h>
 
-// EXTERNAL INCLUDES
-#include <math.h>
-#include <memory.h>
-
 // INTERNAL INCLUDES
-#include <dali/public-api/math/rect.h>
-#include <dali/public-api/math/math-utils.h>
 #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
 {
@@ -36,32 +31,39 @@ namespace Dali
 namespace Internal
 {
 
-BitmapTexture::BitmapTexture(Integration::Bitmap* const bitmap, const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile, Context& context)
-: Texture(context,
-          bitmapPackedPixelsProfile->GetBufferWidth(),
-          bitmapPackedPixelsProfile->GetBufferHeight(),
-          bitmap->GetImageWidth(),
-          bitmap->GetImageHeight(),
-          bitmap->GetPixelFormat()),
+BitmapTexture::BitmapTexture(
+  Integration::Bitmap* const bitmap,
+  const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile,
+  Context& context,
+  ResourcePolicy::Discardable policy)
+: Texture( context,
+           bitmapPackedPixelsProfile->GetBufferWidth(),
+           bitmapPackedPixelsProfile->GetBufferHeight(),
+           bitmap->GetImageWidth(),
+           bitmap->GetImageHeight(),
+           bitmap->GetPixelFormat()),
   mBitmap(bitmap),
-  mClearPixels(false)
+  mClearPixels(false),
+  mDiscardPolicy(policy)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
   DALI_LOG_SET_OBJECT_STRING(this, DALI_LOG_GET_OBJECT_STRING(bitmap));
 }
 
 BitmapTexture::BitmapTexture(
-  unsigned int  width,
-  unsigned int  height,
+  unsigned int width,
+  unsigned int height,
   Pixel::Format pixelFormat,
-  bool          clearPixels,
-  Context&      context)
-: Texture(context,
-          width, height,
-          width, height,
-          pixelFormat),
+  bool clearPixels,
+  Context& context,
+  ResourcePolicy::Discardable policy)
+: Texture( context,
+           width, height,
+           width, height,
+           pixelFormat),
   mBitmap(NULL),
-  mClearPixels(clearPixels)
+  mClearPixels(clearPixels),
+  mDiscardPolicy(policy)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
 }
@@ -69,18 +71,21 @@ BitmapTexture::BitmapTexture(
 BitmapTexture::~BitmapTexture()
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
+
   // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed
   // 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(GL_TEXTURE7);  // bind in unused unit so rebind works the first time
+  mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
   mContext.Bind2dTexture(mId);
   mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
 
@@ -110,20 +115,20 @@ void BitmapTexture::UploadBitmapArray( const BitmapUploadArray& bitmapArray )
                             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;
-     }
+    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;
+    }
   }
 }
 
@@ -154,7 +159,7 @@ void BitmapTexture::AreaUpdated( const RectArea& updateArea, const unsigned char
   GLenum pixelDataType = GL_UNSIGNED_BYTE;
   Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
 
-  mContext.ActiveTexture(GL_TEXTURE7);  // bind in unused unit so rebind works the first time
+  mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
 
   mContext.Bind2dTexture(mId);
 
@@ -213,14 +218,12 @@ void BitmapTexture::AssignBitmap( bool generateTexture, const unsigned char* pix
   }
   DALI_ASSERT_DEBUG( mId != 0 );
 
-  mContext.ActiveTexture(GL_TEXTURE7); // bind in unused unit so rebind works the first time
+  mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
   mContext.Bind2dTexture(mId);
   Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
 
   mContext.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
   mContext.TexImage2D(GL_TEXTURE_2D, 0, pixelFormat, mWidth, mHeight, 0, pixelFormat, pixelDataType, pixels);
-  mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  mContext.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   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);
 
@@ -250,14 +253,15 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
 
   const unsigned char* pixels = mBitmap->GetBuffer();
 
+  // We should never have null pixel data here - resource manager has deliberately loaded/reloaded data
+
   DALI_ASSERT_DEBUG( pixels != NULL );
 
-  if ( NULL == pixels )
+  if( NULL == pixels )
   {
-    DALI_LOG_ERROR("bitmap has no data\n");
-    GlCleanup(); // Note, We suicide here in the case of bad input.
+    DALI_LOG_ERROR("BitmapTexture::Upload() - Bitmap has no pixel data.\n");
   }
-  else
+  else if( mId != 0 )
   {
     if( mImageWidth == mBitmap->GetImageWidth() &&
         mImageHeight == mBitmap->GetImageHeight() &&
@@ -265,26 +269,19 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
         mHeight == bitmapPackedPixels->GetBufferHeight() &&
         mPixelFormat == mBitmap->GetPixelFormat() ) // and size hasn't changed
     {
-      if ( mId ) // If the texture is already bound
-      {
-        RectArea area(0, 0, mImageWidth, mImageHeight);  // just update whole texture
-        AreaUpdated( area, pixels );
-        mBitmap->DiscardBuffer();
-      }
+      RectArea area(0, 0, mImageWidth, mImageHeight);  // just update whole texture
+      AreaUpdated( area, pixels );
+      DiscardBitmapBuffer();
     }
-    else
-    {                                           // Otherwise, reload the pixel data
+    else // Otherwise, reload the pixel data
+    {
       mImageWidth  = mBitmap->GetImageWidth();
       mImageHeight = mBitmap->GetImageHeight();
       mWidth       = bitmapPackedPixels->GetBufferWidth();
       mHeight      = bitmapPackedPixels->GetBufferHeight();
       mPixelFormat = mBitmap->GetPixelFormat();
 
-      if ( mId ) // If the texture is already bound
-      {
-        AssignBitmap( false, pixels );
-        mBitmap->DiscardBuffer();
-      }
+      AssignBitmap( false, pixels );
     }
   }
 }
@@ -296,14 +293,12 @@ void BitmapTexture::UpdateArea( const RectArea& updateArea )
   if( mBitmap != 0 )
   {
     const unsigned char* pixels = mBitmap->GetBuffer();
-    if ( NULL == pixels )
-    {
-      DALI_LOG_ERROR("bitmap has no data\n");
-      GlCleanup(); ///!ToDo: Why do we suicide in the case of bad input?
-    }
-    else
+
+    // Pixel data could be null if we've uploaded to GL and discarded the data.
+
+    if( NULL != pixels )
     {
-      if ( mId ) // If the texture is already bound
+      if( mId ) // If the texture is already bound
       {
         if( updateArea.IsEmpty() )
         {
@@ -334,7 +329,7 @@ void BitmapTexture::ClearAreas( const BitmapClearArray& areaArray, std::size_t b
     GLenum pixelDataType = GL_UNSIGNED_BYTE;
     Integration::ConvertToGlFormat(mPixelFormat, pixelDataType, pixelFormat);
 
-    mContext.ActiveTexture(GL_TEXTURE7);  // bind in unused unit so rebind works the first time
+    mContext.ActiveTexture( TEXTURE_UNIT_UPLOAD );
     mContext.Bind2dTexture(mId);
 
     size_t numPixels = blockSize*blockSize;
@@ -378,18 +373,21 @@ bool BitmapTexture::UpdateOnCreate()
 bool BitmapTexture::CreateGlTexture()
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
-  DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Bitmap: %s\n", DALI_LOG_GET_OBJECT_C_STR(this));
+  DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "BitmapTexture::CreateGlTexture() Bitmap: %s\n", DALI_LOG_GET_OBJECT_C_STR(this));
 
   if( mBitmap )
   {
     const unsigned char* pixels = mBitmap->GetBuffer();
 
-    DALI_ASSERT_DEBUG(pixels != NULL);
+    // pixel data could be NULL here if we've had a context loss and we previously discarded
+    // the pixel data on the previous upload. If it is null, then we shouldn't generate a
+    // new GL Texture; leaving mId as zero. Eventually, the bitmap will get reloaded,
+    // and pixels will become non-null.
 
     if( NULL != pixels )
     {
       AssignBitmap( true, pixels );
-      mBitmap->DiscardBuffer();
+      DiscardBitmapBuffer();
     }
   }
   else
@@ -435,6 +433,18 @@ unsigned int BitmapTexture::GetHeight() const
   return height;
 }
 
+void BitmapTexture::DiscardBitmapBuffer()
+{
+  DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "BitmapTexture::DiscardBitmapBuffer() DiscardPolicy: %s\n", mDiscardPolicy == ResourcePolicy::DISCARD?"DISCARD":"RETAIN");
+
+  if( ResourcePolicy::DISCARD == mDiscardPolicy )
+  {
+    DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "  Discarding bitmap\n");
+    mBitmap->DiscardBuffer();
+  }
+}
+
+
 } //namespace Internal
 
 } //namespace Dali