Create glyph bitmap without copy if single color 67/275967/5
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 7 Jun 2022 13:22:38 +0000 (22:22 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 8 Jun 2022 06:27:25 +0000 (15:27 +0900)
Make we don't use memcpy when we get simple glyph bitmap
who rendered by FreeType library.
Just copy the pointer, and deallocate our own.
+
allocate all glyph's data.buffer as malloc instead of new.
Because FreeType Bitmap memory allocated by malloc system.
We must be release them as free, not delete[].

Change-Id: Ic13cfe22e894d8ed8caa1e837bfb02fa4c846083
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-adaptor-internal/utc-Dali-FontClient.cpp
dali/internal/text/text-abstraction/cairo-renderer.cpp
dali/internal/text/text-abstraction/plugin/embedded-item.cpp
dali/internal/text/text-abstraction/plugin/font-client-plugin-impl.cpp
dali/internal/text/text-abstraction/plugin/font-client-utils.cpp
dali/internal/text/text-abstraction/plugin/font-client-utils.h
dali/internal/text/text-abstraction/plugin/font-face-cache-item.cpp

index 208deb1..006f04d 100644 (file)
@@ -173,6 +173,11 @@ int UtcDaliFontClientAtlasLimitationEnabled(void)
   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData2000.width, TEST_LOCATION);
   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData2000.height, TEST_LOCATION);
 
+  // Release copied memories
+  free(glyphBufferData200.buffer);
+  free(glyphBufferData1000.buffer);
+  free(glyphBufferData2000.buffer);
+
   END_TEST;
 }
 
index dd11c76..4bccb0b 100644 (file)
@@ -854,7 +854,7 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
 
           // Retrieve the image
           TextAbstraction::FontClient::GlyphBufferData data;
