aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core/SkMallocPixelRef.h
blob: 2e4c4e69ebefb3963221d22f639e4e993c57418b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * Copyright 2008 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkMallocPixelRef_DEFINED
#define SkMallocPixelRef_DEFINED

#include "SkPixelRef.h"

/** We explicitly use the same allocator for our pixels that SkMask does,
    so that we can freely assign memory allocated by one class to the other.
*/
class SK_API SkMallocPixelRef : public SkPixelRef {
public:
    /**
     *  Return a new SkMallocPixelRef with the provided pixel storage, rowBytes,
     *  and optional colortable. The caller is responsible for managing the
     *  lifetime of the pixel storage buffer, as this pixelref will not try
     *  to delete it.
     *
     *  Returns NULL on failure.
     */
    static sk_sp<SkPixelRef> MakeDirect(const SkImageInfo&, void* addr,
                                       size_t rowBytes, sk_sp<SkColorTable>);

    /**
     *  Return a new SkMallocPixelRef, automatically allocating storage for the
     *  pixels. If rowBytes are 0, an optimal value will be chosen automatically.
     *  If rowBytes is > 0, then it will be respected, or NULL will be returned
     *  if rowBytes is invalid for the specified info.
     *
     *  This pixelref will ref() the specified colortable (if not NULL).
     *
     *  Returns NULL on failure.
     */
    static sk_sp<SkPixelRef> MakeAllocate(const SkImageInfo&, size_t rowBytes, sk_sp<SkColorTable>);

    /**
     *  Identical to MakeAllocate, except all pixel bytes are zeroed.
     */
    static sk_sp<SkPixelRef> MakeZeroed(const SkImageInfo&, size_t rowBytes, sk_sp<SkColorTable>);

    /**
     *  Return a new SkMallocPixelRef with the provided pixel storage,
     *  rowBytes, and optional colortable. On destruction, ReleaseProc
     *  will be called.
     *
     *  If ReleaseProc is NULL, the pixels will never be released. This
     *  can be useful if the pixels were stack allocated. However, such an
     *  SkMallocPixelRef must not live beyond its pixels (e.g. by copying
     *  an SkBitmap pointing to it, or drawing to an SkPicture).
     *
     *  Returns NULL on failure.
     */
    typedef void (*ReleaseProc)(void* addr, void* context);
    static sk_sp<SkPixelRef> MakeWithProc(const SkImageInfo& info,
                                          size_t rowBytes, sk_sp<SkColorTable>,
                                          void* addr, ReleaseProc proc,
                                          void* context);

    /**
     *  Return a new SkMallocPixelRef that will use the provided
     *  SkData, rowBytes, and optional colortable as pixel storage.
     *  The SkData will be ref()ed and on destruction of the PielRef,
     *  the SkData will be unref()ed.
     *
     *  Returns NULL on failure.
     */
    static sk_sp<SkPixelRef> MakeWithData(const SkImageInfo& info,
                                          size_t rowBytes,
                                          sk_sp<SkColorTable>,
                                          sk_sp<SkData> data);
    
#ifdef SK_SUPPORT_LEGACY_PIXELREFFACTORY
    static SkMallocPixelRef* NewDirect(const SkImageInfo& info, void* addr,
                                       size_t rowBytes, SkColorTable* ctable) {
        return (SkMallocPixelRef*)MakeDirect(info, addr, rowBytes, sk_ref_sp(ctable)).release();
    }
    static SkMallocPixelRef* NewAllocate(const SkImageInfo& info, size_t rb, SkColorTable* ct) {
        return (SkMallocPixelRef*)MakeAllocate(info, rb, sk_ref_sp(ct)).release();
    }
    static SkMallocPixelRef* NewZeroed(const SkImageInfo& info, size_t rowBytes, SkColorTable* ct) {
        return (SkMallocPixelRef*)MakeZeroed(info, rowBytes, sk_ref_sp(ct)).release();
    }
    static SkMallocPixelRef* NewWithProc(const SkImageInfo& info,
                                               size_t rowBytes, SkColorTable* ctable,
                                               void* addr, ReleaseProc proc,
                                               void* ctx) {
        return (SkMallocPixelRef*)MakeWithProc(info, rowBytes, sk_ref_sp(ctable), addr, proc, ctx).release();
    }
    static SkMallocPixelRef* NewWithData(const SkImageInfo& info,
                                         size_t rowBytes,
                                         SkColorTable* ctable,
                                         SkData* data);
#endif

    void* getAddr() const { return fStorage; }

protected:
    // The ownPixels version of this constructor is deprecated.
    SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
                     bool ownPixels);
    ~SkMallocPixelRef() override;

    bool onNewLockPixels(LockRec*) override;
    void onUnlockPixels() override;
    size_t getAllocatedSizeInBytes() const override;

private:
    // Uses alloc to implement NewAllocate or NewZeroed.
    static sk_sp<SkPixelRef> MakeUsing(void*(*alloc)(size_t),
                                       const SkImageInfo&,
                                       size_t rowBytes,
                                       sk_sp<SkColorTable>);

    void*               fStorage;
    sk_sp<SkColorTable> fCTable;
    size_t              fRB;
    ReleaseProc         fReleaseProc;
    void*               fReleaseProcContext;

    SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, sk_sp<SkColorTable>,
                     ReleaseProc proc, void* context);

    typedef SkPixelRef INHERITED;
};


#endif