1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkAutoPixmapStorage_DEFINED 9 #define SkAutoPixmapStorage_DEFINED 10 11 #include "include/core/SkPixmap.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/private/base/SkMalloc.h" 14 15 #include <cstddef> 16 17 class SkData; 18 struct SkImageInfo; 19 struct SkMask; 20 21 class SkAutoPixmapStorage : public SkPixmap { 22 public: 23 SkAutoPixmapStorage(); 24 ~SkAutoPixmapStorage(); 25 26 SkAutoPixmapStorage(SkAutoPixmapStorage&& other); 27 28 /** 29 * Leave the moved-from object in a free-but-valid state. 30 */ 31 SkAutoPixmapStorage& operator=(SkAutoPixmapStorage&& other); 32 33 /** 34 * Try to allocate memory for the pixels needed to match the specified Info. On success 35 * return true and fill out the pixmap to point to that memory. The storage will be freed 36 * when this object is destroyed, or if another call to tryAlloc() or alloc() is made. 37 * 38 * On failure, return false and reset() the pixmap to empty. 39 */ 40 bool tryAlloc(const SkImageInfo&); 41 42 /** 43 * Allocate memory for the pixels needed to match the specified Info and fill out the pixmap 44 * to point to that memory. The storage will be freed when this object is destroyed, 45 * or if another call to tryAlloc() or alloc() is made. 46 * 47 * If the memory cannot be allocated, calls SK_ABORT(). 48 */ 49 void alloc(const SkImageInfo&); 50 51 /** 52 * Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if 53 * alloc/tryAlloc was called. 54 */ 55 static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes); 56 57 /** 58 * Returns a void* of the allocated pixel memory and resets the pixmap. If the storage hasn't 59 * been allocated, the result is NULL. The caller is responsible for calling sk_free to free 60 * the returned memory. 61 */ 62 [[nodiscard]] void* detachPixels(); 63 64 /** 65 * Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap. 66 * If the storage hasn't been allocated, the result is NULL. 67 */ 68 [[nodiscard]] sk_sp<SkData> detachPixelsAsData(); 69 70 // We wrap these so we can clear our internal storage 71 reset()72 void reset() { 73 this->freeStorage(); 74 this->INHERITED::reset(); 75 } reset(const SkImageInfo & info,const void * addr,size_t rb)76 void reset(const SkImageInfo& info, const void* addr, size_t rb) { 77 this->freeStorage(); 78 this->INHERITED::reset(info, addr, rb); 79 } 80 reset(const SkMask & mask)81 [[nodiscard]] bool reset(const SkMask& mask) { 82 this->freeStorage(); 83 return this->INHERITED::reset(mask); 84 } 85 86 private: 87 void* fStorage; 88 freeStorage()89 void freeStorage() { 90 sk_free(fStorage); 91 fStorage = nullptr; 92 } 93 94 using INHERITED = SkPixmap; 95 }; 96 97 #endif 98