-          std::unique_ptr<GlyphBuffer>                 glyphBufferPtr(new GlyphBuffer(data, GlyphBuffer::DELETE));
+          std::unique_ptr<GlyphBuffer>                 glyphBufferPtr(new GlyphBuffer(data, GlyphBuffer::FREE));
           if(isEmoji)
           {
             data.width  = parameters.glyphs[run.glyphIndex].width;
@@ -904,11 +904,10 @@ Devel::PixelBuffer RenderTextCairo(const TextAbstraction::TextRenderer::Paramete
                                                     heightOut);
             if(nullptr != pixelsOut)
             {
-              delete[] data.buffer;
-              data.buffer                = pixelsOut;
-              glyphBufferPtr.get()->type = GlyphBuffer::FREE;
-              data.width                 = widthOut;
-              data.height                = heightOut;
+              free(data.buffer);
+              data.buffer = pixelsOut;
+              data.width  = widthOut;
+              data.height = heightOut;
             }
 
             glyphX = centerX - 0.5 * static_cast<double>(data.width);
index cdec41f..16b8044 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -50,7 +50,7 @@ void EmbeddedItem::CreateBitmap(const std::vector<PixelBufferCacheItem>&
   {
     // Creates the output buffer
     const unsigned int bufferSize = data.width * data.height * 4u;
-    data.buffer                   = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[].
+    data.buffer                   = (uint8_t*)malloc(bufferSize * sizeof(uint8_t)); // @note The caller is responsible for deallocating the bitmap data using free.
 
     memset(data.buffer, 0u, bufferSize);
 
index 7790a2e..6c0c264 100644 (file)
@@ -1165,7 +1165,7 @@ PixelData FontClient::Plugin::CreateBitmap(FontId fontId, GlyphIndex glyphIndex,
                         data.width,
                         data.height,
                         data.format,
-                        PixelData::DELETE_ARRAY);
+                        PixelData::FREE);
 }
 
 void FontClient::Plugin::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
index bb79eb3..9141ca1 100644 (file)
@@ -143,7 +143,7 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned
 
   // Creates the output buffer
   const unsigned int bufferSize = data.width * data.height * 4u;
-  data.buffer                   = new uint8_t[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[].
+  data.buffer                   = (uint8_t*)malloc(bufferSize * sizeof(uint8_t)); // @note The caller is responsible for deallocating the bitmap data using free.
 
   if(inputDimensions == desiredDimensions)
   {
@@ -164,10 +164,12 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, unsigned
  * @brief Copy the FreeType bitmap to the given buffer.
  *
  * @param[out] data The bitmap data.
- * @param[in] srcBitmap The FreeType bitmap.
+ * @param[in,out] srcBitmap The FreeType bitmap.
  * @param[in] isShearRequired Whether the bitmap needs a shear transform (for software italics).
+ * @param[in] moveBuffer Whether the bitmap buffer move. True if just copy buffer pointer. False if we use memcpy. (Default is false.)
+ * @note If you set moveBuffer=true, the bitmap's buffer moved frome srcBitmap to data. So srcBitmap buffer changed as nullptr.
  */
-void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap srcBitmap, bool isShearRequired)
+void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap& srcBitmap, bool isShearRequired, bool moveBuffer)
 {
   if(srcBitmap.width * srcBitmap.rows > 0)
   {
@@ -181,7 +183,7 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap
           unsigned int width    = srcBitmap.width;
           unsigned     height   = srcBitmap.rows;
 
-          std::unique_ptr<uint8_t, void (*)(void*)> pixelsOutPtr(nullptr, free);
+          uint8_t* releaseRequiredPixelPtr = nullptr;
 
           if(isShearRequired)
           {
@@ -232,18 +234,52 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap
                                                       widthOut,
                                                       heightOut);
 
-            width    = widthOut;
-            height   = heightOut;
-            pixelsIn = pixelsOut;
-            pixelsOutPtr.reset(pixelsOut);
+            if(DALI_LIKELY(pixelsOut))
+            {
+              width  = widthOut;
+              height = heightOut;
+
+              if(moveBuffer)
+              {
+                releaseRequiredPixelPtr = pixelsIn;
+              }
+              else
+              {
+                releaseRequiredPixelPtr = pixelsOut;
+              }
+
+              // Change input buffer ptr.
+              pixelsIn = pixelsOut;
+            }
+            else
+            {
+              DALI_LOG_ERROR("ERROR! software italic slant failed!\n");
+            }
           }
 
-          const unsigned int bufferSize = width * height;
-          data.buffer                   = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[].
-          data.width                    = width;
-          data.height                   = height;
-          data.format                   = Pixel::L8; // Sets the pixel format.
-          memcpy(data.buffer, pixelsIn, bufferSize);
+          data.width  = width;
+          data.height = height;
+          data.format = Pixel::L8; // Sets the pixel format.
+
+          if(moveBuffer)
+          {
+            data.buffer = pixelsIn;
+
+            // Happy trick for copyless convert bitmap!
+            srcBitmap.buffer = nullptr;
+          }
+          else
+          {
+            const unsigned int bufferSize = width * height;
+            data.buffer                   = (uint8_t*)malloc(bufferSize * sizeof(uint8_t)); // @note The caller is responsible for deallocating the bitmap data using free.
+
+            memcpy(data.buffer, pixelsIn, bufferSize);
+          }
+
+          if(releaseRequiredPixelPtr)
+          {
+            free(releaseRequiredPixelPtr);
+          }
         }
         break;
       }
@@ -253,6 +289,7 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data, FT_Bitmap
       {
         if(srcBitmap.pitch == static_cast<int>(srcBitmap.width << 2u))
         {
+          // Color glyph doesn't support copyless convert bitmap. Just memcpy
           ConvertBitmap(data, srcBitmap.width, srcBitmap.rows, srcBitmap.buffer);
 
           // Sets the pixel format.
index f329193..daf4c5b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEST_ABSTRACTION_INTERNAL_FONT_CLIENT_UTILS_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -38,8 +38,9 @@ void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data,
                    const unsigned char* const                    srcBuffer);
 
 void ConvertBitmap(TextAbstraction::FontClient::GlyphBufferData& data,
-                   FT_Bitmap                                     srcBitmap,
-                   bool                                          isShearRequired);
+                   FT_Bitmap&                                    srcBitmap,
+                   bool                                          isShearRequired,
+                   bool                                          moveBuffer = false);
 
 /**
  * @brief Creates a font family pattern used to match fonts.
index 34e2b48..dcde3e7 100644 (file)
@@ -424,7 +424,8 @@ void FontFaceCacheItem::CreateBitmap(
           data.outlineOffsetY = bitmapGlyph->top - offsetY - outlineWidth;
         }
 
-        ConvertBitmap(data, bitmapGlyph->bitmap, isShearRequired);
+        // Move bitmap buffer into data.buffer
+        ConvertBitmap(data, bitmapGlyph->bitmap, isShearRequired, true);
 
         // Copied FT_Glyph object must be released with FT_Done_Glyph
         FT_Done_Glyph(glyph);