xref: /aosp_15_r20/external/skia/src/core/SkAutoPixmapStorage.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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