| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2015 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 | #include "GrResourceProvider.h" | 
 | 9 |  | 
| Greg Daniel | a5cb781 | 2017-06-16 09:45:32 -0400 | [diff] [blame] | 10 | #include "GrBackendSemaphore.h" | 
| cdalton | 397536c | 2016-03-25 12:15:03 -0700 | [diff] [blame] | 11 | #include "GrBuffer.h" | 
| robertphillips | 5fa7f30 | 2016-07-21 09:21:04 -0700 | [diff] [blame] | 12 | #include "GrCaps.h" | 
| Robert Phillips | 26c90e0 | 2017-03-14 14:39:29 -0400 | [diff] [blame] | 13 | #include "GrContext.h" | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 14 | #include "GrContextPriv.h" | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 15 | #include "GrGpu.h" | 
| Robert Phillips | 67d52cf | 2017-06-05 13:38:13 -0400 | [diff] [blame] | 16 | #include "GrPath.h" | 
| kkinnunen | cabe20c | 2015-06-01 01:37:26 -0700 | [diff] [blame] | 17 | #include "GrPathRendering.h" | 
| Robert Phillips | 0bd24dc | 2018-01-16 08:06:32 -0500 | [diff] [blame] | 18 | #include "GrProxyProvider.h" | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 19 | #include "GrRenderTargetPriv.h" | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 20 | #include "GrResourceCache.h" | 
 | 21 | #include "GrResourceKey.h" | 
| Greg Daniel | d85f97d | 2017-03-07 13:37:21 -0500 | [diff] [blame] | 22 | #include "GrSemaphore.h" | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 23 | #include "GrStencilAttachment.h" | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 24 | #include "GrTexturePriv.h" | 
 | 25 | #include "../private/GrSingleOwner.h" | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 26 | #include "SkGr.h" | 
| halcanary | 4dbbd04 | 2016-06-07 17:21:10 -0700 | [diff] [blame] | 27 | #include "SkMathPriv.h" | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 28 |  | 
 | 29 | GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey); | 
 | 30 |  | 
| Robert Phillips | 1bfece8 | 2017-06-01 13:56:52 -0400 | [diff] [blame] | 31 | const uint32_t GrResourceProvider::kMinScratchTextureSize = 16; | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 32 |  | 
| Robert Phillips | a3f7026 | 2018-02-08 10:59:38 -0500 | [diff] [blame] | 33 | #ifdef SK_DISABLE_EXPLICIT_GPU_RESOURCE_ALLOCATION | 
 | 34 | static const bool kDefaultExplicitlyAllocateGPUResources = false; | 
 | 35 | #else | 
 | 36 | static const bool kDefaultExplicitlyAllocateGPUResources = true; | 
 | 37 | #endif | 
 | 38 |  | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 39 | #define ASSERT_SINGLE_OWNER \ | 
 | 40 |     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);) | 
 | 41 |  | 
| Robert Phillips | 4150eea | 2018-02-07 17:08:21 -0500 | [diff] [blame] | 42 | GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner, | 
| Robert Phillips | a3f7026 | 2018-02-08 10:59:38 -0500 | [diff] [blame] | 43 |                                        GrContextOptions::Enable explicitlyAllocateGPUResources) | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 44 |         : fCache(cache) | 
 | 45 |         , fGpu(gpu) | 
 | 46 | #ifdef SK_DEBUG | 
 | 47 |         , fSingleOwner(owner) | 
 | 48 | #endif | 
| Robert Phillips | 4150eea | 2018-02-07 17:08:21 -0500 | [diff] [blame] | 49 | { | 
| Robert Phillips | a3f7026 | 2018-02-08 10:59:38 -0500 | [diff] [blame] | 50 |     if (GrContextOptions::Enable::kNo == explicitlyAllocateGPUResources) { | 
 | 51 |         fExplicitlyAllocateGPUResources = false; | 
 | 52 |     } else if (GrContextOptions::Enable::kYes == explicitlyAllocateGPUResources) { | 
 | 53 |         fExplicitlyAllocateGPUResources = true; | 
 | 54 |     } else { | 
 | 55 |         fExplicitlyAllocateGPUResources = kDefaultExplicitlyAllocateGPUResources; | 
 | 56 |     } | 
 | 57 |  | 
| Robert Phillips | 26c90e0 | 2017-03-14 14:39:29 -0400 | [diff] [blame] | 58 |     fCaps = sk_ref_sp(fGpu->caps()); | 
 | 59 |  | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 60 |     GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey); | 
 | 61 |     fQuadIndexBufferKey = gQuadIndexBufferKey; | 
 | 62 | } | 
 | 63 |  | 
