Robert Phillips | 1afd4cd | 2018-01-08 13:40:32 -0500 | [diff] [blame^] | 1 | /* |
| 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 | |
| 17 | class GrCaps; |
| 18 | class GrResourceProvider; |
| 19 | class GrSingleOwner; |
| 20 | |
| 21 | /* |
| 22 | * A factory for creating GrSurfaceProxy-derived objects. |
| 23 | */ |
| 24 | class GrProxyProvider { |
| 25 | public: |
| 26 | GrProxyProvider(GrResourceProvider*, GrResourceCache*, sk_sp<const GrCaps>, GrSingleOwner*); |
| 27 | |
| 28 | ~GrProxyProvider(); |
| 29 | |
| 30 | /* |
| 31 | * Assigns a unique key to a proxy. The proxy will be findable via this key using |
| 32 | * findProxyByUniqueKey(). It is an error if an existing proxy already has a key. |
| 33 | */ |
| 34 | void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*); |
| 35 | |
| 36 | /* |
| 37 | * Sets the unique key of the provided proxy to the unique key of the surface. The surface must |
| 38 | * have a valid unique key. |
| 39 | */ |
| 40 | void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*); |
| 41 | |
| 42 | /* |
| 43 | * Removes a unique key from a proxy. If the proxy has already been instantiated, it will |
| 44 | * also remove the unique key from the target GrSurface. |
| 45 | */ |
| 46 | void removeUniqueKeyFromProxy(const GrUniqueKey&, GrTextureProxy*); |
| 47 | |
| 48 | /* |
| 49 | * Finds a proxy by unique key. |
| 50 | */ |
| 51 | sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); |
| 52 | |
| 53 | /* |
| 54 | * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique |
| 55 | * key. |
| 56 | */ |
| 57 | sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin); |
| 58 | |
| 59 | /* |
| 60 | * Create an un-mipmapped texture proxy with data. |
| 61 | */ |
| 62 | sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel&); |
| 63 | |
| 64 | /* |
| 65 | * Create a mipmapped texture proxy with data. |
| 66 | */ |
| 67 | sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted, |
| 68 | const GrMipLevel texels[], int mipLevelCount, |
| 69 | SkDestinationSurfaceColorMode mipColorMode); |
| 70 | |
| 71 | // 'proxy' is about to be used as a texture src or drawn to. This query can be used to |
| 72 | // determine if it is going to need a texture domain or a full clear. |
| 73 | static bool IsFunctionallyExact(GrSurfaceProxy* proxy); |
| 74 | |
| 75 | /** |
| 76 | * Either the proxy attached to the unique key is being deleted (in which case we |
| 77 | * don't want it cluttering up the hash table) or the client has indicated that |
| 78 | * it will never refer to the unique key again. In either case, remove the key |
| 79 | * from the hash table. |
| 80 | * Note: this does not, by itself, alter unique key attached to the underlying GrTexture. |
| 81 | */ |
| 82 | void processInvalidProxyUniqueKey(const GrUniqueKey&); |
| 83 | |
| 84 | /** |
| 85 | * Same as above, but you must pass in a GrTextureProxy to save having to search for it. The |
| 86 | * GrUniqueKey of the proxy must be valid and it must match the passed in key. This function |
| 87 | * also gives the option to invalidate the GrUniqueKey on the underlying GrTexture. |
| 88 | */ |
| 89 | void processInvalidProxyUniqueKey(const GrUniqueKey&, GrTextureProxy*, bool invalidateSurface); |
| 90 | |
| 91 | const GrCaps* caps() const { return fCaps.get(); } |
| 92 | |
| 93 | void abandon() { |
| 94 | fResourceCache = nullptr; |
| 95 | fResourceProvider = nullptr; |
| 96 | } |
| 97 | |
| 98 | bool isAbandoned() const { |
| 99 | SkASSERT(SkToBool(fResourceCache) == SkToBool(fResourceProvider)); |
| 100 | return !SkToBool(fResourceCache); |
| 101 | } |
| 102 | |
| 103 | int numUniqueKeyProxies_TestOnly() const; |
| 104 | |
| 105 | void removeAllUniqueKeys(); |
| 106 | |
| 107 | private: |
| 108 | struct UniquelyKeyedProxyHashTraits { |
| 109 | static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); } |
| 110 | |
| 111 | static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); } |
| 112 | }; |
| 113 | typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash; |
| 114 | |
| 115 | // This holds the texture proxies that have unique keys. The resourceCache does not get a ref |
| 116 | // on these proxies but they must send a message to the resourceCache when they are deleted. |
| 117 | UniquelyKeyedProxyHash fUniquelyKeyedProxies; |
| 118 | |
| 119 | GrResourceProvider* fResourceProvider; |
| 120 | GrResourceCache* fResourceCache; |
| 121 | sk_sp<const GrCaps> fCaps; |
| 122 | |
| 123 | // In debug builds we guard against improper thread handling |
| 124 | SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;) |
| 125 | }; |
| 126 | |
| 127 | #endif |