1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_CUSTOM_PAINT_CANVAS_PAINT_MEM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_CUSTOM_PAINT_CANVAS_PAINT_MEM_H 18 19 #include <cstdlib> 20 #include <limits> 21 #include <memory> 22 #include <type_traits> 23 #include <utility> 24 25 #include "base/log/log.h" 26 27 namespace OHOS::Ace::NG { 28 29 template <typename T, 30 typename = std::enable_if_t<std::is_trivially_default_constructible<T>::value && 31 std::is_trivially_destructible<T>::value>> 32 class AutoTMalloc { 33 public: 34 explicit AutoTMalloc(T* ptr = nullptr) : fPtr_(ptr) {} AutoTMalloc(size_t count)35 explicit AutoTMalloc(size_t count) 36 : fPtr_(count ? (T*)MallocThrow(count, sizeof(T)) : nullptr) {} 37 38 AutoTMalloc(AutoTMalloc&&) = default; 39 AutoTMalloc& operator=(AutoTMalloc&&) = default; realloc(size_t count)40 void realloc(size_t count) 41 { 42 fPtr_.reset(count ? (T*)ReallocThrow(fPtr_.release(), count * sizeof(T)) : nullptr); 43 } 44 45 T* Reset(size_t count = 0) 46 { 47 fPtr_.reset(count ? (T*)MallocThrow(count, sizeof(T)) : nullptr); 48 return this->get(); 49 } get()50 T* get() const { return fPtr_.get(); } 51 operator T*() { return fPtr_.get(); } 52 operator const T*() const { return fPtr_.get(); } 53 T& operator[](int index) { return fPtr_.get()[index]; } 54 const T& operator[](int index) const { return fPtr_.get()[index]; } data()55 const T* data() const { return fPtr_.get(); } data()56 T* data() { return fPtr_.get(); } release()57 T* release() { return fPtr_.release(); } 58 59 private: 60 enum { 61 MALLOC_ZERO_INITIALIZE = 1 << 0, 62 MALLOC_THROW = 1 << 1, 63 }; 64 ThrowOnFailure(size_t size,void * p)65 static inline void* ThrowOnFailure(size_t size, void* p) 66 { 67 if (size > 0 && p == nullptr) { 68 TAG_LOGE(AceLogTag::ACE_CANVAS_COMPONENT, "canvas paint out of memory"); 69 } 70 return p; 71 } 72 Add(size_t x,size_t y)73 static inline size_t Add(size_t x, size_t y) 74 { 75 return x + y; 76 } 77 Mul32(uint32_t x,uint32_t y)78 static inline uint32_t Mul32(uint32_t x, uint32_t y) 79 { 80 uint64_t bx = x; 81 uint64_t by = y; 82 uint64_t result = bx * by; 83 return result; 84 } 85 Mul64(uint64_t x,uint64_t y)86 static inline uint64_t Mul64(uint64_t x, uint64_t y) 87 { 88 if (x <= std::numeric_limits<uint64_t>::max() >> INT32SIZE 89 && y <= std::numeric_limits<uint64_t>::max() >> INT32SIZE) { 90 return x * y; 91 } else { 92 auto hi = [](uint64_t x) { return x >> INT32SIZE; }; 93 auto lo = [](uint64_t x) { return x & INT32VALUE; }; 94 uint64_t lx_ly = lo(x) * lo(y); 95 uint64_t hx_ly = hi(x) * lo(y); 96 uint64_t lx_hy = lo(x) * hi(y); 97 uint64_t result = Add(lx_ly, (hx_ly << INT32SIZE)); 98 result = Add(result, (lx_hy << INT32SIZE)); 99 return result; 100 } 101 } 102 MallocFlags(size_t size,unsigned flags)103 static inline void* MallocFlags(size_t size, unsigned flags) 104 { 105 void* p; 106 if (flags & MALLOC_ZERO_INITIALIZE) { 107 p = std::calloc(size, 1); 108 } else { 109 p = std::malloc(size); 110 } 111 if (flags & MALLOC_THROW) { 112 return ThrowOnFailure(size, p); 113 } else { 114 return p; 115 } 116 } 117 MallocThrow(size_t x,size_t y)118 static inline void* MallocThrow(size_t x, size_t y) 119 { 120 auto size = sizeof(size_t) == sizeof(uint64_t)? Mul64(x, y): Mul32(x, y); 121 return MallocFlags(size, MALLOC_THROW); 122 } 123 ReallocThrow(void * addr,size_t size)124 static inline void* ReallocThrow(void*addr, size_t size) 125 { 126 return nullptr; 127 } 128 129 template <typename V, V* P> 130 struct FunctionWrapper { 131 template <typename... Args> 132 auto operator()(Args&&... args) const-> decltype(P(std::forward<Args>(args)...)) 133 { 134 return P(std::forward<Args>(args)...); 135 } 136 }; 137 138 std::unique_ptr<T, FunctionWrapper<void(void*), free>> fPtr_; 139 static constexpr uint32_t INT32SIZE = 32; 140 static constexpr uint32_t INT32VALUE = 0xFFFFFFFF; 141 }; 142 143 } // namespce OHOS::Ace 144 145 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_CUSTOM_PAINT_CANVAS_PAINT_MEM_H 146