| Robert Phillips | 8e8c755 | 2017-07-10 12:06:05 -0400 | [diff] [blame] | 64 | sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, | 
| Brian Osman | 2b23c4b | 2018-06-01 12:25:08 -0400 | [diff] [blame] | 65 |                                                    const GrMipLevel texels[], int mipLevelCount) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 66 |     ASSERT_SINGLE_OWNER | 
 | 67 |  | 
| Robert Phillips | 7f1b4f8 | 2017-11-28 07:38:39 -0500 | [diff] [blame] | 68 |     SkASSERT(mipLevelCount > 0); | 
| Robert Phillips | 1119dc3 | 2017-04-11 12:54:57 -0400 | [diff] [blame] | 69 |  | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 70 |     if (this->isAbandoned()) { | 
 | 71 |         return nullptr; | 
 | 72 |     } | 
| Robert Phillips | 1119dc3 | 2017-04-11 12:54:57 -0400 | [diff] [blame] | 73 |  | 
| Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 74 |     GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo; | 
 | 75 |     if (!fCaps->validateSurfaceDesc(desc, mipMapped)) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 76 |         return nullptr; | 
 | 77 |     } | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 78 |  | 
| Brian Osman | 2b23c4b | 2018-06-01 12:25:08 -0400 | [diff] [blame] | 79 |     return fGpu->createTexture(desc, budgeted, texels, mipLevelCount); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 80 | } | 
 | 81 |  | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 82 | sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc, | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 83 |                                                      SkBudgeted budgeted, Flags flags) { | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 84 |     sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags)); | 
 | 85 |     if (tex && SkBudgeted::kNo == budgeted) { | 
 | 86 |         tex->resourcePriv().makeUnbudgeted(); | 
 | 87 |     } | 
 | 88 |  | 
 | 89 |     return tex; | 
 | 90 | } | 
 | 91 |  | 
| Robert Phillips | 1afd4cd | 2018-01-08 13:40:32 -0500 | [diff] [blame] | 92 | sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, | 
 | 93 |                                                    SkBudgeted budgeted, | 
| Greg Daniel | fb3abcd | 2018-02-02 15:48:33 -0500 | [diff] [blame] | 94 |                                                    SkBackingFit fit, | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 95 |                                                    const GrMipLevel& mipLevel, | 
 | 96 |                                                    Flags flags) { | 
| Robert Phillips | 774831a | 2017-04-20 10:19:33 -0400 | [diff] [blame] | 97 |     ASSERT_SINGLE_OWNER | 
 | 98 |  | 
 | 99 |     if (this->isAbandoned()) { | 
 | 100 |         return nullptr; | 
 | 101 |     } | 
 | 102 |  | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 103 |     if (!mipLevel.fPixels) { | 
 | 104 |         return nullptr; | 
 | 105 |     } | 
 | 106 |  | 
| Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 107 |     if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) { | 
| Brian Salomon | d34edf3 | 2017-05-19 15:45:48 -0400 | [diff] [blame] | 108 |         return nullptr; | 
 | 109 |     } | 
 | 110 |  | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 111 |     GrContext* context = fGpu->getContext(); | 
