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 "SkMalloc.h"
12 #include "SkPixmap.h"
13 
14 class SkAutoPixmapStorage : public SkPixmap {
15 public:
16     SkAutoPixmapStorage();
17     ~SkAutoPixmapStorage();
18 
19     /**
20     * Leave the moved-from object in a free-but-valid state.
21     */
22     SkAutoPixmapStorage& operator=(SkAutoPixmapStorage&& other);
23 
24     /**
25     *  Try to allocate memory for the pixels needed to match the specified Info. On success
26     *  return true and fill out the pixmap to point to that memory. The storage will be freed
27     *  when this object is destroyed, or if another call to tryAlloc() or alloc() is made.
28     *
29     *  On failure, return false and reset() the pixmap to empty.
30     */
31     bool tryAlloc(const SkImageInfo&);
32 
33     /**
34     *  Allocate memory for the pixels needed to match the specified Info and fill out the pixmap
35     *  to point to that memory. The storage will be freed when this object is destroyed,
36     *  or if another call to tryAlloc() or alloc() is made.
37     *
38     *  If the memory cannot be allocated, calls SK_ABORT().
39     */
40     void alloc(const SkImageInfo&);
41 
42     /**
43     * Gets the size and optionally the rowBytes that would be allocated by SkAutoPixmapStorage if
44     * alloc/tryAlloc was called.
45     */
46     static size_t AllocSize(const SkImageInfo& info, size_t* rowBytes);
47 
48     /**
49     *  Returns an SkData object wrapping the allocated pixels memory, and resets the pixmap.
50     *  If the storage hasn't been allocated, the result is NULL.
51     */
52     const SkData* SK_WARN_UNUSED_RESULT detachPixelsAsData();
53 
54     // We wrap these so we can clear our internal storage
55 
reset()56     void reset() {
57         this->freeStorage();
58         this->INHERITED::reset();
59     }
reset(const SkImageInfo & info,const void * addr,size_t rb)60     void reset(const SkImageInfo& info, const void* addr, size_t rb) {
61         this->freeStorage();
62         this->INHERITED::reset(info, addr, rb);
63     }
64 
reset(const SkMask & mask)65     bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) {
66         this->freeStorage();
67         return this->INHERITED::reset(mask);
68     }
69 
70 private:
71     void*   fStorage;
72 
freeStorage()73     void freeStorage() {
74         sk_free(fStorage);
75         fStorage = nullptr;
76     }
77 
78     typedef SkPixmap INHERITED;
79 };
80 
81 #endif
82