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
14class SkAutoPixmapStorage : public SkPixmap {
15public:
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
56    void reset() {
57        this->freeStorage();
58        this->INHERITED::reset();
59    }
60    void reset(const SkImageInfo& info, const void* addr, size_t rb) {
61        this->freeStorage();
62        this->INHERITED::reset(info, addr, rb);
63    }
64
65    bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) {
66        this->freeStorage();
67        return this->INHERITED::reset(mask);
68    }
69
70private:
71    void*   fStorage;
72
73    void freeStorage() {
74        sk_free(fStorage);
75        fStorage = nullptr;
76    }
77
78    typedef SkPixmap INHERITED;
79};
80
81#endif
82