| Robert Phillips | 0bd24dc | 2018-01-16 08:06:32 -0500 | [diff] [blame] | 112 |     GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 113 |  | 
| Brian Salomon | 1fcac05 | 2018-05-09 16:33:09 -0400 | [diff] [blame] | 114 |     SkColorType colorType; | 
 | 115 |     if (GrPixelConfigToColorType(desc.fConfig, &colorType)) { | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 116 |         sk_sp<GrTexture> tex = (SkBackingFit::kApprox == fit) | 
 | 117 |                 ? this->createApproxTexture(desc, flags) | 
 | 118 |                 : this->createTexture(desc, budgeted, flags); | 
 | 119 |         if (!tex) { | 
 | 120 |             return nullptr; | 
 | 121 |         } | 
 | 122 |  | 
 | 123 |         sk_sp<GrTextureProxy> proxy = proxyProvider->createWrapped(std::move(tex), | 
 | 124 |                                                                    kTopLeft_GrSurfaceOrigin); | 
| Brian Salomon | 1fcac05 | 2018-05-09 16:33:09 -0400 | [diff] [blame] | 125 |         if (!proxy) { | 
 | 126 |             return nullptr; | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 127 |         } | 
| Brian Salomon | 1fcac05 | 2018-05-09 16:33:09 -0400 | [diff] [blame] | 128 |         auto srcInfo = SkImageInfo::Make(desc.fWidth, desc.fHeight, colorType, | 
| Brian Osman | 9363ac4 | 2018-06-01 16:10:53 -0400 | [diff] [blame] | 129 |                                          kUnknown_SkAlphaType); | 
| Brian Salomon | 1fcac05 | 2018-05-09 16:33:09 -0400 | [diff] [blame] | 130 |         sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext( | 
| Brian Osman | 9363ac4 | 2018-06-01 16:10:53 -0400 | [diff] [blame] | 131 |                 std::move(proxy)); | 
| Brian Salomon | 1fcac05 | 2018-05-09 16:33:09 -0400 | [diff] [blame] | 132 |         if (!sContext) { | 
 | 133 |             return nullptr; | 
 | 134 |         } | 
 | 135 |         SkAssertResult(sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)); | 
| Brian Salomon | fd98c2c | 2018-07-31 17:25:29 -0400 | [diff] [blame] | 136 |         return sk_ref_sp(sContext->asTextureProxy()->peekTexture()); | 
| Brian Salomon | 1fcac05 | 2018-05-09 16:33:09 -0400 | [diff] [blame] | 137 |     } else { | 
 | 138 |         return fGpu->createTexture(desc, budgeted, &mipLevel, 1); | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 139 |     } | 
| Robert Phillips | 45fdae1 | 2017-04-17 12:57:27 -0400 | [diff] [blame] | 140 | } | 
 | 141 |  | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 142 | sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 143 |                                                    Flags flags) { | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 144 |     ASSERT_SINGLE_OWNER | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 145 |     if (this->isAbandoned()) { | 
 | 146 |         return nullptr; | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 147 |     } | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 148 |  | 
| Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 149 |     if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) { | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 150 |         return nullptr; | 
 | 151 |     } | 
 | 152 |  | 
| Greg Daniel | 2191823 | 2017-09-08 14:46:23 -0400 | [diff] [blame] | 153 |     sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags); | 
| Robert Phillips | 92de631 | 2017-05-23 07:43:48 -0400 | [diff] [blame] | 154 |     if (tex) { | 
 | 155 |         return tex; | 
| Robert Phillips | e78b725 | 2017-04-06 07:59:41 -0400 | [diff] [blame] | 156 |     } | 
 | 157 |  | 
| Robert Phillips | 67d52cf | 2017-06-05 13:38:13 -0400 | [diff] [blame] | 158 |     return fGpu->createTexture(desc, budgeted); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 159 | } | 
 | 160 |  | 
| Robert Phillips | 67d52cf | 2017-06-05 13:38:13 -0400 | [diff] [blame] | 161 | sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc, | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 162 |                                                          Flags flags) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 163 |     ASSERT_SINGLE_OWNER | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 164 |     SkASSERT(Flags::kNone == flags || Flags::kNoPendingIO == flags); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 165 |  | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 166 |     if (this->isAbandoned()) { | 
 | 167 |         return nullptr; | 
 | 168 |     } | 
| Robert Phillips | 1119dc3 | 2017-04-11 12:54:57 -0400 | [diff] [blame] | 169 |  | 
| Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 170 |     if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) { | 
| Brian Salomon | d34edf3 | 2017-05-19 15:45:48 -0400 | [diff] [blame] | 171 |         return nullptr; | 
 | 172 |     } | 
 | 173 |  | 
