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