blob: 1150c794a67816462758ef2f478f0d5e9a84746f [file] [log] [blame]
Robert Phillips1afd4cd2018-01-08 13:40:32 -05001/*
2 * Copyright 2018 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 GrProxyProvider_DEFINED
9#define GrProxyProvider_DEFINED
10
11#include "GrResourceKey.h"
12#include "GrTextureProxy.h"
13#include "GrTypes.h"
14#include "SkRefCnt.h"
15#include "SkTDynamicHash.h"
16
17class GrCaps;
18class GrResourceProvider;
19class GrSingleOwner;
Robert Phillips0bd24dc2018-01-16 08:06:32 -050020class GrBackendRenderTarget;
Robert Phillips1afd4cd2018-01-08 13:40:32 -050021
22/*
23 * A factory for creating GrSurfaceProxy-derived objects.
24 */
25class GrProxyProvider {
26public:
27 GrProxyProvider(GrResourceProvider*, GrResourceCache*, sk_sp<const GrCaps>, GrSingleOwner*);
28
29 ~GrProxyProvider();
30
31 /*
32 * Assigns a unique key to a proxy. The proxy will be findable via this key using
33 * findProxyByUniqueKey(). It is an error if an existing proxy already has a key.
34 */
35 void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*);
36
37 /*
38 * Sets the unique key of the provided proxy to the unique key of the surface. The surface must
39 * have a valid unique key.
40 */
41 void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*);
42
43 /*
44 * Removes a unique key from a proxy. If the proxy has already been instantiated, it will
45 * also remove the unique key from the target GrSurface.
46 */
47 void removeUniqueKeyFromProxy(const GrUniqueKey&, GrTextureProxy*);
48
49 /*
50 * Finds a proxy by unique key.
51 */
52 sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
53
54 /*
55 * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique
56 * key.
57 */
58 sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
59
60 /*
Robert Phillips0bd24dc2018-01-16 08:06:32 -050061 * Create a texture proxy that is backed by an instantiated GrSurface. This is almost entirely
62 * used by Skia's testing code.
63 * DDL TODO: remove the remaining Skia-internal use of this method and make it truly
64 * testing-only.
Robert Phillips1afd4cd2018-01-08 13:40:32 -050065 */
Robert Phillips0bd24dc2018-01-16 08:06:32 -050066 sk_sp<GrTextureProxy> createInstantiatedProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
67 uint32_t flags = 0);
68
69 /*
70 * Create an un-mipmapped texture proxy with data.
71 * DDL TODO: need to refine ownership semantics of 'srcData' if we're in completely
72 * deferred mode
73 */
74 sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted,
75 const void* srcData, size_t rowBytes);
Robert Phillips1afd4cd2018-01-08 13:40:32 -050076
77 /*
78 * Create a mipmapped texture proxy with data.
Robert Phillips0bd24dc2018-01-16 08:06:32 -050079 *
80 * @param desc Description of the texture properties.
81 * @param budgeted Does the texture count against the resource cache budget?
82 * @param texels A contiguous array of mipmap levels
83 * @param mipLevelCount The amount of elements in the texels array
Robert Phillips1afd4cd2018-01-08 13:40:32 -050084 */
Robert Phillips0bd24dc2018-01-16 08:06:32 -050085 sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, SkBudgeted,
86 const GrMipLevel texels[], int mipLevelCount,
87 SkDestinationSurfaceColorMode mipColorMode =
88 SkDestinationSurfaceColorMode::kLegacy);
89
90
91 /*
92 * Create a mipmapped texture proxy without any data.
93 *
94 * Like the call above but there are no texels to upload. A texture proxy is returned that
95 * simply has space allocated for the mips. We will allocated the full amount of mip levels
96 * based on the width and height in the GrSurfaceDesc.
97 */
98 sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, SkBudgeted);
99
100 /*
101 * Create a GrSurfaceProxy without any data.
102 */
103 sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
104 uint32_t flags = 0);
105
106 /*
107 * Create a texture proxy that wraps a (non-renderable) backend texture.
108 */
109 sk_sp<GrTextureProxy> createWrappedTextureProxy(const GrBackendTexture&, GrSurfaceOrigin);
110
111 /*
112 * Create a texture proxy that wraps a backend texture and is both texture-able and renderable
113 */
114 sk_sp<GrTextureProxy> createWrappedTextureProxy(const GrBackendTexture&,
115 GrSurfaceOrigin,
116 int sampleCnt);
117
118 /*
119 * Create a render target proxy that wraps a backend rendertarget
120 */
121 sk_sp<GrSurfaceProxy> createWrappedRenderTargetProxy(const GrBackendRenderTarget&,
122 GrSurfaceOrigin);
123
124 /*
125 * Create a render target proxy that wraps a backend texture?
126 */
127 sk_sp<GrSurfaceProxy> createWrappedRenderTargetProxy(const GrBackendTexture& tex,
128 GrSurfaceOrigin origin,
129 int sampleCnt);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500130
131 // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
132 // determine if it is going to need a texture domain or a full clear.
133 static bool IsFunctionallyExact(GrSurfaceProxy* proxy);
134
135 /**
136 * Either the proxy attached to the unique key is being deleted (in which case we
137 * don't want it cluttering up the hash table) or the client has indicated that
138 * it will never refer to the unique key again. In either case, remove the key
139 * from the hash table.
140 * Note: this does not, by itself, alter unique key attached to the underlying GrTexture.
141 */
142 void processInvalidProxyUniqueKey(const GrUniqueKey&);
143
144 /**
145 * Same as above, but you must pass in a GrTextureProxy to save having to search for it. The
146 * GrUniqueKey of the proxy must be valid and it must match the passed in key. This function
147 * also gives the option to invalidate the GrUniqueKey on the underlying GrTexture.
148 */
149 void processInvalidProxyUniqueKey(const GrUniqueKey&, GrTextureProxy*, bool invalidateSurface);
150
151 const GrCaps* caps() const { return fCaps.get(); }
152
153 void abandon() {
154 fResourceCache = nullptr;
155 fResourceProvider = nullptr;
156 }
157
158 bool isAbandoned() const {
159 SkASSERT(SkToBool(fResourceCache) == SkToBool(fResourceProvider));
160 return !SkToBool(fResourceCache);
161 }
162
163 int numUniqueKeyProxies_TestOnly() const;
164
165 void removeAllUniqueKeys();
166
167private:
168 struct UniquelyKeyedProxyHashTraits {
169 static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); }
170
171 static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); }
172 };
173 typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash;
174
175 // This holds the texture proxies that have unique keys. The resourceCache does not get a ref
176 // on these proxies but they must send a message to the resourceCache when they are deleted.
177 UniquelyKeyedProxyHash fUniquelyKeyedProxies;
178
179 GrResourceProvider* fResourceProvider;
180 GrResourceCache* fResourceCache;
181 sk_sp<const GrCaps> fCaps;
182
183 // In debug builds we guard against improper thread handling
184 SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
185};
186
187#endif