| Greg Daniel | 6b60b6e | 2017-09-26 16:37:12 -0400 | [diff] [blame] | 174 |     if (auto tex = this->refScratchTexture(desc, flags)) { | 
 | 175 |         return tex; | 
 | 176 |     } | 
 | 177 |  | 
| Greg Daniel | 29bf84f | 2017-09-25 12:25:12 -0400 | [diff] [blame] | 178 |     SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc); | 
 | 179 |  | 
 | 180 |     // bin by pow2 with a reasonable min | 
 | 181 |     if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) && | 
 | 182 |         (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) { | 
 | 183 |         GrSurfaceDesc* wdesc = copyDesc.writable(); | 
 | 184 |         wdesc->fWidth  = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth)); | 
 | 185 |         wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight)); | 
 | 186 |     } | 
 | 187 |  | 
 | 188 |     if (auto tex = this->refScratchTexture(*copyDesc, flags)) { | 
 | 189 |         return tex; | 
 | 190 |     } | 
 | 191 |  | 
 | 192 |     return fGpu->createTexture(*copyDesc, SkBudgeted::kYes); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 193 | } | 
 | 194 |  | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 195 | sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc, Flags flags) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 196 |     ASSERT_SINGLE_OWNER | 
 | 197 |     SkASSERT(!this->isAbandoned()); | 
| Brian Salomon | bdecacf | 2018-02-02 20:32:49 -0500 | [diff] [blame] | 198 |     SkASSERT(fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 199 |  | 
| Brian Salomon | d17b4a6 | 2017-05-23 16:53:47 -0400 | [diff] [blame] | 200 |     // We could make initial clears work with scratch textures but it is a rare case so we just opt | 
 | 201 |     // to fall back to making a new texture. | 
| Greg Daniel | 29bf84f | 2017-09-25 12:25:12 -0400 | [diff] [blame] | 202 |     if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) && | 
 | 203 |         (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 204 |  | 
 | 205 |         GrScratchKey key; | 
| Greg Daniel | 29bf84f | 2017-09-25 12:25:12 -0400 | [diff] [blame] | 206 |         GrTexturePriv::ComputeScratchKey(desc, &key); | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 207 |         auto scratchFlags = GrResourceCache::ScratchFlags::kNone; | 
 | 208 |         if (Flags::kNoPendingIO & flags) { | 
 | 209 |             scratchFlags |= GrResourceCache::ScratchFlags::kRequireNoPendingIO; | 
| Greg Daniel | 29bf84f | 2017-09-25 12:25:12 -0400 | [diff] [blame] | 210 |         } else  if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 211 |             // If it is not a render target then it will most likely be populated by | 
 | 212 |             // writePixels() which will trigger a flush if the texture has pending IO. | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 213 |             scratchFlags |= GrResourceCache::ScratchFlags::kPreferNoPendingIO; | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 214 |         } | 
 | 215 |         GrGpuResource* resource = fCache->findAndRefScratchResource(key, | 
| Greg Daniel | 29bf84f | 2017-09-25 12:25:12 -0400 | [diff] [blame] | 216 |                                                                     GrSurface::WorstCaseSize(desc), | 
 | 217 |                                                                     scratchFlags); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 218 |         if (resource) { | 
 | 219 |             GrSurface* surface = static_cast<GrSurface*>(resource); | 
| Robert Phillips | 67d52cf | 2017-06-05 13:38:13 -0400 | [diff] [blame] | 220 |             return sk_sp<GrTexture>(surface->asTexture()); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 221 |         } | 
 | 222 |     } | 
 | 223 |  | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 224 |     return nullptr; | 
 | 225 | } | 
 | 226 |  | 
| Greg Daniel | 7ef28f3 | 2017-04-20 16:41:55 +0000 | [diff] [blame] | 227 | sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex, | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 228 |                                                         GrWrapOwnership ownership) { | 
 | 229 |     ASSERT_SINGLE_OWNER | 
 | 230 |     if (this->isAbandoned()) { | 
 | 231 |         return nullptr; | 
 | 232 |     } | 
| Robert Phillips | b0e93a2 | 2017-08-29 08:26:54 -0400 | [diff] [blame] | 233 |     return fGpu->wrapBackendTexture(tex, ownership); | 
| Brian Salomon | d17f658 | 2017-07-19 18:28:58 -0400 | [diff] [blame] | 234 | } | 
 | 235 |  | 
 | 236 | sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex, | 
