lottie/vector: refactor VBitmap class to use shared_ptr for refcount implementation. 39/196739/2
authorsubhransu mohanty <sub.mohanty@samsung.com>
Fri, 4 Jan 2019 04:22:33 +0000 (13:22 +0900)
committersubhransu mohanty <sub.mohanty@samsung.com>
Fri, 4 Jan 2019 04:28:50 +0000 (13:28 +0900)
Change-Id: I2a5bca2cd6a86a1f3ac69eb7799ee46b784f61cf

src/lottie/lottieitem.cpp
src/vector/vbitmap.cpp
src/vector/vbitmap.h
src/vector/vdrawhelper.cpp

index 886b8c0..11a6489 100644 (file)
@@ -118,9 +118,9 @@ const LOTLayerNode * LOTCompItem::renderTree() const
 
 bool LOTCompItem::render(const lottie::Surface &surface)
 {
-    VBitmap bitmap((uchar *)surface.buffer(), surface.width(), surface.height(),
-                   surface.bytesPerLine(), VBitmap::Format::ARGB32_Premultiplied,
-                   nullptr, nullptr);
+    VBitmap bitmap(reinterpret_cast<uchar *>(surface.buffer()),
+                   surface.width(), surface.height(),
+                   surface.bytesPerLine(), VBitmap::Format::ARGB32_Premultiplied);
 
     /* schedule all preprocess task for this frame at once.
      */
index a72d56e..6fdbbd4 100644 (file)
 
 V_BEGIN_NAMESPACE
 
-struct VBitmapData {
-    ~VBitmapData();
-    VBitmapData();
-    static VBitmapData *create(int width, int height, VBitmap::Format format);
-    RefCount            ref;
-    int                 width;
-    int                 height;
-    int                 depth;
-    int                 stride;
-    int                 nBytes;
-    VBitmap::Format     format;
-    uchar *             data;
-    VBitmapCleanupFunction cleanupFunction;
-    void *                 cleanupInfo;
-    uint                   ownData : 1;
-    uint                   roData : 1;
-};
-
-VBitmapData::~VBitmapData()
-{
-    if (cleanupFunction) cleanupFunction(cleanupInfo);
-    if (data && ownData) free(data);
-    data = 0;
-}
-
-VBitmapData::VBitmapData()
-    : ref(0),
-      width(0),
-      height(0),
-      depth(0),
-      stride(0),
-      nBytes(0),
-      format(VBitmap::Format::ARGB32),
-      data(nullptr),
-      cleanupFunction(0),
-      cleanupInfo(0),
-      ownData(true),
-      roData(false)
-{
-}
-
-VBitmapData *VBitmapData::create(int width, int height, VBitmap::Format format)
-{
-    if ((width <= 0) || (height <= 0) || format == VBitmap::Format::Invalid)
-        return nullptr;
-
-    int depth = 1;
-    switch (format) {
-    case VBitmap::Format::Alpha8:
-        depth = 8;
-        VECTOR_FALLTHROUGH
-    case VBitmap::Format::ARGB32:
-    case VBitmap::Format::ARGB32_Premultiplied:
-        depth = 32;
-        break;
-    default:
-        break;
+struct VBitmap::Impl {
+    uchar *             mData{nullptr};
+    uint                mWidth{0};
+    uint                mHeight{0};
+    uint                mStride{0};
+    uint                mBytes{0};
+    VBitmap::Format     mFormat{VBitmap::Format::Invalid};
+    bool                mOwnData;
+    bool                mRoData;
+
+    Impl() = delete ;
+
+    Impl(uint width, uint height, VBitmap::Format format):
+        mOwnData(true),
+        mRoData(false)
+    {
+        uint depth = Impl::depth(format);
+        uint stride = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4)
+
+        mWidth = width;
+        mHeight = height;
+        mFormat = format;
+        mStride = stride;
+        mBytes = mStride * mHeight;
+        mData = reinterpret_cast<uchar *>(::operator new(mBytes));
+
+        if (!mData) {
+            // handle malloc failure
+            ;
+        }
     }
 
-    const int stride = ((width * depth + 31) >> 5)
-                       << 2;  // bytes per scanline (must be multiple of 4)
-
-    VBitmapData *d = new VBitmapData;
-
-    d->width = width;
-    d->height = height;
-    d->depth = depth;
-    d->format = format;
-    d->stride = stride;
-    d->nBytes = d->stride * height;
-    d->data = (uchar *)malloc(d->nBytes);
-
-    if (!d->data) {
-        delete d;
-        return 0;
+    Impl(uchar *data, uint w, uint h, uint bytesPerLine, VBitmap::Format format):
+        mOwnData(false),
+        mRoData(false)
+    {
+        mWidth = w;
+        mHeight = h;
+        mFormat = format;
+        mStride = bytesPerLine;
+        mBytes = mStride * mHeight;
+        mData = data;
     }
 
-    return d;
-}
-
-inline void VBitmap::cleanUp(VBitmapData *d)
-{
-    delete d;
-}
-
-void VBitmap::detach()
-{
-    if (d) {
-        if (d->ref.isShared() || d->roData) *this = copy();
+    ~Impl()
+    {
+        if (mOwnData && mData) ::operator delete(mData);
     }
-}
-
-VBitmap::~VBitmap()
-{
-    if (!d) return;
-
-    if (!d->ref.deref()) cleanUp(d);
-}
-
-VBitmap::VBitmap() : d(nullptr) {}
-
-VBitmap::VBitmap(const VBitmap &other)
-{
-    d = other.d;
-    if (d) d->ref.ref();
-}
 
-VBitmap::VBitmap(VBitmap &&other) : d(other.d)
-{
-    other.d = nullptr;
-}
-
-VBitmap &VBitmap::operator=(const VBitmap &other)
-{
-    if (!d) {
-        d = other.d;
-        if (d) d->ref.ref();
-    } else {
-        if (!d->ref.deref()) cleanUp(d);
-        other.d->ref.ref();
-        d = other.d;
+    uint stride() const {return mStride;}
+    uint width() const {return mWidth;}
+    uint height() const {return mHeight;}
+    VBitmap::Format format() const {return mFormat;}
+    uchar* data() { return mData;}
+
+    static uint depth(VBitmap::Format format)
+    {
+        uint depth = 1;
+        switch (format) {
+        case VBitmap::Format::Alpha8:
+            depth = 8;
+            break;
+        case VBitmap::Format::ARGB32:
+        case VBitmap::Format::ARGB32_Premultiplied:
+            depth = 32;
+            break;
+        default:
+            break;
+        }
+        return depth;
     }
+    void fill(uint /*pixel*/)
+    {
+        //@TODO
+    }
+};
 
-    return *this;
-}
-
-inline VBitmap &VBitmap::operator=(VBitmap &&other)
+VBitmap::VBitmap(uint width, uint height, VBitmap::Format format)
 {
-    if (d && !d->ref.deref()) cleanUp(d);
-    d = other.d;
-    return *this;
-}
+    if (width <=0 || height <=0 || format == Format::Invalid) return;
 
-VBitmap::VBitmap(int w, int h, VBitmap::Format format) {}
-VBitmap::VBitmap(uchar *data, int w, int h, int bytesPerLine,
-                 VBitmap::Format format, VBitmapCleanupFunction f,
-                 void *cleanupInfo)
-{
-    d = new VBitmapData;
-    d->data = data;
-    d->format = format;
-    d->width = w;
-    d->height = h;
-    d->stride = bytesPerLine;
-    d->cleanupFunction = nullptr;
-    d->cleanupInfo = nullptr;
-    d->ownData = false;
-    d->roData = false;
-    d->ref.setOwned();
-}
+    mImpl = std::make_shared<Impl>(width, height, format);
 
-VBitmap VBitmap::copy(const VRect &r) const
-{
-    // TODO implement properly.
-    return *this;
-}
-
-int VBitmap::stride() const
-{
-    return d ? d->stride : 0;
 }
 
-int VBitmap::width() const
+VBitmap::VBitmap(uchar *data, uint width, uint height, uint bytesPerLine,
+                 VBitmap::Format format)
 {
-    return d ? d->width : 0;
-}
+    if (!data ||
+        width <=0 || height <=0 ||
+        bytesPerLine <=0 ||
+        format == Format::Invalid) return;
 
-int VBitmap::height() const
-{
-    return d ? d->height : 0;
+    mImpl = std::make_shared<Impl>(data, width, height, bytesPerLine, format);
 }
 
-uchar *VBitmap::bits()
+uint VBitmap::stride() const
 {
-    if (!d) return 0;
-    detach();
-
-    // In case detach ran out of memory...
-    if (!d) return 0;
-
-    return d->data;
+    return mImpl ? mImpl->stride() : 0;
 }
 
-const uchar *VBitmap::bits() const
+uint VBitmap::width() const
 {
-    return d ? d->data : 0;
+    return mImpl ? mImpl->width() : 0;
 }
 
-bool VBitmap::isNull() const
+uint VBitmap::height() const
 {
-    return !d;
+    return mImpl ? mImpl->height() : 0;
 }
 
-uchar *VBitmap::scanLine(int i)
+uchar *VBitmap::data()
 {
-    if (!d) return 0;
-
-    detach();
-
-    // In case detach() ran out of memory
-    if (!d) return 0;
-
-    return d->data + i * d->stride;
+    return mImpl ? mImpl->data() : nullptr;
 }
 
-const uchar *VBitmap::scanLine(int i) const
+bool VBitmap::valid() const
 {
-    if (!d) return 0;
-
-    // assert(i >= 0 && i < height());
-    return d->data + i * d->stride;
+    return mImpl ? true : false;
 }
 
 VBitmap::Format VBitmap::format() const
 {
-    if (!d) return VBitmap::Format::Invalid;
-    return d->format;
+    return mImpl ? mImpl->format() : VBitmap::Format::Invalid;
 }
 
 void VBitmap::fill(uint pixel)
 {
-    if (!d) return;
+    if (mImpl) mImpl->fill(pixel);
 }
 
 V_END_NAMESPACE
index bdf2e76..8b162c2 100644 (file)
 
 V_BEGIN_NAMESPACE
 
-struct VBitmapData;
-typedef void (*VBitmapCleanupFunction)(void *);
 class VBitmap {
 public:
-    enum class Format { Invalid, Alpha8, ARGB32, ARGB32_Premultiplied, Last };
-    ~VBitmap();
-    VBitmap();
-    VBitmap(const VBitmap &other);
-    VBitmap(VBitmap &&other);
-    VBitmap &operator=(const VBitmap &);
-    VBitmap &operator=(VBitmap &&other);
-
-    VBitmap(int w, int h, VBitmap::Format format);
-    VBitmap(uchar *data, int w, int h, int bytesPerLine, VBitmap::Format format,
-            VBitmapCleanupFunction f = nullptr, void *cleanupInfo = nullptr);
-
-    VBitmap copy(const VRect &rect = VRect()) const;
-    void    fill(uint pixel);
-
-    int             width() const;
-    int             height() const;
-    uchar *         bits();
-    const uchar *   bits() const;
-    uchar *         scanLine(int);
-    const uchar *   scanLine(int) const;
-    int             stride() const;
-    bool            isNull() const;
+    enum class Format: uchar {
+        Invalid,
+        Alpha8,
+        ARGB32,
+        ARGB32_Premultiplied
+    };
+
+    VBitmap() = default;
+    VBitmap(uint w, uint h, VBitmap::Format format);
+    VBitmap(uchar *data, uint w, uint h, uint bytesPerLine, VBitmap::Format format);
+
+    uint          stride() const;
+    uint          width() const;
+    uint          height() const;
     VBitmap::Format format() const;
+    bool            valid() const;
+    uchar *         data();
 
+    void    fill(uint pixel);
 private:
-    void         detach();
-    void         cleanUp(VBitmapData *x);
-    VBitmapData *d{nullptr};
+    struct Impl;
+    std::shared_ptr<Impl> mImpl;
 };
 
 V_END_NAMESPACE
index c682edb..7e57fde 100644 (file)
@@ -201,14 +201,13 @@ void VRasterBuffer::clear()
 
 VBitmap::Format VRasterBuffer::prepare(VBitmap *image)
 {
-    mBuffer = (uchar *)image->bits();
+    mBuffer = image->data();
     mWidth = image->width();
     mHeight = image->height();
     mBytesPerPixel = 4;
     mBytesPerLine = image->stride();
 
     mFormat = image->format();
-    // drawHelper = qDrawHelper + format;
     return mFormat;
 }