aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrTextureProvider.h
blob: b8d185648dd6f4b9f64a1fff90ebf5418f443e14 (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrTextureProvider_DEFINED
#define GrTextureProvider_DEFINED

#include "GrTexture.h"
#include "GrTypes.h"

class GrSingleOwner;

class SK_API GrTextureProvider {
public:
    ///////////////////////////////////////////////////////////////////////////
    // Textures

    /**
     * Creates a new texture in the resource cache and returns it. The caller owns a
     * ref on the returned texture which must be balanced by a call to unref.
     *
     * @param desc          Description of the texture properties.
     * @param budgeted      Does the texture count against the resource cache budget?
     * @param texels        A contiguous array of mipmap levels
     * @param mipLevelCount The amount of elements in the texels array
     */
    GrTexture* createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
                                      const GrMipLevel* texels, int mipLevelCount,
                                      uint32_t flags = 0);

    /**
     * This function is a shim which creates a SkTArray<GrMipLevel> of size 1.
     * It then calls createTexture with that SkTArray.
     *
     * @param srcData   Pointer to the pixel values (optional).
     * @param rowBytes  The number of bytes between rows of the texture. Zero
     *                  implies tightly packed rows. For compressed pixel configs, this
     *                  field is ignored.
     */
    GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, const void* srcData,
                             size_t rowBytes, uint32_t flags = 0);

    /** Shortcut for creating a texture with no initial data to upload. */
    GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, uint32_t flags = 0) {
        return this->createTexture(desc, budgeted, nullptr, 0, flags);
    }

    /** Assigns a unique key to the texture. The texture will be findable via this key using
        findTextureByUniqueKey(). If an existing texture has this key, it's key will be removed. */
    void assignUniqueKeyToTexture(const GrUniqueKey& key, GrTexture* texture) {
        this->assignUniqueKeyToResource(key, texture);
    }

    /** Finds a texture by unique key. If the texture is found it is ref'ed and returned. */
    GrTexture* findAndRefTextureByUniqueKey(const GrUniqueKey& key);

    /**
     * Determines whether a texture is associated with the unique key. If the texture is found it
     * will not be locked or returned. This call does not affect the priority of the resource for
     * deletion.
     */
    bool existsTextureWithUniqueKey(const GrUniqueKey& key) const {
        return this->existsResourceWithUniqueKey(key);
    }

    /**
     * Finds a texture that approximately matches the descriptor. Will be at least as large in width
     * and height as desc specifies. If desc specifies that the texture should be a render target
     * then result will be a render target. Format and sample count will always match the request.
     * The contents of the texture are undefined. The caller owns a ref on the returned texture and
     * must balance with a call to unref.
     */
    GrTexture* createApproxTexture(const GrSurfaceDesc&, uint32_t flags = 0);

    /** Legacy function that no longer should be used. */
    enum ScratchTexMatch {
        kExact_ScratchTexMatch,
        kApprox_ScratchTexMatch
    };
    GrTexture* refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match, uint32_t flags) {
        if (kApprox_ScratchTexMatch == match) {
            return this->createApproxTexture(desc, flags);
        } else {
            return this->createTexture(desc, SkBudgeted::kYes, flags);
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // Wrapped Backend Surfaces

    /**
     * Wraps an existing texture with a GrTexture object.
     *
     * OpenGL: if the object is a texture Gr may change its GL texture params
     *         when it is drawn.
     *
     * @return GrTexture object or NULL on failure.
     */
    sk_sp<GrTexture> wrapBackendTexture(const GrBackendTextureDesc& desc,
                                        GrWrapOwnership = kBorrow_GrWrapOwnership);

    /**
     * Wraps an existing render target with a GrRenderTarget object. It is
     * similar to wrapBackendTexture but can be used to draw into surfaces
     * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
     * the client will resolve to a texture). Currently wrapped render targets
     * always use the kBorrow_GrWrapOwnership semantics.
     *
     * @return GrRenderTarget object or NULL on failure.
     */
     sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);

     static const int kMinScratchTextureSize;

protected:
    GrTextureProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* singleOwner);

    /**
     * Assigns a unique key to a resource. If the key is associated with another resource that
     * association is removed and replaced by this resource.
     */
    void assignUniqueKeyToResource(const GrUniqueKey&, GrGpuResource*);

    /**
     * Finds a resource in the cache, based on the specified key. This is intended for use in
     * conjunction with addResourceToCache(). The return value will be NULL if not found. The
     * caller must balance with a call to unref().
     */
    GrGpuResource* findAndRefResourceByUniqueKey(const GrUniqueKey&);

    /**
     * Determines whether a resource is in the cache. If the resource is found it
     * will not be locked or returned. This call does not affect the priority of
     * the resource for deletion.
     */
    bool existsResourceWithUniqueKey(const GrUniqueKey& key) const;

    enum ScratchTextureFlags {
        kExact_ScratchTextureFlag           = 0x1,
        kNoPendingIO_ScratchTextureFlag     = 0x2, // (http://skbug.com/4156)
        kNoCreate_ScratchTextureFlag        = 0x4,
        kLastScratchTextureFlag = kNoCreate_ScratchTextureFlag
    };

    /** A common impl for GrTextureProvider and GrResourceProvider variants. */
    GrTexture* internalCreateApproxTexture(const GrSurfaceDesc& desc, uint32_t scratchTextureFlags);

    GrTexture* refScratchTexture(const GrSurfaceDesc&, uint32_t scratchTextureFlags);

    void abandon() {
        fCache = NULL;
        fGpu = NULL;
    }

    GrResourceCache* cache() { return fCache; }
    const GrResourceCache* cache() const { return fCache; }

    GrGpu* gpu() { return fGpu; }
    const GrGpu* gpu() const { return fGpu; }

    bool isAbandoned() const {
        SkASSERT(SkToBool(fGpu) == SkToBool(fCache));
        return !SkToBool(fCache);
    }

private:
    GrResourceCache* fCache;
    GrGpu* fGpu;

    // In debug builds we guard against improper thread handling
    SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
};

#endif