| Brian Salomon | d17f658 | 2017-07-19 18:28:58 -0400 | [diff] [blame] | 237 |                                                                   int sampleCnt, | 
 | 238 |                                                                   GrWrapOwnership ownership) { | 
 | 239 |     ASSERT_SINGLE_OWNER | 
 | 240 |     if (this->isAbandoned()) { | 
 | 241 |         return nullptr; | 
 | 242 |     } | 
| Robert Phillips | b0e93a2 | 2017-08-29 08:26:54 -0400 | [diff] [blame] | 243 |     return fGpu->wrapRenderableBackendTexture(tex, sampleCnt, ownership); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 244 | } | 
 | 245 |  | 
 | 246 | sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget( | 
| Robert Phillips | b0e93a2 | 2017-08-29 08:26:54 -0400 | [diff] [blame] | 247 |         const GrBackendRenderTarget& backendRT) | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 248 | { | 
 | 249 |     ASSERT_SINGLE_OWNER | 
| Robert Phillips | b0e93a2 | 2017-08-29 08:26:54 -0400 | [diff] [blame] | 250 |     return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 251 | } | 
 | 252 |  | 
 | 253 | void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key, | 
 | 254 |                                                    GrGpuResource* resource) { | 
 | 255 |     ASSERT_SINGLE_OWNER | 
 | 256 |     if (this->isAbandoned() || !resource) { | 
 | 257 |         return; | 
 | 258 |     } | 
 | 259 |     resource->resourcePriv().setUniqueKey(key); | 
 | 260 | } | 
 | 261 |  | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 262 | sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) { | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 263 |     ASSERT_SINGLE_OWNER | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 264 |     return this->isAbandoned() ? nullptr | 
 | 265 |                                : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key)); | 
| Brian Osman | 32342f0 | 2017-03-04 08:12:46 -0500 | [diff] [blame] | 266 | } | 
 | 267 |  | 
