diff options
Diffstat (limited to 'libshims')
-rw-r--r-- | libshims/include/ui/GraphicBuffer.h | 142 | ||||
-rw-r--r-- | libshims/include/ui/GraphicBufferAllocator.h | 16 | ||||
-rw-r--r-- | libshims/include/ui/GraphicBufferMapper.h | 38 | ||||
-rw-r--r-- | libshims/include/utils/Looper.h | 10 | ||||
-rw-r--r-- | libshims/include/utils/VectorImpl.h | 43 | ||||
-rw-r--r-- | libshims/ui/GraphicBuffer.cpp | 320 | ||||
-rw-r--r-- | libshims/ui/GraphicBufferAllocator.cpp | 103 | ||||
-rw-r--r-- | libshims/ui/GraphicBufferMapper.cpp | 101 | ||||
-rw-r--r-- | libshims/utils/Looper.cpp | 83 | ||||
-rw-r--r-- | libshims/utils/VectorImpl.cpp | 79 |
10 files changed, 525 insertions, 410 deletions
diff --git a/libshims/include/ui/GraphicBuffer.h b/libshims/include/ui/GraphicBuffer.h index 7b4fac8..c195342 100644 --- a/libshims/include/ui/GraphicBuffer.h +++ b/libshims/include/ui/GraphicBuffer.h @@ -21,8 +21,12 @@ #include <sys/types.h> #include <string> +#include <utility> +#include <vector> +#include <android/hardware_buffer.h> #include <ui/ANativeObjectBase.h> +#include <ui/GraphicBufferMapper.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> #include <utils/Flattenable.h> @@ -31,13 +35,17 @@ #include <nativebase/nativebase.h> #include <hardware/gralloc.h> -struct ANativeWindowBuffer; namespace android { -class DetachedBufferHandle; +#ifndef LIBUI_IN_VNDK +class BufferHubBuffer; +#endif // LIBUI_IN_VNDK + class GraphicBufferMapper; +using GraphicBufferDeathCallback = std::function<void(void* /*context*/, uint64_t bufferId)>; + // =========================================================================== // GraphicBuffer // =========================================================================== @@ -76,6 +84,10 @@ public: static sp<GraphicBuffer> from(ANativeWindowBuffer *); + static GraphicBuffer* fromAHardwareBuffer(AHardwareBuffer*); + static GraphicBuffer const* fromAHardwareBuffer(AHardwareBuffer const*); + AHardwareBuffer* toAHardwareBuffer(); + AHardwareBuffer const* toAHardwareBuffer() const; // Create a GraphicBuffer to be unflatten'ed into or be reallocated. GraphicBuffer(); @@ -119,29 +131,27 @@ public: // cannot be used directly, such as one from hidl_handle. CLONE_HANDLE, }; - GraphicBuffer(const native_handle_t* handle, HandleWrapMethod method, - uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, - uint64_t usage, uint32_t stride); + GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, uint32_t inWidth, + uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage, + uint32_t inStride); // These functions are deprecated because they only take 32 bits of usage - GraphicBuffer(const native_handle_t* handle, HandleWrapMethod method, - uint32_t width, uint32_t height, - PixelFormat format, - uint32_t usage, uint32_t stride) - : GraphicBuffer(handle, method, width, height, format, layerCount, - static_cast<uint64_t>(usage), stride) {} + GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, uint32_t inWidth, + uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, + uint32_t inStride) + : GraphicBuffer(inHandle, method, inWidth, inHeight, inFormat, inLayerCount, + static_cast<uint64_t>(inUsage), inStride) {} GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, - uint32_t inUsage, uint32_t inStride, + uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride, native_handle_t* inHandle, bool keepOwnership); GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, - uint32_t inUsage); - // create a buffer from an existing ANativeWindowBuffer - GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership); - - GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inUsage, std::string requestorName = "<Unknown>"); +#ifndef LIBUI_IN_VNDK + // Create a GraphicBuffer from an existing BufferHubBuffer. + GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer); +#endif // LIBUI_IN_VNDK + // return status status_t initCheck() const; @@ -153,6 +163,7 @@ public: uint32_t getLayerCount() const { return static_cast<uint32_t>(layerCount); } Rect getBounds() const { return Rect(width, height); } uint64_t getId() const { return mId; } + int32_t getBufferId() const { return mBufferId; } uint32_t getGenerationNumber() const { return mGenerationNumber; } void setGenerationNumber(uint32_t generation) { @@ -168,24 +179,35 @@ public: bool needsReallocation(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage); - status_t lock(uint32_t inUsage, void** vaddr); - status_t lock(uint32_t inUsage, const Rect& rect, void** vaddr); + // For the following two lock functions, if bytesPerStride or bytesPerPixel + // are unknown or variable, -1 will be returned + status_t lock(uint32_t inUsage, void** vaddr, int32_t* outBytesPerPixel = nullptr, + int32_t* outBytesPerStride = nullptr); + status_t lock(uint32_t inUsage, const Rect& rect, void** vaddr, + int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); // For HAL_PIXEL_FORMAT_YCbCr_420_888 status_t lockYCbCr(uint32_t inUsage, android_ycbcr *ycbcr); status_t lockYCbCr(uint32_t inUsage, const Rect& rect, android_ycbcr *ycbcr); status_t unlock(); - status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd); - status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, - int fenceFd); - status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, - const Rect& rect, void** vaddr, int fenceFd); + // For the following three lockAsync functions, if bytesPerStride or bytesPerPixel + // are unknown or variable, -1 will be returned + status_t lockAsync(uint32_t inUsage, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); + status_t lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); + status_t lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, const Rect& rect, + void** vaddr, int fenceFd, int32_t* outBytesPerPixel = nullptr, + int32_t* outBytesPerStride = nullptr); status_t lockAsyncYCbCr(uint32_t inUsage, android_ycbcr *ycbcr, int fenceFd); status_t lockAsyncYCbCr(uint32_t inUsage, const Rect& rect, android_ycbcr *ycbcr, int fenceFd); status_t unlockAsync(int *fenceFd); + status_t isSupported(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, bool* outSupported) const; + ANativeWindowBuffer* getNativeBuffer() const; // for debugging @@ -197,10 +219,16 @@ public: status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); - // Sets and takes DetachedBuffer. Should only be called from BufferHub. - bool isDetachedBuffer() const; - status_t setDetachedBufferHandle(std::unique_ptr<DetachedBufferHandle> detachedBuffer); - std::unique_ptr<DetachedBufferHandle> takeDetachedBufferHandle(); + GraphicBufferMapper::Version getBufferMapperVersion() const { + return mBufferMapper.getMapperVersion(); + } + + void addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context); + +#ifndef LIBUI_IN_VNDK + // Returns whether this GraphicBuffer is backed by BufferHubBuffer. + bool isBufferHubBuffer() const; +#endif // LIBUI_IN_VNDK private: ~GraphicBuffer(); @@ -232,41 +260,61 @@ private: PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage, std::string requestorName); - status_t initWithHandle(const native_handle_t* handle, - HandleWrapMethod method, uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, - uint64_t usage, uint32_t stride); + status_t initWithHandle(const native_handle_t* inHandle, HandleWrapMethod method, + uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride); void free_handle(); GraphicBufferMapper& mBufferMapper; ssize_t mInitCheck; - // If we're wrapping another buffer then this reference will make sure it - // doesn't get freed. - sp<ANativeWindowBuffer> mWrappedBuffer; - // numbers of fds/ints in native_handle_t to flatten uint32_t mTransportNumFds; uint32_t mTransportNumInts; uint64_t mId; + // System unique buffer ID. Note that this is different from mId, which is process unique. For + // GraphicBuffer backed by BufferHub, the mBufferId is a system unique identifier that stays the + // same cross process for the same chunck of underlying memory. Also note that this only applies + // to GraphicBuffers that are backed by BufferHub. + int32_t mBufferId = -1; + // Stores the generation number of this buffer. If this number does not // match the BufferQueue's internal generation number (set through // IGBP::setGenerationNumber), attempts to attach the buffer will fail. uint32_t mGenerationNumber; - // Stores a BufferHub handle that can be used to re-attach this GraphicBuffer back into a - // BufferHub producer/consumer set. In terms of GraphicBuffer's relationship with BufferHub, - // there are three different modes: - // 1. Legacy mode: GraphicBuffer is not backed by BufferHub and mDetachedBufferHandle must be - // invalid. - // 2. Detached mode: GraphicBuffer is backed by BufferHub, but not part of a producer/consumer - // set. In this mode, mDetachedBufferHandle must be valid. - // 3. Attached mode: GraphicBuffer is backed by BufferHub and it's part of a producer/consumer - // set. In this mode, mDetachedBufferHandle must be invalid. - std::unique_ptr<DetachedBufferHandle> mDetachedBufferHandle; + // Send a callback when a GraphicBuffer dies. + // + // This is used for BufferStateLayer caching. GraphicBuffers are refcounted per process. When + // A GraphicBuffer doesn't have any more sp<> in a process, it is destroyed. This causes + // problems when trying to implicitcly cache across process boundaries. Ideally, both sides + // of the cache would hold onto wp<> references. When an app dropped its sp<>, the GraphicBuffer + // would be destroyed. Unfortunately, when SurfaceFlinger has only a wp<> reference to the + // GraphicBuffer, it immediately goes out of scope in the SurfaceFlinger process. SurfaceFlinger + // must hold onto a sp<> to the buffer. When the GraphicBuffer goes out of scope in the app's + // process, the client side cache will get this callback. It erases the buffer from its cache + // and informs SurfaceFlinger that it should drop its strong pointer reference to the buffer. + std::vector<std::pair<GraphicBufferDeathCallback, void* /*mDeathCallbackContext*/>> + mDeathCallbacks; + +#ifndef LIBUI_IN_VNDK + // Flatten this GraphicBuffer object if backed by BufferHubBuffer. + status_t flattenBufferHubBuffer(void*& buffer, size_t& size) const; + + // Unflatten into BufferHubBuffer backed GraphicBuffer. + // Unflatten will fail if the original GraphicBuffer object is destructed. For instance, a + // GraphicBuffer backed by BufferHubBuffer_1 flatten in process/thread A, transport the token + // to process/thread B through a socket, BufferHubBuffer_1 dies and bufferhub invalidated the + // token. Race condition occurs between the invalidation of the token in bufferhub process and + // process/thread B trying to unflatten and import the buffer with that token. + status_t unflattenBufferHubBuffer(void const*& buffer, size_t& size); + + // Stores a BufferHubBuffer that handles buffer signaling, identification. + std::unique_ptr<BufferHubBuffer> mBufferHubBuffer; +#endif // LIBUI_IN_VNDK }; }; // namespace android diff --git a/libshims/include/ui/GraphicBufferAllocator.h b/libshims/include/ui/GraphicBufferAllocator.h index 546fb4b..25d4512 100644 --- a/libshims/include/ui/GraphicBufferAllocator.h +++ b/libshims/include/ui/GraphicBufferAllocator.h @@ -32,16 +32,10 @@ #include <utils/Mutex.h> #include <utils/Singleton.h> -#include <hardware/gralloc.h> - namespace android { -namespace Gralloc2 { -class Allocator; -} - +class GrallocAllocator; class GraphicBufferMapper; -class String8; class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator> { @@ -55,7 +49,9 @@ public: status_t free(buffer_handle_t handle); - void dump(String8& res) const; + size_t getTotalSize() const; + + void dump(std::string& res) const; static void dumpToSystemLog(); private: @@ -77,8 +73,8 @@ private: GraphicBufferAllocator(); ~GraphicBufferAllocator(); - alloc_device_t *mAllocDev; - const std::unique_ptr<const Gralloc2::Allocator> mAllocator; + GraphicBufferMapper& mMapper; + std::unique_ptr<const GrallocAllocator> mAllocator; }; // --------------------------------------------------------------------------- diff --git a/libshims/include/ui/GraphicBufferMapper.h b/libshims/include/ui/GraphicBufferMapper.h index 7cf003d..2461454 100644 --- a/libshims/include/ui/GraphicBufferMapper.h +++ b/libshims/include/ui/GraphicBufferMapper.h @@ -35,15 +35,16 @@ namespace android { // --------------------------------------------------------------------------- -namespace Gralloc2 { -class Mapper; -} - +class GrallocMapper; class Rect; class GraphicBufferMapper : public Singleton<GraphicBufferMapper> { public: + enum Version { + GRALLOC_2, + GRALLOC_3, + }; static void preloadHal(); static inline GraphicBufferMapper& get() { return getInstance(); } @@ -59,20 +60,21 @@ public: void getTransportSize(buffer_handle_t handle, uint32_t* outTransportNumFds, uint32_t* outTransportNumInts); - status_t lock(buffer_handle_t handle, - uint32_t usage, const Rect& bounds, void** vaddr); + status_t lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, void** vaddr, + int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); status_t lockYCbCr(buffer_handle_t handle, uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr); status_t unlock(buffer_handle_t handle); - status_t lockAsync(buffer_handle_t handle, - uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd); + status_t lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds, void** vaddr, + int fenceFd, int32_t* outBytesPerPixel = nullptr, + int32_t* outBytesPerStride = nullptr); - status_t lockAsync(buffer_handle_t handle, - uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds, - void** vaddr, int fenceFd); + status_t lockAsync(buffer_handle_t handle, uint64_t producerUsage, uint64_t consumerUsage, + const Rect& bounds, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel = nullptr, int32_t* outBytesPerStride = nullptr); status_t lockAsyncYCbCr(buffer_handle_t handle, uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, @@ -80,17 +82,23 @@ public: status_t unlockAsync(buffer_handle_t handle, int *fenceFd); - const Gralloc2::Mapper& getGrallocMapper() const - { - return *mMapper; + status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format, + uint32_t layerCount, uint64_t usage, bool* outSupported); + + const GrallocMapper& getGrallocMapper() const { + return reinterpret_cast<const GrallocMapper&>(*mMapper); } + Version getMapperVersion() const { return mMapperVersion; } + private: friend class Singleton<GraphicBufferMapper>; GraphicBufferMapper(); - const std::unique_ptr<const Gralloc2::Mapper> mMapper; + std::unique_ptr<const GrallocMapper> mMapper; + + Version mMapperVersion; }; // --------------------------------------------------------------------------- diff --git a/libshims/include/utils/Looper.h b/libshims/include/utils/Looper.h index a62e67f..c439c5c 100644 --- a/libshims/include/utils/Looper.h +++ b/libshims/include/utils/Looper.h @@ -24,6 +24,8 @@ #include <sys/epoll.h> +#include <android-base/unique_fd.h> + namespace android { /* @@ -262,7 +264,7 @@ public: */ int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); inline int pollOnce(int timeoutMillis) { - return pollOnce(timeoutMillis, NULL, NULL, NULL); + return pollOnce(timeoutMillis, nullptr, nullptr, nullptr); } /** @@ -272,7 +274,7 @@ public: */ int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); inline int pollAll(int timeoutMillis) { - return pollAll(timeoutMillis, NULL, NULL, NULL); + return pollAll(timeoutMillis, nullptr, nullptr, nullptr); } /** @@ -447,7 +449,7 @@ private: const bool mAllowNonCallbacks; // immutable - int mWakeEventFd; // immutable + android::base::unique_fd mWakeEventFd; // immutable Mutex mLock; Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock @@ -457,7 +459,7 @@ private: // any use of it is racy anyway. volatile bool mPolling; - int mEpollFd; // guarded by mLock but only modified on the looper thread + android::base::unique_fd mEpollFd; // guarded by mLock but only modified on the looper thread bool mEpollRebuildRequired; // guarded by mLock // Locked list of file descriptor monitoring requests. diff --git a/libshims/include/utils/VectorImpl.h b/libshims/include/utils/VectorImpl.h index f5fa742..41b9f33 100644 --- a/libshims/include/utils/VectorImpl.h +++ b/libshims/include/utils/VectorImpl.h @@ -53,12 +53,12 @@ public: /*! must be called from subclasses destructor */ void finish_vector(); - VectorImpl& operator = (const VectorImpl& rhs); - + VectorImpl& operator = (const VectorImpl& rhs); + /*! C-style array access */ inline const void* arrayImpl() const { return mStorage; } void* editArrayImpl(); - + /*! vector stats */ inline size_t size() const { return mCount; } inline bool isEmpty() const { return mCount == 0; } @@ -71,7 +71,7 @@ public: ssize_t appendVector(const VectorImpl& vector); ssize_t insertArrayAt(const void* array, size_t index, size_t length); ssize_t appendArray(const void* array, size_t length); - + /*! add/insert/replace items */ ssize_t insertAt(size_t where, size_t numItems = 1); ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); @@ -105,16 +105,7 @@ protected: virtual void do_splat(void* dest, const void* item, size_t num) const = 0; virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0; virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0; - - virtual void reservedVectorImpl1(); - virtual void reservedVectorImpl2(); - virtual void reservedVectorImpl3(); - virtual void reservedVectorImpl4(); - virtual void reservedVectorImpl5(); - virtual void reservedVectorImpl6(); - virtual void reservedVectorImpl7(); - virtual void reservedVectorImpl8(); - + private: void* _grow(size_t where, size_t amount); void _shrink(size_t where, size_t amount); @@ -141,10 +132,10 @@ class SortedVectorImpl : public VectorImpl { public: SortedVectorImpl(size_t itemSize, uint32_t flags); - SortedVectorImpl(const VectorImpl& rhs); + explicit SortedVectorImpl(const VectorImpl& rhs); virtual ~SortedVectorImpl(); - - SortedVectorImpl& operator = (const SortedVectorImpl& rhs); + + SortedVectorImpl& operator = (const SortedVectorImpl& rhs); //! finds the index of an item ssize_t indexOf(const void* item) const; @@ -158,24 +149,15 @@ public: //! merges a vector into this one ssize_t merge(const VectorImpl& vector); ssize_t merge(const SortedVectorImpl& vector); - + //! removes an item ssize_t remove(const void* item); - + protected: virtual int do_compare(const void* lhs, const void* rhs) const = 0; - virtual void reservedSortedVectorImpl1(); - virtual void reservedSortedVectorImpl2(); - virtual void reservedSortedVectorImpl3(); - virtual void reservedSortedVectorImpl4(); - virtual void reservedSortedVectorImpl5(); - virtual void reservedSortedVectorImpl6(); - virtual void reservedSortedVectorImpl7(); - virtual void reservedSortedVectorImpl8(); - private: - ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; + ssize_t _indexOrderOf(const void* item, size_t* order = nullptr) const; // these are made private, because they can't be used on a SortedVector // (they don't have an implementation either) @@ -193,8 +175,7 @@ private: ssize_t replaceAt(const void* item, size_t index); }; -}; // namespace android - +} // namespace android // --------------------------------------------------------------------------- diff --git a/libshims/ui/GraphicBuffer.cpp b/libshims/ui/GraphicBuffer.cpp index a1cf872..3fc6a2d 100644 --- a/libshims/ui/GraphicBuffer.cpp +++ b/libshims/ui/GraphicBuffer.cpp @@ -15,6 +15,7 @@ */ #define LOG_TAG "GraphicBuffer" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <ui/GraphicBuffer.h> @@ -22,10 +23,14 @@ #include <grallocusage/GrallocUsageConversion.h> -#include <ui/DetachedBufferHandle.h> +#ifndef LIBUI_IN_VNDK +#include <ui/BufferHubBuffer.h> +#endif // LIBUI_IN_VNDK + #include <ui/Gralloc2.h> #include <ui/GraphicBufferAllocator.h> #include <ui/GraphicBufferMapper.h> +#include <utils/Trace.h> namespace android { @@ -44,6 +49,22 @@ sp<GraphicBuffer> GraphicBuffer::from(ANativeWindowBuffer* anwb) { return static_cast<GraphicBuffer *>(anwb); } +GraphicBuffer* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer* buffer) { + return reinterpret_cast<GraphicBuffer*>(buffer); +} + +GraphicBuffer const* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer const* buffer) { + return reinterpret_cast<GraphicBuffer const*>(buffer); +} + +AHardwareBuffer* GraphicBuffer::toAHardwareBuffer() { + return reinterpret_cast<AHardwareBuffer*>(this); +} + +AHardwareBuffer const* GraphicBuffer::toAHardwareBuffer() const { + return reinterpret_cast<AHardwareBuffer const*>(this); +} + GraphicBuffer::GraphicBuffer() : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) @@ -55,57 +76,66 @@ GraphicBuffer::GraphicBuffer() usage_deprecated = 0; usage = 0; layerCount = 0; - handle = NULL; + handle = nullptr; } +// deprecated GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage) - : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()) + PixelFormat inFormat, uint32_t inUsage, std::string requestorName) + : GraphicBuffer(inWidth, inHeight, inFormat, 1, static_cast<uint64_t>(inUsage), requestorName) { - width = - height = - stride = - format = - usage = 0; - handle = NULL; - mInitCheck = initWithSize(inWidth, inHeight, inFormat, 1, - static_cast<uint64_t>(inUsage), "<Unknown>"); } +GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, std::string requestorName) + : GraphicBuffer() { + mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, + std::move(requestorName)); +} + +// deprecated GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, - PixelFormat inFormat, uint32_t inUsage, uint32_t inStride, - native_handle_t* inHandle, bool keepOwnership) - : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), - mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mId(getUniqueId()) -{ - width = static_cast<int>(inWidth); - height = static_cast<int>(inHeight); - stride = static_cast<int>(inStride); - format = inFormat; - usage = static_cast<int>(inUsage); - handle = inHandle; -} - -GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) - : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), - mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mWrappedBuffer(buffer), mId(getUniqueId()) + PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, + uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) + : GraphicBuffer(inHandle, keepOwnership ? TAKE_HANDLE : WRAP_HANDLE, + inWidth, inHeight, inFormat, inLayerCount, static_cast<uint64_t>(inUsage), + inStride) { - width = buffer->width; - height = buffer->height; - stride = buffer->stride; - format = buffer->format; - usage = buffer->usage; - handle = buffer->handle; } +GraphicBuffer::GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, + uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride) + : GraphicBuffer() { + mInitCheck = initWithHandle(inHandle, method, inWidth, inHeight, inFormat, inLayerCount, + inUsage, inStride); +} + +#ifndef LIBUI_IN_VNDK +GraphicBuffer::GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer) : GraphicBuffer() { + if (buffer == nullptr) { + mInitCheck = BAD_VALUE; + return; + } + + mInitCheck = initWithHandle(buffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, + buffer->desc().width, buffer->desc().height, + static_cast<PixelFormat>(buffer->desc().format), + buffer->desc().layers, buffer->desc().usage, buffer->desc().stride); + mBufferId = buffer->id(); + mBufferHubBuffer = std::move(buffer); +} +#endif // LIBUI_IN_VNDK + GraphicBuffer::~GraphicBuffer() { + ATRACE_CALL(); if (handle) { free_handle(); } + for (auto& [callback, context] : mDeathCallbacks) { + callback(context, mId); + } } void GraphicBuffer::free_handle() @@ -116,7 +146,7 @@ void GraphicBuffer::free_handle() GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); } - handle = NULL; + handle = nullptr; } status_t GraphicBuffer::initCheck() const { @@ -130,7 +160,6 @@ void GraphicBuffer::dumpAllocationsToSystemLog() ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const { - LOG_ALWAYS_FATAL_IF(this == NULL, "getNativeBuffer() called on NULL GraphicBuffer"); return static_cast<ANativeWindowBuffer*>( const_cast<GraphicBuffer*>(this)); } @@ -152,7 +181,7 @@ status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, if (handle) { GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); - handle = 0; + handle = nullptr; } return initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, "[Reallocation]"); } @@ -165,6 +194,7 @@ bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight, if (inFormat != format) return true; if (inLayerCount != layerCount) return true; if ((usage & inUsage) != inUsage) return true; + if ((usage & USAGE_PROTECTED) != (inUsage & USAGE_PROTECTED)) return true; return false; } @@ -191,26 +221,24 @@ status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight, return err; } -status_t GraphicBuffer::initWithHandle(const native_handle_t* handle, - HandleWrapMethod method, uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, uint64_t usage, - uint32_t stride) -{ - ANativeWindowBuffer::width = static_cast<int>(width); - ANativeWindowBuffer::height = static_cast<int>(height); - ANativeWindowBuffer::stride = static_cast<int>(stride); - ANativeWindowBuffer::format = format; - ANativeWindowBuffer::usage = usage; - ANativeWindowBuffer::usage_deprecated = int(usage); +status_t GraphicBuffer::initWithHandle(const native_handle_t* inHandle, HandleWrapMethod method, + uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride) { + ANativeWindowBuffer::width = static_cast<int>(inWidth); + ANativeWindowBuffer::height = static_cast<int>(inHeight); + ANativeWindowBuffer::stride = static_cast<int>(inStride); + ANativeWindowBuffer::format = inFormat; + ANativeWindowBuffer::usage = inUsage; + ANativeWindowBuffer::usage_deprecated = int(inUsage); - ANativeWindowBuffer::layerCount = layerCount; + ANativeWindowBuffer::layerCount = inLayerCount; mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle; if (method == TAKE_UNREGISTERED_HANDLE || method == CLONE_HANDLE) { buffer_handle_t importedHandle; - status_t err = mBufferMapper.importBuffer(handle, width, height, - layerCount, format, usage, stride, &importedHandle); + status_t err = mBufferMapper.importBuffer(inHandle, inWidth, inHeight, inLayerCount, + inFormat, inUsage, inStride, &importedHandle); if (err != NO_ERROR) { initWithHandle(nullptr, WRAP_HANDLE, 0, 0, 0, 0, 0, 0); @@ -218,28 +246,28 @@ status_t GraphicBuffer::initWithHandle(const native_handle_t* handle, } if (method == TAKE_UNREGISTERED_HANDLE) { - native_handle_close(handle); - native_handle_delete(const_cast<native_handle_t*>(handle)); + native_handle_close(inHandle); + native_handle_delete(const_cast<native_handle_t*>(inHandle)); } - handle = importedHandle; - mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts); + inHandle = importedHandle; + mBufferMapper.getTransportSize(inHandle, &mTransportNumFds, &mTransportNumInts); } - ANativeWindowBuffer::handle = handle; + ANativeWindowBuffer::handle = inHandle; return NO_ERROR; } -status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr) -{ +status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { const Rect lockBounds(width, height); - status_t res = lock(inUsage, lockBounds, vaddr); + status_t res = lock(inUsage, lockBounds, vaddr, outBytesPerPixel, outBytesPerStride); return res; } -status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr) -{ +status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { if (rect.left < 0 || rect.right > width || rect.top < 0 || rect.bottom > height) { ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", @@ -247,7 +275,10 @@ status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr) width, height); return BAD_VALUE; } - status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr); + + status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr, outBytesPerPixel, + outBytesPerStride); + return res; } @@ -278,22 +309,22 @@ status_t GraphicBuffer::unlock() return res; } -status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd) -{ +status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { const Rect lockBounds(width, height); - status_t res = lockAsync(inUsage, lockBounds, vaddr, fenceFd); + status_t res = + lockAsync(inUsage, lockBounds, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); return res; } -status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect, - void** vaddr, int fenceFd) -{ - return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd); +status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { + return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); } -status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, - uint64_t inConsumerUsage, const Rect& rect, void** vaddr, int fenceFd) -{ +status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, + const Rect& rect, void** vaddr, int fenceFd, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { if (rect.left < 0 || rect.right > width || rect.top < 0 || rect.bottom > height) { ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", @@ -301,8 +332,10 @@ status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, width, height); return BAD_VALUE; } - status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, - inConsumerUsage, rect, vaddr, fenceFd); + + status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, inConsumerUsage, rect, + vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); + return res; } @@ -334,15 +367,37 @@ status_t GraphicBuffer::unlockAsync(int *fenceFd) return res; } +status_t GraphicBuffer::isSupported(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, + uint32_t inLayerCount, uint64_t inUsage, + bool* outSupported) const { + return mBufferMapper.isSupported(inWidth, inHeight, inFormat, inLayerCount, inUsage, + outSupported); +} + size_t GraphicBuffer::getFlattenedSize() const { +#ifndef LIBUI_IN_VNDK + if (mBufferHubBuffer != nullptr) { + return 48; + } +#endif return static_cast<size_t>(13 + (handle ? mTransportNumInts : 0)) * sizeof(int); } size_t GraphicBuffer::getFdCount() const { +#ifndef LIBUI_IN_VNDK + if (mBufferHubBuffer != nullptr) { + return 0; + } +#endif return static_cast<size_t>(handle ? mTransportNumFds : 0); } status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { +#ifndef LIBUI_IN_VNDK + if (mBufferHubBuffer != nullptr) { + return flattenBufferHubBuffer(buffer, size); + } +#endif size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); if (size < sizeNeeded) return NO_MEMORY; @@ -369,7 +424,7 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& buf[11] = int32_t(mTransportNumInts); memcpy(fds, handle->data, static_cast<size_t>(mTransportNumFds) * sizeof(int)); memcpy(buf + 13, handle->data + handle->numFds, - static_cast<size_t>(mTransportNumInts) * sizeof(int)); + static_cast<size_t>(mTransportNumInts) * sizeof(int)); } buffer = static_cast<void*>(static_cast<uint8_t*>(buffer) + sizeNeeded); @@ -378,14 +433,13 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& fds += mTransportNumFds; count -= static_cast<size_t>(mTransportNumFds); } - return NO_ERROR; } -status_t GraphicBuffer::unflatten( - void const*& buffer, size_t& size, int const*& fds, size_t& count) { - if (size < 12 * sizeof(int)) { - android_errorWriteLog(0x534e4554, "114223584"); +status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& fds, + size_t& count) { + // Check if size is not smaller than buf[0] is supposed to take. + if (size < sizeof(int)) { return NO_MEMORY; } @@ -400,10 +454,21 @@ status_t GraphicBuffer::unflatten( } else if (buf[0] == 'GBFR') { // old version, when usage bits were 32-bits flattenWordCount = 12; + } else if (buf[0] == 'BHBB') { // BufferHub backed buffer. +#ifndef LIBUI_IN_VNDK + return unflattenBufferHubBuffer(buffer, size); +#else + return BAD_TYPE; +#endif } else { return BAD_TYPE; } + if (size < 12 * sizeof(int)) { + android_errorWriteLog(0x534e4554, "114223584"); + return NO_MEMORY; + } + const size_t numFds = static_cast<size_t>(buf[10]); const size_t numInts = static_cast<size_t>(buf[11]); @@ -416,7 +481,7 @@ status_t GraphicBuffer::unflatten( width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", numFds, numInts); return BAD_VALUE; } @@ -444,13 +509,13 @@ status_t GraphicBuffer::unflatten( } else { usage = uint64_t(usage_deprecated); } - native_handle* h = native_handle_create( - static_cast<int>(numFds), static_cast<int>(numInts)); + native_handle* h = + native_handle_create(static_cast<int>(numFds), static_cast<int>(numInts)); if (!h) { width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; ALOGE("unflatten: native_handle_create failed"); return NO_MEMORY; } @@ -461,7 +526,7 @@ status_t GraphicBuffer::unflatten( width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; } mId = static_cast<uint64_t>(buf[7]) << 32; @@ -471,7 +536,7 @@ status_t GraphicBuffer::unflatten( mOwner = ownHandle; - if (handle != 0) { + if (handle != nullptr) { buffer_handle_t importedHandle; status_t err = mBufferMapper.importBuffer(handle, uint32_t(width), uint32_t(height), uint32_t(layerCount), format, usage, uint32_t(stride), &importedHandle); @@ -479,7 +544,7 @@ status_t GraphicBuffer::unflatten( width = height = stride = format = usage_deprecated = 0; layerCount = 0; usage = 0; - handle = NULL; + handle = nullptr; ALOGE("unflatten: registerBuffer failed: %s (%d)", strerror(-err), err); return err; } @@ -494,27 +559,82 @@ status_t GraphicBuffer::unflatten( size -= sizeNeeded; fds += numFds; count -= numFds; - return NO_ERROR; } -bool GraphicBuffer::isDetachedBuffer() const { - return mDetachedBufferHandle && mDetachedBufferHandle->isValid(); +void GraphicBuffer::addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context) { + mDeathCallbacks.emplace_back(deathCallback, context); } -status_t GraphicBuffer::setDetachedBufferHandle(std::unique_ptr<DetachedBufferHandle> channel) { - if (isDetachedBuffer()) { - ALOGW("setDetachedBuffer: there is already a BufferHub channel associated with this " - "GraphicBuffer. Replacing the old one."); +#ifndef LIBUI_IN_VNDK +status_t GraphicBuffer::flattenBufferHubBuffer(void*& buffer, size_t& size) const { + sp<NativeHandle> tokenHandle = mBufferHubBuffer->duplicate(); + if (tokenHandle == nullptr || tokenHandle->handle() == nullptr || + tokenHandle->handle()->numFds != 0) { + return BAD_VALUE; + } + + // Size needed for one label, one number of ints inside the token, one generation number and + // the token itself. + int numIntsInToken = tokenHandle->handle()->numInts; + const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); + if (size < sizeNeeded) { + ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, + static_cast<int>(sizeNeeded), static_cast<int>(size)); + return NO_MEMORY; + } + size -= sizeNeeded; + + int* buf = static_cast<int*>(buffer); + buf[0] = 'BHBB'; + buf[1] = numIntsInToken; + memcpy(buf + 2, tokenHandle->handle()->data, static_cast<size_t>(numIntsInToken) * sizeof(int)); + buf[2 + numIntsInToken] = static_cast<int32_t>(mGenerationNumber); + + return NO_ERROR; +} + +status_t GraphicBuffer::unflattenBufferHubBuffer(void const*& buffer, size_t& size) { + const int* buf = static_cast<const int*>(buffer); + int numIntsInToken = buf[1]; + // Size needed for one label, one number of ints inside the token, one generation number and + // the token itself. + const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); + if (size < sizeNeeded) { + ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, + static_cast<int>(sizeNeeded), static_cast<int>(size)); + return NO_MEMORY; + } + size -= sizeNeeded; + native_handle_t* importToken = native_handle_create(/*numFds=*/0, /*numInts=*/numIntsInToken); + memcpy(importToken->data, buf + 2, static_cast<size_t>(buf[1]) * sizeof(int)); + sp<NativeHandle> importTokenHandle = NativeHandle::create(importToken, /*ownHandle=*/true); + std::unique_ptr<BufferHubBuffer> bufferHubBuffer = BufferHubBuffer::import(importTokenHandle); + if (bufferHubBuffer == nullptr || bufferHubBuffer.get() == nullptr) { + return BAD_VALUE; + } + // Reconstruct this GraphicBuffer object using the new BufferHubBuffer object. + if (handle) { + free_handle(); } + mId = 0; + mGenerationNumber = static_cast<uint32_t>(buf[2 + numIntsInToken]); + mInitCheck = + initWithHandle(bufferHubBuffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, + bufferHubBuffer->desc().width, bufferHubBuffer->desc().height, + static_cast<PixelFormat>(bufferHubBuffer->desc().format), + bufferHubBuffer->desc().layers, bufferHubBuffer->desc().usage, + bufferHubBuffer->desc().stride); + mBufferId = bufferHubBuffer->id(); + mBufferHubBuffer.reset(std::move(bufferHubBuffer.get())); - mDetachedBufferHandle = std::move(channel); return NO_ERROR; } -std::unique_ptr<DetachedBufferHandle> GraphicBuffer::takeDetachedBufferHandle() { - return std::move(mDetachedBufferHandle); +bool GraphicBuffer::isBufferHubBuffer() const { + return mBufferHubBuffer != nullptr; } +#endif // LIBUI_IN_VNDK // --------------------------------------------------------------------------- diff --git a/libshims/ui/GraphicBufferAllocator.cpp b/libshims/ui/GraphicBufferAllocator.cpp index 3806a8d..0861a1f 100644 --- a/libshims/ui/GraphicBufferAllocator.cpp +++ b/libshims/ui/GraphicBufferAllocator.cpp @@ -24,79 +24,82 @@ #include <grallocusage/GrallocUsageConversion.h> +#include <android-base/stringprintf.h> #include <log/log.h> #include <utils/Singleton.h> -#include <utils/String8.h> #include <utils/Trace.h> +#include <ui/Gralloc.h> #include <ui/Gralloc2.h> +#include <ui/Gralloc3.h> #include <ui/GraphicBufferMapper.h> namespace android { // --------------------------------------------------------------------------- +using base::StringAppendF; + ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator ) Mutex GraphicBufferAllocator::sLock; KeyedVector<buffer_handle_t, GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList; -GraphicBufferAllocator::GraphicBufferAllocator() - : mAllocDev(0) -{ - hw_module_t const* module; - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); - if (err == 0) { - gralloc_open(module, &mAllocDev); +GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) { + mAllocator = std::make_unique<const Gralloc3Allocator>( + reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper())); + if (!mAllocator->isLoaded()) { + mAllocator = std::make_unique<const Gralloc2Allocator>( + reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper())); + } + + if (!mAllocator->isLoaded()) { + LOG_ALWAYS_FATAL("gralloc-allocator is missing"); } } -GraphicBufferAllocator::~GraphicBufferAllocator() -{ - gralloc_close(mAllocDev); +GraphicBufferAllocator::~GraphicBufferAllocator() {} + +size_t GraphicBufferAllocator::getTotalSize() const { + Mutex::Autolock _l(sLock); + size_t total = 0; + for (size_t i = 0; i < sAllocList.size(); ++i) { + total += sAllocList.valueAt(i).size; + } + return total; } -void GraphicBufferAllocator::dump(String8& result) const -{ +void GraphicBufferAllocator::dump(std::string& result) const { Mutex::Autolock _l(sLock); KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); size_t total = 0; - const size_t SIZE = 4096; - char buffer[SIZE]; - snprintf(buffer, SIZE, "Allocated buffers:\n"); - result.append(buffer); + result.append("Allocated buffers:\n"); const size_t c = list.size(); for (size_t i=0 ; i<c ; i++) { const alloc_rec_t& rec(list.valueAt(i)); if (rec.size) { - snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 - " | %s\n", - list.keyAt(i), rec.size/1024.0, - rec.width, rec.stride, rec.height, rec.layerCount, rec.format, - rec.usage, rec.requestorName.c_str()); + StringAppendF(&result, + "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 " | %s\n", + list.keyAt(i), rec.size / 1024.0, rec.width, rec.stride, rec.height, + rec.layerCount, rec.format, rec.usage, rec.requestorName.c_str()); } else { - snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 - " | %s\n", - list.keyAt(i), - rec.width, rec.stride, rec.height, rec.layerCount, rec.format, - rec.usage, rec.requestorName.c_str()); + StringAppendF(&result, + "%10p: unknown | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64 " | %s\n", + list.keyAt(i), rec.width, rec.stride, rec.height, rec.layerCount, + rec.format, rec.usage, rec.requestorName.c_str()); } - result.append(buffer); total += rec.size; } - snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0); - result.append(buffer); + StringAppendF(&result, "Total allocated (estimate): %.2f KB\n", total / 1024.0); - std::string deviceDump = mAllocator->dumpDebugInfo(); - result.append(deviceDump.c_str(), deviceDump.size()); + result.append(mAllocator->dumpDebugInfo()); } void GraphicBufferAllocator::dumpToSystemLog() { - String8 s; + std::string s; GraphicBufferAllocator::getInstance().dump(s); - ALOGD("%s", s.string()); + ALOGD("%s", s.c_str()); } status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, @@ -115,15 +118,12 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, if (layerCount < 1) layerCount = 1; - Gralloc2::IMapper::BufferDescriptorInfo info = {}; - info.width = width; - info.height = height; - info.layerCount = layerCount; - info.format = static_cast<Gralloc2::PixelFormat>(format); - info.usage = usage; + // TODO(b/72323293, b/72703005): Remove these invalid bits from callers + usage &= ~static_cast<uint64_t>((1 << 10) | (1 << 13)); - Gralloc2::Error error = mAllocator->allocate(info, stride, handle); - if (error == Gralloc2::Error::NONE) { + status_t error = + mAllocator->allocate(width, height, format, layerCount, usage, 1, stride, handle); + if (error == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); uint32_t bpp = bytesPerPixel(format); @@ -150,18 +150,17 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, status_t GraphicBufferAllocator::free(buffer_handle_t handle) { - status_t err; + ATRACE_CALL(); - err = mAllocDev->free(mAllocDev, handle); + // We allocated a buffer from the allocator and imported it into the + // mapper to get the handle. We just need to free the handle now. + mMapper.freeBuffer(handle); - ALOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); - list.removeItem(handle); - } + Mutex::Autolock _l(sLock); + KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); + list.removeItem(handle); - return err; + return NO_ERROR; } // --------------------------------------------------------------------------- diff --git a/libshims/ui/GraphicBufferMapper.cpp b/libshims/ui/GraphicBufferMapper.cpp index 2d8e582..25b7247 100644 --- a/libshims/ui/GraphicBufferMapper.cpp +++ b/libshims/ui/GraphicBufferMapper.cpp @@ -32,7 +32,9 @@ #include <utils/Log.h> #include <utils/Trace.h> +#include <ui/Gralloc.h> #include <ui/Gralloc2.h> +#include <ui/Gralloc3.h> #include <ui/GraphicBuffer.h> #include <system/graphics.h> @@ -43,12 +45,22 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper ) void GraphicBufferMapper::preloadHal() { - Gralloc2::Mapper::preload(); + Gralloc2Mapper::preload(); + Gralloc3Mapper::preload(); } -GraphicBufferMapper::GraphicBufferMapper() - : mMapper(std::make_unique<const Gralloc2::Mapper>()) -{ +GraphicBufferMapper::GraphicBufferMapper() { + mMapper = std::make_unique<const Gralloc3Mapper>(); + if (!mMapper->isLoaded()) { + mMapper = std::make_unique<const Gralloc2Mapper>(); + mMapperVersion = Version::GRALLOC_2; + } else { + mMapperVersion = Version::GRALLOC_3; + } + + if (!mMapper->isLoaded()) { + LOG_ALWAYS_FATAL("gralloc-mapper is missing"); + } } status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle, @@ -59,22 +71,15 @@ status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle, ATRACE_CALL(); buffer_handle_t bufferHandle; - Gralloc2::Error error = mMapper->importBuffer( - hardware::hidl_handle(rawHandle), &bufferHandle); - if (error != Gralloc2::Error::NONE) { + status_t error = mMapper->importBuffer(hardware::hidl_handle(rawHandle), &bufferHandle); + if (error != NO_ERROR) { ALOGW("importBuffer(%p) failed: %d", rawHandle, error); - return static_cast<status_t>(error); + return error; } - Gralloc2::IMapper::BufferDescriptorInfo info = {}; - info.width = width; - info.height = height; - info.layerCount = layerCount; - info.format = static_cast<Gralloc2::PixelFormat>(format); - info.usage = usage; - - error = mMapper->validateBufferSize(bufferHandle, info, stride); - if (error != Gralloc2::Error::NONE) { + error = mMapper->validateBufferSize(bufferHandle, width, height, format, layerCount, usage, + stride); + if (error != NO_ERROR) { ALOGE("validateBufferSize(%p) failed: %d", rawHandle, error); freeBuffer(bufferHandle); return static_cast<status_t>(error); @@ -100,19 +105,10 @@ status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle) return NO_ERROR; } -static inline Gralloc2::IMapper::Rect asGralloc2Rect(const Rect& rect) { - Gralloc2::IMapper::Rect outRect{}; - outRect.left = rect.left; - outRect.top = rect.top; - outRect.width = rect.width(); - outRect.height = rect.height(); - return outRect; -} - -status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, - const Rect& bounds, void** vaddr) -{ - return lockAsync(handle, usage, bounds, vaddr, -1); +status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + void** vaddr, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { + return lockAsync(handle, usage, bounds, vaddr, -1, outBytesPerPixel, outBytesPerStride); } status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage, @@ -132,27 +128,23 @@ status_t GraphicBufferMapper::unlock(buffer_handle_t handle) return error; } -status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, - uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd) -{ - return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd); +status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds, + void** vaddr, int fenceFd, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { + return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd, outBytesPerPixel, + outBytesPerStride); } -status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, - uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds, - void** vaddr, int fenceFd) -{ +status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint64_t producerUsage, + uint64_t consumerUsage, const Rect& bounds, void** vaddr, + int fenceFd, int32_t* outBytesPerPixel, + int32_t* outBytesPerStride) { ATRACE_CALL(); const uint64_t usage = static_cast<uint64_t>( android_convertGralloc1To0Usage(producerUsage, consumerUsage)); - Gralloc2::Error error = mMapper->lock(handle, usage, - asGralloc2Rect(bounds), fenceFd, vaddr); - - ALOGW_IF(error != Gralloc2::Error::NONE, "lock(%p, ...) failed: %d", - handle, error); - - return static_cast<status_t>(error); + return mMapper->lock(handle, usage, bounds, fenceFd, vaddr, outBytesPerPixel, + outBytesPerStride); } status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, @@ -160,19 +152,7 @@ status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle, { ATRACE_CALL(); - Gralloc2::YCbCrLayout layout; - Gralloc2::Error error = mMapper->lock(handle, usage, - asGralloc2Rect(bounds), fenceFd, &layout); - if (error == Gralloc2::Error::NONE) { - ycbcr->y = layout.y; - ycbcr->cb = layout.cb; - ycbcr->cr = layout.cr; - ycbcr->ystride = static_cast<size_t>(layout.yStride); - ycbcr->cstride = static_cast<size_t>(layout.cStride); - ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep); - } - - return static_cast<status_t>(error); + return mMapper->lock(handle, usage, bounds, fenceFd, ycbcr); } status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd) @@ -184,5 +164,10 @@ status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd) return NO_ERROR; } +status_t GraphicBufferMapper::isSupported(uint32_t width, uint32_t height, + android::PixelFormat format, uint32_t layerCount, + uint64_t usage, bool* outSupported) { + return mMapper->isSupported(width, height, format, layerCount, usage, outSupported); +} // --------------------------------------------------------------------------- }; // namespace android diff --git a/libshims/utils/Looper.cpp b/libshims/utils/Looper.cpp index 6c57b2e..2d696eb 100644 --- a/libshims/utils/Looper.cpp +++ b/libshims/utils/Looper.cpp @@ -29,7 +29,7 @@ WeakMessageHandler::~WeakMessageHandler() { void WeakMessageHandler::handleMessage(const Message& message) { sp<MessageHandler> handler = mHandler.promote(); - if (handler != NULL) { + if (handler != nullptr) { handler->handleMessage(message); } } @@ -51,43 +51,38 @@ int SimpleLooperCallback::handleEvent(int fd, int events, void* data) { // --- Looper --- -// Hint for number of file descriptors to be associated with the epoll instance. -static const int EPOLL_SIZE_HINT = 8; - // Maximum number of file descriptors for which to retrieve poll events each iteration. static const int EPOLL_MAX_EVENTS = 16; static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; static pthread_key_t gTLSKey = 0; -Looper::Looper(bool allowNonCallbacks) : - mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), - mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false), - mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { - mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s", - strerror(errno)); +Looper::Looper(bool allowNonCallbacks) + : mAllowNonCallbacks(allowNonCallbacks), + mSendingMessage(false), + mPolling(false), + mEpollRebuildRequired(false), + mNextRequestSeq(0), + mResponseIndex(0), + mNextMessageUptime(LLONG_MAX) { + mWakeEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC)); + LOG_ALWAYS_FATAL_IF(mWakeEventFd.get() < 0, "Could not make wake event fd: %s", strerror(errno)); AutoMutex _l(mLock); rebuildEpollLocked(); } Looper::~Looper() { - close(mWakeEventFd); - mWakeEventFd = -1; - if (mEpollFd >= 0) { - close(mEpollFd); - } } void Looper::initTLSKey() { - int result = pthread_key_create(& gTLSKey, threadDestructor); - LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); + int error = pthread_key_create(&gTLSKey, threadDestructor); + LOG_ALWAYS_FATAL_IF(error != 0, "Could not allocate TLS key: %s", strerror(error)); } void Looper::threadDestructor(void *st) { Looper* const self = static_cast<Looper*>(st); - if (self != NULL) { + if (self != nullptr) { self->decStrong((void*)threadDestructor); } } @@ -95,13 +90,13 @@ void Looper::threadDestructor(void *st) { void Looper::setForThread(const sp<Looper>& looper) { sp<Looper> old = getForThread(); // also has side-effect of initializing TLS - if (looper != NULL) { + if (looper != nullptr) { looper->incStrong((void*)threadDestructor); } pthread_setspecific(gTLSKey, looper.get()); - if (old != NULL) { + if (old != nullptr) { old->decStrong((void*)threadDestructor); } } @@ -116,7 +111,7 @@ sp<Looper> Looper::getForThread() { sp<Looper> Looper::prepare(int opts) { bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS; sp<Looper> looper = Looper::getForThread(); - if (looper == NULL) { + if (looper == nullptr) { looper = new Looper(allowNonCallbacks); Looper::setForThread(looper); } @@ -137,18 +132,18 @@ void Looper::rebuildEpollLocked() { #if DEBUG_CALLBACKS ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this); #endif - close(mEpollFd); + mEpollFd.reset(); } // Allocate the new epoll instance and register the wake pipe. - mEpollFd = epoll_create(EPOLL_SIZE_HINT); + mEpollFd.reset(epoll_create1(EPOLL_CLOEXEC)); LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno)); struct epoll_event eventItem; memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union eventItem.events = EPOLLIN; - eventItem.data.fd = mWakeEventFd; - int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem); + eventItem.data.fd = mWakeEventFd.get(); + int result = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mWakeEventFd.get(), &eventItem); LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s", strerror(errno)); @@ -157,7 +152,7 @@ void Looper::rebuildEpollLocked() { struct epoll_event eventItem; request.initEventItem(&eventItem); - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem); + int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, request.fd, &eventItem); if (epollResult < 0) { ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s", request.fd, strerror(errno)); @@ -190,9 +185,9 @@ int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outDa "fd=%d, events=0x%x, data=%p", this, ident, fd, events, data); #endif - if (outFd != NULL) *outFd = fd; - if (outEvents != NULL) *outEvents = events; - if (outData != NULL) *outData = data; + if (outFd != nullptr) *outFd = fd; + if (outEvents != nullptr) *outEvents = events; + if (outData != nullptr) *outData = data; return ident; } } @@ -201,9 +196,9 @@ int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outDa #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - returning result %d", this, result); #endif - if (outFd != NULL) *outFd = 0; - if (outEvents != NULL) *outEvents = 0; - if (outData != NULL) *outData = NULL; + if (outFd != nullptr) *outFd = 0; + if (outEvents != nullptr) *outEvents = 0; + if (outData != nullptr) *outData = nullptr; return result; } @@ -239,7 +234,7 @@ int Looper::pollInner(int timeoutMillis) { mPolling = true; struct epoll_event eventItems[EPOLL_MAX_EVENTS]; - int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); + int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis); // No longer idling. mPolling = false; @@ -281,7 +276,7 @@ int Looper::pollInner(int timeoutMillis) { for (int i = 0; i < eventCount; i++) { int fd = eventItems[i].data.fd; uint32_t epollEvents = eventItems[i].events; - if (fd == mWakeEventFd) { + if (fd == mWakeEventFd.get()) { if (epollEvents & EPOLLIN) { awoken(); } else { @@ -401,11 +396,11 @@ void Looper::wake() { #endif uint64_t inc = 1; - ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t))); + ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd.get(), &inc, sizeof(uint64_t))); if (nWrite != sizeof(uint64_t)) { if (errno != EAGAIN) { - LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s", - mWakeEventFd, strerror(errno)); + LOG_ALWAYS_FATAL("Could not write wake signal to fd %d (returned %zd): %s", + mWakeEventFd.get(), nWrite, strerror(errno)); } } } @@ -416,7 +411,7 @@ void Looper::awoken() { #endif uint64_t counter; - TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t))); + TEMP_FAILURE_RETRY(read(mWakeEventFd.get(), &counter, sizeof(uint64_t))); } void Looper::pushResponse(int events, const Request& request) { @@ -427,7 +422,7 @@ void Looper::pushResponse(int events, const Request& request) { } int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) { - return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); + return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : nullptr, data); } int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) { @@ -467,14 +462,14 @@ int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callb ssize_t requestIndex = mRequests.indexOfKey(fd); if (requestIndex < 0) { - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); + int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem); if (epollResult < 0) { ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno)); return -1; } mRequests.add(fd, request); } else { - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); + int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_MOD, fd, &eventItem); if (epollResult < 0) { if (errno == ENOENT) { // Tolerate ENOENT because it means that an older file descriptor was @@ -495,7 +490,7 @@ int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callb "being recycled, falling back on EPOLL_CTL_ADD: %s", this, strerror(errno)); #endif - epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); + epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem); if (epollResult < 0) { ALOGE("Error modifying or adding epoll events for fd %d: %s", fd, strerror(errno)); @@ -542,7 +537,7 @@ int Looper::removeFd(int fd, int seq) { // updating the epoll set so that we avoid accidentally leaking callbacks. mRequests.removeItemsAt(requestIndex); - int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); + int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_DEL, fd, nullptr); if (epollResult < 0) { if (seq != -1 && (errno == EBADF || errno == ENOENT)) { // Tolerate EBADF or ENOENT when the sequence number is known because it diff --git a/libshims/utils/VectorImpl.cpp b/libshims/utils/VectorImpl.cpp index 14b331b..c97a19b 100644 --- a/libshims/utils/VectorImpl.cpp +++ b/libshims/utils/VectorImpl.cpp @@ -24,8 +24,6 @@ #include <log/log.h> -#include <safe_iop.h> - #include "SharedBuffer.h" /*****************************************************************************/ @@ -44,7 +42,7 @@ static inline size_t max(size_t a, size_t b) { // ---------------------------------------------------------------------------- VectorImpl::VectorImpl(size_t itemSize, uint32_t flags) - : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize) + : mStorage(nullptr), mCount(0), mFlags(flags), mItemSize(itemSize) { } @@ -77,7 +75,7 @@ VectorImpl& VectorImpl::operator = (const VectorImpl& rhs) mCount = rhs.mCount; SharedBuffer::bufferFromData(mStorage)->acquire(); } else { - mStorage = 0; + mStorage = nullptr; mCount = 0; } } @@ -89,14 +87,14 @@ void* VectorImpl::editArrayImpl() if (mStorage) { const SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage); SharedBuffer* editable = sb->attemptEdit(); - if (editable == 0) { + if (editable == nullptr) { // If we're here, we're not the only owner of the buffer. // We must make a copy of it. editable = SharedBuffer::alloc(sb->size()); // Fail instead of returning a pointer to storage that's not // editable. Otherwise we'd be editing the contents of a buffer // for which we're not the only owner, which is undefined behaviour. - LOG_ALWAYS_FATAL_IF(editable == NULL); + LOG_ALWAYS_FATAL_IF(editable == nullptr); _do_copy(editable->data(), mStorage, mCount); release_storage(); mStorage = editable->data(); @@ -141,7 +139,7 @@ ssize_t VectorImpl::appendArray(const void* array, size_t length) ssize_t VectorImpl::insertAt(size_t index, size_t numItems) { - return insertAt(0, index, numItems); + return insertAt(nullptr, index, numItems); } ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems) @@ -177,7 +175,7 @@ status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state) const ssize_t count = size(); if (count > 1) { void* array = const_cast<void*>(arrayImpl()); - void* temp = 0; + void* temp = nullptr; ssize_t i = 1; while (i < count) { void* item = reinterpret_cast<char*>(array) + mItemSize*(i); @@ -205,7 +203,7 @@ status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state) _do_copy(next, curr, 1); next = curr; --j; - curr = NULL; + curr = nullptr; if (j >= 0) { curr = reinterpret_cast<char*>(array) + mItemSize*(j); } @@ -222,7 +220,7 @@ status_t VectorImpl::sort(VectorImpl::compar_r_t cmp, void* state) free(temp); } } - return NO_ERROR; + return OK; } void VectorImpl::pop() @@ -233,7 +231,7 @@ void VectorImpl::pop() void VectorImpl::push() { - push(0); + push(nullptr); } void VectorImpl::push(const void* item) @@ -243,7 +241,7 @@ void VectorImpl::push(const void* item) ssize_t VectorImpl::add() { - return add(0); + return add(nullptr); } ssize_t VectorImpl::add(const void* item) @@ -253,7 +251,7 @@ ssize_t VectorImpl::add(const void* item) ssize_t VectorImpl::replaceAt(size_t index) { - return replaceAt(0, index); + return replaceAt(nullptr, index); } ssize_t VectorImpl::replaceAt(const void* prototype, size_t index) @@ -267,10 +265,10 @@ ssize_t VectorImpl::replaceAt(const void* prototype, size_t index) void* item = editItemLocation(index); if (item != prototype) { - if (item == 0) + if (item == nullptr) return NO_MEMORY; _do_destroy(item, 1); - if (prototype == 0) { + if (prototype == nullptr) { _do_construct(item, 1); } else { _do_copy(item, prototype, 1); @@ -294,7 +292,7 @@ ssize_t VectorImpl::removeItemsAt(size_t index, size_t count) void VectorImpl::finish_vector() { release_storage(); - mStorage = 0; + mStorage = nullptr; mCount = 0; } @@ -315,7 +313,7 @@ void* VectorImpl::editItemLocation(size_t index) return reinterpret_cast<char*>(buffer) + index*mItemSize; } } - return 0; + return nullptr; } const void* VectorImpl::itemLocation(size_t index) const @@ -330,7 +328,7 @@ const void* VectorImpl::itemLocation(size_t index) const return reinterpret_cast<const char*>(buffer) + index*mItemSize; } } - return 0; + return nullptr; } ssize_t VectorImpl::setCapacity(size_t new_capacity) @@ -342,7 +340,7 @@ ssize_t VectorImpl::setCapacity(size_t new_capacity) } size_t new_allocation_size = 0; - LOG_ALWAYS_FATAL_IF(!safe_mul(&new_allocation_size, new_capacity, mItemSize)); + LOG_ALWAYS_FATAL_IF(__builtin_mul_overflow(new_capacity, mItemSize, &new_allocation_size)); SharedBuffer* sb = SharedBuffer::alloc(new_allocation_size); if (sb) { void* array = sb->data(); @@ -356,7 +354,7 @@ ssize_t VectorImpl::setCapacity(size_t new_capacity) } ssize_t VectorImpl::resize(size_t size) { - ssize_t result = NO_ERROR; + ssize_t result = OK; if (size > mCount) { result = insertAt(mCount, size - mCount); } else if (size < mCount) { @@ -386,7 +384,7 @@ void* VectorImpl::_grow(size_t where, size_t amount) this, (int)where, (int)amount, (int)mCount); // caller already checked size_t new_size; - LOG_ALWAYS_FATAL_IF(!safe_add(&new_size, mCount, amount), "new_size overflow"); + LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(mCount, amount, &new_size), "new_size overflow"); if (capacity() < new_size) { // NOTE: This implementation used to resize vectors as per ((3*x + 1) / 2) @@ -397,17 +395,18 @@ void* VectorImpl::_grow(size_t where, size_t amount) // // This approximates the old calculation, using (x + (x/2) + 1) instead. size_t new_capacity = 0; - LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_size, (new_size / 2)), - "new_capacity overflow"); - LOG_ALWAYS_FATAL_IF(!safe_add(&new_capacity, new_capacity, static_cast<size_t>(1u)), + LOG_ALWAYS_FATAL_IF(__builtin_add_overflow(new_size, (new_size / 2), &new_capacity), "new_capacity overflow"); + LOG_ALWAYS_FATAL_IF( + __builtin_add_overflow(new_capacity, static_cast<size_t>(1u), &new_capacity), + "new_capacity overflow"); new_capacity = max(kMinVectorCapacity, new_capacity); size_t new_alloc_size = 0; - LOG_ALWAYS_FATAL_IF(!safe_mul(&new_alloc_size, new_capacity, mItemSize), + LOG_ALWAYS_FATAL_IF(__builtin_mul_overflow(new_capacity, mItemSize, &new_alloc_size), "new_alloc_size overflow"); -// ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); + // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); if ((mStorage) && (mCount==where) && (mFlags & HAS_TRIVIAL_COPY) && @@ -418,7 +417,7 @@ void* VectorImpl::_grow(size_t where, size_t amount) if (sb) { mStorage = sb->data(); } else { - return NULL; + return nullptr; } } else { SharedBuffer* sb = SharedBuffer::alloc(new_alloc_size); @@ -435,7 +434,7 @@ void* VectorImpl::_grow(size_t where, size_t amount) release_storage(); mStorage = const_cast<void*>(array); } else { - return NULL; + return nullptr; } } } else { @@ -464,7 +463,7 @@ void VectorImpl::_shrink(size_t where, size_t amount) this, (int)where, (int)amount, (int)mCount); // caller already checked size_t new_size; - LOG_ALWAYS_FATAL_IF(!safe_sub(&new_size, mCount, amount)); + LOG_ALWAYS_FATAL_IF(__builtin_sub_overflow(mCount, amount, &new_size)); if (new_size < (capacity() / 2)) { // NOTE: (new_size * 2) is safe because capacity didn't overflow and @@ -556,15 +555,6 @@ void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) con do_move_backward(dest, from, num); } -void VectorImpl::reservedVectorImpl1() { } -void VectorImpl::reservedVectorImpl2() { } -void VectorImpl::reservedVectorImpl3() { } -void VectorImpl::reservedVectorImpl4() { } -void VectorImpl::reservedVectorImpl5() { } -void VectorImpl::reservedVectorImpl6() { } -void VectorImpl::reservedVectorImpl7() { } -void VectorImpl::reservedVectorImpl8() { } - /*****************************************************************************/ SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags) @@ -654,13 +644,13 @@ ssize_t SortedVectorImpl::merge(const VectorImpl& vector) } } } - return NO_ERROR; + return OK; } ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector) { // we've merging a sorted vector... nice! - ssize_t err = NO_ERROR; + ssize_t err = OK; if (!vector.isEmpty()) { // first take care of the case where the vectors are sorted together if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) { @@ -684,15 +674,6 @@ ssize_t SortedVectorImpl::remove(const void* item) return i; } -void SortedVectorImpl::reservedSortedVectorImpl1() { }; -void SortedVectorImpl::reservedSortedVectorImpl2() { }; -void SortedVectorImpl::reservedSortedVectorImpl3() { }; -void SortedVectorImpl::reservedSortedVectorImpl4() { }; -void SortedVectorImpl::reservedSortedVectorImpl5() { }; -void SortedVectorImpl::reservedSortedVectorImpl6() { }; -void SortedVectorImpl::reservedSortedVectorImpl7() { }; -void SortedVectorImpl::reservedSortedVectorImpl8() { }; - /*****************************************************************************/ }; // namespace android |