| Chris Dalton | 5d2de08 | 2017-12-19 10:40:23 -0700 | [diff] [blame] | 268 | sk_sp<const GrBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrBufferType intendedType, | 
 | 269 |                                                                  size_t size, | 
 | 270 |                                                                  const void* data, | 
 | 271 |                                                                  const GrUniqueKey& key) { | 
 | 272 |     if (auto buffer = this->findByUniqueKey<GrBuffer>(key)) { | 
| Kevin Lubick | f7621cb | 2018-04-16 15:51:44 -0400 | [diff] [blame] | 273 |         return std::move(buffer); | 
| Chris Dalton | 5d2de08 | 2017-12-19 10:40:23 -0700 | [diff] [blame] | 274 |     } | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 275 |     if (auto buffer = this->createBuffer(size, intendedType, kStatic_GrAccessPattern, Flags::kNone, | 
| Chris Dalton | 5d2de08 | 2017-12-19 10:40:23 -0700 | [diff] [blame] | 276 |                                          data)) { | 
 | 277 |         // We shouldn't bin and/or cachestatic buffers. | 
 | 278 |         SkASSERT(buffer->sizeInBytes() == size); | 
 | 279 |         SkASSERT(!buffer->resourcePriv().getScratchKey().isValid()); | 
 | 280 |         SkASSERT(!buffer->resourcePriv().hasPendingIO_debugOnly()); | 
 | 281 |         buffer->resourcePriv().setUniqueKey(key); | 
 | 282 |         return sk_sp<const GrBuffer>(buffer); | 
 | 283 |     } | 
 | 284 |     return nullptr; | 
 | 285 | } | 
 | 286 |  | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 287 | sk_sp<const GrBuffer> GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern, | 
 | 288 |                                                                      int patternSize, | 
 | 289 |                                                                      int reps, | 
 | 290 |                                                                      int vertCount, | 
 | 291 |                                                                      const GrUniqueKey& key) { | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 292 |     size_t bufferSize = patternSize * reps * sizeof(uint16_t); | 
 | 293 |  | 
| Brian Salomon | 09d994e | 2016-12-21 11:14:46 -0500 | [diff] [blame] | 294 |     // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO. | 
| Brian Salomon | 7f56d3d | 2017-10-09 13:02:49 -0400 | [diff] [blame] | 295 |     sk_sp<GrBuffer> buffer(this->createBuffer(bufferSize, kIndex_GrBufferType, | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 296 |                                               kStatic_GrAccessPattern, Flags::kNoPendingIO)); | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 297 |     if (!buffer) { | 
| halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 298 |         return nullptr; | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 299 |     } | 
| Brian Salomon | 7f56d3d | 2017-10-09 13:02:49 -0400 | [diff] [blame] | 300 |     uint16_t* data = (uint16_t*) buffer->map(); | 
 | 301 |     SkAutoTArray<uint16_t> temp; | 
 | 302 |     if (!data) { | 
 | 303 |         temp.reset(reps * patternSize); | 
 | 304 |         data = temp.get(); | 
 | 305 |     } | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 306 |     for (int i = 0; i < reps; ++i) { | 
 | 307 |         int baseIdx = i * patternSize; | 
 | 308 |         uint16_t baseVert = (uint16_t)(i * vertCount); | 
 | 309 |         for (int j = 0; j < patternSize; ++j) { | 
 | 310 |             data[baseIdx+j] = baseVert + pattern[j]; | 
 | 311 |         } | 
 | 312 |     } | 
| Brian Salomon | 7f56d3d | 2017-10-09 13:02:49 -0400 | [diff] [blame] | 313 |     if (temp.get()) { | 
 | 314 |         if (!buffer->updateData(data, bufferSize)) { | 
 | 315 |             return nullptr; | 
 | 316 |         } | 
 | 317 |     } else { | 
 | 318 |         buffer->unmap(); | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 319 |     } | 
| Brian Salomon | 7f56d3d | 2017-10-09 13:02:49 -0400 | [diff] [blame] | 320 |     this->assignUniqueKeyToResource(key, buffer.get()); | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 321 |     return std::move(buffer); | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 322 | } | 
 | 323 |  | 
| Brian Salomon | 3416969 | 2017-08-28 15:32:01 -0400 | [diff] [blame] | 324 | static constexpr int kMaxQuads = 1 << 12;  // max possible: (1 << 14) - 1; | 
 | 325 |  | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 326 | sk_sp<const GrBuffer> GrResourceProvider::createQuadIndexBuffer() { | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 327 |     GR_STATIC_ASSERT(4 * kMaxQuads <= 65535); | 
| Brian Salomon | 57caa66 | 2017-10-18 12:21:05 +0000 | [diff] [blame] | 328 |     static const uint16_t kPattern[] = { 0, 1, 2, 2, 1, 3 }; | 
| Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 329 |     return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey); | 
| bsalomon | ed0bcad | 2015-05-04 10:36:42 -0700 | [diff] [blame] | 330 | } | 
 | 331 |  | 
| Brian Salomon | 763abf0 | 2018-05-01 18:49:38 +0000 | [diff] [blame] | 332 | int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; } | 
| Brian Salomon | 3416969 | 2017-08-28 15:32:01 -0400 | [diff] [blame] | 333 |  | 
| Robert Phillips | 67d52cf | 2017-06-05 13:38:13 -0400 | [diff] [blame] | 334 | sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) { | 
| Robert Phillips | 0f17181 | 2017-09-21 14:25:31 -0400 | [diff] [blame] | 335 |     if (this->isAbandoned()) { | 
 | 336 |         return nullptr; | 
 | 337 |     } | 
 | 338 |  | 
| bsalomon | 706f08f | 2015-05-22 07:35:58 -0700 | [diff] [blame] | 339 |     SkASSERT(this->gpu()->pathRendering()); | 
| bsalomon | 6663acf | 2016-05-10 09:14:17 -0700 | [diff] [blame] | 340 |     return this->gpu()->pathRendering()->createPath(path, style); | 
| bsalomon | 706f08f | 2015-05-22 07:35:58 -0700 | [diff] [blame] | 341 | } | 
 | 342 |  | 
| cdalton | e2e71c2 | 2016-04-07 18:13:29 -0700 | [diff] [blame] | 343 | GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType, | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 344 |                                            GrAccessPattern accessPattern, Flags flags, | 
| cdalton | 1bf3e71 | 2016-04-19 10:00:02 -0700 | [diff] [blame] | 345 |                                            const void* data) { | 
| robertphillips | 1b8e1b5 | 2015-06-24 06:54:10 -0700 | [diff] [blame] | 346 |     if (this->isAbandoned()) { | 
| halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 347 |         return nullptr; | 
| robertphillips | 1b8e1b5 | 2015-06-24 06:54:10 -0700 | [diff] [blame] | 348 |     } | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 349 |     if (kDynamic_GrAccessPattern != accessPattern) { | 
 | 350 |         return this->gpu()->createBuffer(size, intendedType, accessPattern, data); | 
 | 351 |     } | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 352 |     if (!(flags & Flags::kRequireGpuMemory) && | 
| csmartdalton | 485a120 | 2016-07-13 10:16:32 -0700 | [diff] [blame] | 353 |         this->gpu()->caps()->preferClientSideDynamicBuffers() && | 
 | 354 |         GrBufferTypeIsVertexOrIndex(intendedType) && | 
 | 355 |         kDynamic_GrAccessPattern == accessPattern) { | 
 | 356 |         return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data); | 
 | 357 |     } | 
| robertphillips | 1b8e1b5 | 2015-06-24 06:54:10 -0700 | [diff] [blame] | 358 |  | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 359 |     // bin by pow2 with a reasonable min | 
| Robert Phillips | 9e38047 | 2016-10-28 12:15:03 -0400 | [diff] [blame] | 360 |     static const size_t MIN_SIZE = 1 << 12; | 
 | 361 |     size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size)); | 
| robertphillips | 1b8e1b5 | 2015-06-24 06:54:10 -0700 | [diff] [blame] | 362 |  | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 363 |     GrScratchKey key; | 
| csmartdalton | 485a120 | 2016-07-13 10:16:32 -0700 | [diff] [blame] | 364 |     GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key); | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 365 |     auto scratchFlags = GrResourceCache::ScratchFlags::kNone; | 
 | 366 |     if (flags & Flags::kNoPendingIO) { | 
 | 367 |         scratchFlags = GrResourceCache::ScratchFlags::kRequireNoPendingIO; | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 368 |     } else { | 
| Chris Dalton | d004e0b | 2018-09-27 09:28:03 -0600 | [diff] [blame] | 369 |         scratchFlags = GrResourceCache::ScratchFlags::kPreferNoPendingIO; | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 370 |     } | 
 | 371 |     GrBuffer* buffer = static_cast<GrBuffer*>( | 
 | 372 |         this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags)); | 
 | 373 |     if (!buffer) { | 
 | 374 |         buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern); | 
 | 375 |         if (!buffer) { | 
 | 376 |             return nullptr; | 
| robertphillips | 1b8e1b5 | 2015-06-24 06:54:10 -0700 | [diff] [blame] | 377 |         } | 
 | 378 |     } | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 379 |     if (data) { | 
 | 380 |         buffer->updateData(data, size); | 
 | 381 |     } | 
| csmartdalton | 485a120 | 2016-07-13 10:16:32 -0700 | [diff] [blame] | 382 |     SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs. | 
| cdalton | d37fe76 | 2016-04-21 07:41:50 -0700 | [diff] [blame] | 383 |     return buffer; | 
| jvanverth | 17aa047 | 2016-01-05 10:41:27 -0800 | [diff] [blame] | 384 | } | 
 | 385 |  | 
| Robert Phillips | c0192e3 | 2017-09-21 12:00:26 -0400 | [diff] [blame] | 386 | bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) { | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 387 |     SkASSERT(rt); | 
 | 388 |     if (rt->renderTargetPriv().getStencilAttachment()) { | 
| Robert Phillips | c0192e3 | 2017-09-21 12:00:26 -0400 | [diff] [blame] | 389 |         return true; | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 390 |     } | 
 | 391 |  | 
 | 392 |     if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) { | 
 | 393 |         GrUniqueKey sbKey; | 
 | 394 |  | 
 | 395 |         int width = rt->width(); | 
 | 396 |         int height = rt->height(); | 
 | 397 | #if 0 | 
 | 398 |         if (this->caps()->oversizedStencilSupport()) { | 
 | 399 |             width  = SkNextPow2(width); | 
 | 400 |             height = SkNextPow2(height); | 
 | 401 |         } | 
 | 402 | #endif | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 403 |         GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height, | 
 | 404 |                                                                rt->numStencilSamples(), &sbKey); | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 405 |         auto stencil = this->findByUniqueKey<GrStencilAttachment>(sbKey); | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 406 |         if (!stencil) { | 
 | 407 |             // Need to try and create a new stencil | 
| Brian Salomon | d28a79d | 2017-10-16 13:01:07 -0400 | [diff] [blame] | 408 |             stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height)); | 
| Robert Phillips | 01a9128 | 2018-07-26 08:03:04 -0400 | [diff] [blame] | 409 |             if (!stencil) { | 
 | 410 |                 return false; | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 411 |             } | 
| Robert Phillips | 01a9128 | 2018-07-26 08:03:04 -0400 | [diff] [blame] | 412 |             this->assignUniqueKeyToResource(sbKey, stencil.get()); | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 413 |         } | 
| Greg Daniel | cfa3935 | 2018-10-05 12:01:59 -0400 | [diff] [blame^] | 414 |         rt->renderTargetPriv().attachStencilAttachment(std::move(stencil)); | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 415 |     } | 
| Robert Phillips | c0192e3 | 2017-09-21 12:00:26 -0400 | [diff] [blame] | 416 |     return SkToBool(rt->renderTargetPriv().getStencilAttachment()); | 
| egdaniel | ec00d94 | 2015-09-14 12:56:10 -0700 | [diff] [blame] | 417 | } | 
 | 418 |  | 
| bungeman | 6bd5284 | 2016-10-27 09:30:08 -0700 | [diff] [blame] | 419 | sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget( | 
| Robert Phillips | b0e93a2 | 2017-08-29 08:26:54 -0400 | [diff] [blame] | 420 |         const GrBackendTexture& tex, int sampleCnt) | 
| bungeman | 6bd5284 | 2016-10-27 09:30:08 -0700 | [diff] [blame] | 421 | { | 
| ericrk | f7b8b8a | 2016-02-24 14:49:51 -0800 | [diff] [blame] | 422 |     if (this->isAbandoned()) { | 
 | 423 |         return nullptr; | 
 | 424 |     } | 
| Robert Phillips | 0bd24dc | 2018-01-16 08:06:32 -0500 | [diff] [blame] | 425 |     return fGpu->wrapBackendTextureAsRenderTarget(tex, sampleCnt); | 
| ericrk | f7b8b8a | 2016-02-24 14:49:51 -0800 | [diff] [blame] | 426 | } | 
| Greg Daniel | d85f97d | 2017-03-07 13:37:21 -0500 | [diff] [blame] | 427 |  | 
| Greg Daniel | a5cb781 | 2017-06-16 09:45:32 -0400 | [diff] [blame] | 428 | sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) { | 
 | 429 |     return fGpu->makeSemaphore(isOwned); | 
 | 430 | } | 
 | 431 |  | 
 | 432 | sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore, | 
| Greg Daniel | 17b7c05 | 2018-01-09 13:55:33 -0500 | [diff] [blame] | 433 |                                                             SemaphoreWrapType wrapType, | 
| Greg Daniel | a5cb781 | 2017-06-16 09:45:32 -0400 | [diff] [blame] | 434 |                                                             GrWrapOwnership ownership) { | 
 | 435 |     ASSERT_SINGLE_OWNER | 
| Greg Daniel | 17b7c05 | 2018-01-09 13:55:33 -0500 | [diff] [blame] | 436 |     return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore, | 
 | 437 |                                                                       wrapType, | 
 | 438 |                                                                       ownership); | 
| Greg Daniel | d85f97d | 2017-03-07 13:37:21 -0500 | [diff] [blame] | 439 | } |