• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright 2019 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 "src/gpu/GrContextPriv.h"
9  
10  #include "include/gpu/GrContextThreadSafeProxy.h"
11  #include "include/gpu/GrTexture.h"
12  #include "src/gpu/GrAuditTrail.h"
13  #include "src/gpu/GrContextThreadSafeProxyPriv.h"
14  #include "src/gpu/GrDrawingManager.h"
15  #include "src/gpu/GrGpu.h"
16  #include "src/gpu/GrMemoryPool.h"
17  #include "src/gpu/GrRenderTargetContext.h"
18  #include "src/gpu/GrSkSLFPFactoryCache.h"
19  #include "src/gpu/GrSurfaceContextPriv.h"
20  #include "src/gpu/GrSurfacePriv.h"
21  #include "src/gpu/GrTextureContext.h"
22  #include "src/gpu/SkGr.h"
23  #include "src/gpu/effects/generated/GrConfigConversionEffect.h"
24  #include "src/gpu/text/GrTextBlobCache.h"
25  #include "src/image/SkImage_Base.h"
26  #include "src/image/SkImage_Gpu.h"
27  
28  #define ASSERT_OWNED_PROXY(P) \
29      SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
30  #define ASSERT_SINGLE_OWNER \
31      SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->singleOwner());)
32  #define RETURN_VALUE_IF_ABANDONED(value) if (fContext->abandoned()) { return (value); }
33  #define RETURN_IF_ABANDONED RETURN_VALUE_IF_ABANDONED(void)
34  
refCaps() const35  sk_sp<const GrCaps> GrContextPriv::refCaps() const {
36      return fContext->refCaps();
37  }
38  
fpFactoryCache()39  sk_sp<GrSkSLFPFactoryCache> GrContextPriv::fpFactoryCache() {
40      return fContext->fpFactoryCache();
41  }
42  
refOpMemoryPool()43  sk_sp<GrOpMemoryPool> GrContextPriv::refOpMemoryPool() {
44      return fContext->refOpMemoryPool();
45  }
46  
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)47  void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
48      fContext->addOnFlushCallbackObject(onFlushCBObject);
49  }
50  
makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)51  sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
52                                                                   GrColorType colorType,
53                                                                   SkAlphaType alphaType,
54                                                                   sk_sp<SkColorSpace> colorSpace,
55                                                                   const SkSurfaceProps* props) {
56      return fContext->makeWrappedSurfaceContext(std::move(proxy), colorType, alphaType,
57                                                 std::move(colorSpace), props);
58  }
59  
makeDeferredTextureContext(SkBackingFit fit,int width,int height,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,GrMipMapped mipMapped,GrSurfaceOrigin origin,SkBudgeted budgeted,GrProtected isProtected)60  sk_sp<GrTextureContext> GrContextPriv::makeDeferredTextureContext(SkBackingFit fit,
61                                                                    int width,
62                                                                    int height,
63                                                                    GrColorType colorType,
64                                                                    SkAlphaType alphaType,
65                                                                    sk_sp<SkColorSpace> colorSpace,
66                                                                    GrMipMapped mipMapped,
67                                                                    GrSurfaceOrigin origin,
68                                                                    SkBudgeted budgeted,
69                                                                    GrProtected isProtected) {
70      return fContext->makeDeferredTextureContext(fit, width, height, colorType, alphaType,
71                                                  std::move(colorSpace), mipMapped, origin, budgeted,
72                                                  isProtected);
73  }
74  
makeDeferredRenderTargetContext(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)75  sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContext(
76          SkBackingFit fit,
77          int width,
78          int height,
79          GrColorType colorType,
80          sk_sp<SkColorSpace> colorSpace,
81          int sampleCnt,
82          GrMipMapped mipMapped,
83          GrSurfaceOrigin origin,
84          const SkSurfaceProps* surfaceProps,
85          SkBudgeted budgeted,
86          GrProtected isProtected) {
87      return fContext->makeDeferredRenderTargetContext(fit, width, height, colorType,
88                                                       std::move(colorSpace), sampleCnt, mipMapped,
89                                                       origin, surfaceProps, budgeted, isProtected);
90  }
91  
makeDeferredRenderTargetContextWithFallback(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted)92  sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithFallback(
93          SkBackingFit fit, int width, int height, GrColorType colorType,
94          sk_sp<SkColorSpace> colorSpace, int sampleCnt, GrMipMapped mipMapped,
95          GrSurfaceOrigin origin, const SkSurfaceProps* surfaceProps, SkBudgeted budgeted) {
96      return fContext->makeDeferredRenderTargetContextWithFallback(
97              fit, width, height, colorType, std::move(colorSpace), sampleCnt, mipMapped, origin,
98              surfaceProps, budgeted);
99  }
100  
makeBackendTextureContext(const GrBackendTexture & tex,GrSurfaceOrigin origin,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace)101  sk_sp<GrTextureContext> GrContextPriv::makeBackendTextureContext(const GrBackendTexture& tex,
102                                                                   GrSurfaceOrigin origin,
103                                                                   GrColorType colorType,
104                                                                   SkAlphaType alphaType,
105                                                                   sk_sp<SkColorSpace> colorSpace) {
106      ASSERT_SINGLE_OWNER
107  
108      sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(
109              tex, colorType, origin, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
110      if (!proxy) {
111          return nullptr;
112      }
113  
114      return this->drawingManager()->makeTextureContext(std::move(proxy), colorType, alphaType,
115                                                        std::move(colorSpace));
116  }
117  
makeBackendTextureRenderTargetContext(const GrBackendTexture & tex,GrSurfaceOrigin origin,int sampleCnt,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props,ReleaseProc releaseProc,ReleaseContext releaseCtx)118  sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
119          const GrBackendTexture& tex,
120          GrSurfaceOrigin origin,
121          int sampleCnt,
122          GrColorType colorType,
123          sk_sp<SkColorSpace> colorSpace,
124          const SkSurfaceProps* props,
125          ReleaseProc releaseProc,
126          ReleaseContext releaseCtx) {
127      ASSERT_SINGLE_OWNER
128      SkASSERT(sampleCnt > 0);
129  
130      sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
131              tex, origin, sampleCnt, colorType, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
132              releaseProc, releaseCtx));
133      if (!proxy) {
134          return nullptr;
135      }
136  
137      return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
138                                                             std::move(colorSpace), props);
139  }
140  
makeBackendRenderTargetRenderTargetContext(const GrBackendRenderTarget & backendRT,GrSurfaceOrigin origin,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * surfaceProps,ReleaseProc releaseProc,ReleaseContext releaseCtx)141  sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendRenderTargetRenderTargetContext(
142          const GrBackendRenderTarget& backendRT,
143          GrSurfaceOrigin origin,
144          GrColorType colorType,
145          sk_sp<SkColorSpace> colorSpace,
146          const SkSurfaceProps* surfaceProps,
147          ReleaseProc releaseProc,
148          ReleaseContext releaseCtx) {
149      ASSERT_SINGLE_OWNER
150  
151      sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendRenderTarget(
152              backendRT, colorType, origin, releaseProc, releaseCtx);
153      if (!proxy) {
154          return nullptr;
155      }
156  
157      return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
158                                                             std::move(colorSpace), surfaceProps);
159  }
160  
makeBackendTextureAsRenderTargetRenderTargetContext(const GrBackendTexture & tex,GrSurfaceOrigin origin,int sampleCnt,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)161  sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureAsRenderTargetRenderTargetContext(
162          const GrBackendTexture& tex,
163          GrSurfaceOrigin origin,
164          int sampleCnt,
165          GrColorType colorType,
166          sk_sp<SkColorSpace> colorSpace,
167          const SkSurfaceProps* props) {
168      ASSERT_SINGLE_OWNER
169      SkASSERT(sampleCnt > 0);
170      sk_sp<GrSurfaceProxy> proxy(
171              this->proxyProvider()->wrapBackendTextureAsRenderTarget(tex, colorType,
172                                                                      origin, sampleCnt));
173      if (!proxy) {
174          return nullptr;
175      }
176  
177      return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
178                                                             std::move(colorSpace), props);
179  }
180  
makeVulkanSecondaryCBRenderTargetContext(const SkImageInfo & imageInfo,const GrVkDrawableInfo & vkInfo,const SkSurfaceProps * props)181  sk_sp<GrRenderTargetContext> GrContextPriv::makeVulkanSecondaryCBRenderTargetContext(
182          const SkImageInfo& imageInfo, const GrVkDrawableInfo& vkInfo, const SkSurfaceProps* props) {
183      ASSERT_SINGLE_OWNER
184      sk_sp<GrSurfaceProxy> proxy(
185              this->proxyProvider()->wrapVulkanSecondaryCBAsRenderTarget(imageInfo, vkInfo));
186      if (!proxy) {
187          return nullptr;
188      }
189  
190      return this->drawingManager()->makeRenderTargetContext(
191              std::move(proxy),
192              SkColorTypeToGrColorType(imageInfo.colorType()),
193              imageInfo.refColorSpace(),
194              props);
195  }
196  
flushSurfaces(GrSurfaceProxy * proxies[],int numProxies,const GrFlushInfo & info)197  GrSemaphoresSubmitted GrContextPriv::flushSurfaces(GrSurfaceProxy* proxies[], int numProxies,
198                                                     const GrFlushInfo& info) {
199      ASSERT_SINGLE_OWNER
200      RETURN_VALUE_IF_ABANDONED(GrSemaphoresSubmitted::kNo)
201      GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "flushSurfaces", fContext);
202      SkASSERT(numProxies >= 0);
203      SkASSERT(!numProxies || proxies);
204      for (int i = 0; i < numProxies; ++i) {
205          SkASSERT(proxies[i]);
206          ASSERT_OWNED_PROXY(proxies[i]);
207      }
208      return fContext->drawingManager()->flushSurfaces(
209              proxies, numProxies, SkSurface::BackendSurfaceAccess::kNoAccess, info);
210  }
211  
flushSurface(GrSurfaceProxy * proxy)212  void GrContextPriv::flushSurface(GrSurfaceProxy* proxy) {
213      this->flushSurfaces(proxy ? &proxy : nullptr, proxy ? 1 : 0, {});
214  }
215  
moveRenderTasksToDDL(SkDeferredDisplayList * ddl)216  void GrContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) {
217      fContext->drawingManager()->moveRenderTasksToDDL(ddl);
218  }
219  
copyRenderTasksFromDDL(const SkDeferredDisplayList * ddl,GrRenderTargetProxy * newDest)220  void GrContextPriv::copyRenderTasksFromDDL(const SkDeferredDisplayList* ddl,
221                                             GrRenderTargetProxy* newDest) {
222      fContext->drawingManager()->copyRenderTasksFromDDL(ddl, newDest);
223  }
224  
225  //////////////////////////////////////////////////////////////////////////////
226  
227  #if GR_TEST_UTILS
resetGpuStats() const228  void GrContextPriv::resetGpuStats() const {
229  #if GR_GPU_STATS
230      fContext->fGpu->stats()->reset();
231  #endif
232  }
233  
dumpCacheStats(SkString * out) const234  void GrContextPriv::dumpCacheStats(SkString* out) const {
235  #if GR_CACHE_STATS
236      fContext->fResourceCache->dumpStats(out);
237  #endif
238  }
239  
dumpCacheStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const240  void GrContextPriv::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
241                                                  SkTArray<double>* values) const {
242  #if GR_CACHE_STATS
243      fContext->fResourceCache->dumpStatsKeyValuePairs(keys, values);
244  #endif
245  }
246  
printCacheStats() const247  void GrContextPriv::printCacheStats() const {
248      SkString out;
249      this->dumpCacheStats(&out);
250      SkDebugf("%s", out.c_str());
251  }
252  
dumpGpuStats(SkString * out) const253  void GrContextPriv::dumpGpuStats(SkString* out) const {
254  #if GR_GPU_STATS
255      return fContext->fGpu->stats()->dump(out);
256  #endif
257  }
258  
dumpGpuStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const259  void GrContextPriv::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
260                                                SkTArray<double>* values) const {
261  #if GR_GPU_STATS
262      return fContext->fGpu->stats()->dumpKeyValuePairs(keys, values);
263  #endif
264  }
265  
printGpuStats() const266  void GrContextPriv::printGpuStats() const {
267      SkString out;
268      this->dumpGpuStats(&out);
269      SkDebugf("%s", out.c_str());
270  }
271  
testingOnly_setTextBlobCacheLimit(size_t bytes)272  void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) {
273      fContext->priv().getTextBlobCache()->setBudget(bytes);
274  }
275  
testingOnly_getFontAtlasImage(GrMaskFormat format,unsigned int index)276  sk_sp<SkImage> GrContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index) {
277      auto atlasManager = this->getAtlasManager();
278      if (!atlasManager) {
279          return nullptr;
280      }
281  
282      unsigned int numActiveProxies;
283      const sk_sp<GrTextureProxy>* proxies = atlasManager->getProxies(format, &numActiveProxies);
284      if (index >= numActiveProxies || !proxies || !proxies[index]) {
285          return nullptr;
286      }
287  
288      SkASSERT(proxies[index]->priv().isExact());
289      sk_sp<SkImage> image(new SkImage_Gpu(sk_ref_sp(fContext), kNeedNewImageUniqueID,
290                                           kPremul_SkAlphaType, proxies[index], nullptr));
291      return image;
292  }
293  
testingOnly_purgeAllUnlockedResources()294  void GrContextPriv::testingOnly_purgeAllUnlockedResources() {
295      fContext->fResourceCache->purgeAllUnlocked();
296  }
297  
testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject * cb)298  void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
299      fContext->flush();
300      fContext->drawingManager()->testingOnly_removeOnFlushCallbackObject(cb);
301  }
302  #endif
303  
validPMUPMConversionExists()304  bool GrContextPriv::validPMUPMConversionExists() {
305      ASSERT_SINGLE_OWNER
306      if (!fContext->fDidTestPMConversions) {
307          fContext->fPMUPMConversionsRoundTrip =
308                  GrConfigConversionEffect::TestForPreservingPMConversions(fContext);
309          fContext->fDidTestPMConversions = true;
310      }
311  
312      // The PM<->UPM tests fail or succeed together so we only need to check one.
313      return fContext->fPMUPMConversionsRoundTrip;
314  }
315  
createPMToUPMEffect(std::unique_ptr<GrFragmentProcessor> fp)316  std::unique_ptr<GrFragmentProcessor> GrContextPriv::createPMToUPMEffect(
317          std::unique_ptr<GrFragmentProcessor> fp) {
318      ASSERT_SINGLE_OWNER
319      // We should have already called this->priv().validPMUPMConversionExists() in this case
320      SkASSERT(fContext->fDidTestPMConversions);
321      // ...and it should have succeeded
322      SkASSERT(this->validPMUPMConversionExists());
323  
324      return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToUnpremul);
325  }
326  
createUPMToPMEffect(std::unique_ptr<GrFragmentProcessor> fp)327  std::unique_ptr<GrFragmentProcessor> GrContextPriv::createUPMToPMEffect(
328          std::unique_ptr<GrFragmentProcessor> fp) {
329      ASSERT_SINGLE_OWNER
330      // We should have already called this->priv().validPMUPMConversionExists() in this case
331      SkASSERT(fContext->fDidTestPMConversions);
332      // ...and it should have succeeded
333      SkASSERT(this->validPMUPMConversionExists());
334  
335      return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
336  }
337  
338  //////////////////////////////////////////////////////////////////////////////
339  
340  #include "src/core/SkMipMap.h"
341  
createBackendTexture(const SkPixmap srcData[],int numLevels,GrRenderable renderable,GrProtected isProtected)342  GrBackendTexture GrContextPriv::createBackendTexture(const SkPixmap srcData[], int numLevels,
343                                                       GrRenderable renderable,
344                                                       GrProtected isProtected) {
345      if (!fContext->asDirectContext()) {
346          return {};
347      }
348  
349      if (this->abandoned()) {
350          return {};
351      }
352  
353      if (!srcData || !numLevels) {
354          return {};
355      }
356  
357      int baseWidth = srcData[0].width();
358      int baseHeight = srcData[0].height();
359      SkColorType colorType = srcData[0].colorType();
360  
361      if (numLevels > 1) {
362          if (numLevels != SkMipMap::ComputeLevelCount(baseWidth, baseHeight) + 1) {
363              return {};
364          }
365  
366          int currentWidth = baseWidth;
367          int currentHeight = baseHeight;
368          for (int i = 1; i < numLevels; ++i) {
369              currentWidth = SkTMax(1, currentWidth / 2);
370              currentHeight = SkTMax(1, currentHeight / 2);
371  
372              if (srcData[i].colorType() != colorType) {
373                  return {};
374              }
375  
376              if (srcData[i].width() != currentWidth || srcData[i].height() != currentHeight) {
377                  return {};
378              }
379          }
380      }
381  
382      GrBackendFormat backendFormat = fContext->defaultBackendFormat(colorType, renderable);
383      if (!backendFormat.isValid()) {
384          return {};
385      }
386  
387      GrGpu* gpu = fContext->fGpu.get();
388  
389      // TODO: propagate the array of pixmaps interface to GrGpu
390      return gpu->createBackendTexture(baseWidth, baseHeight, backendFormat,
391                                       GrMipMapped::kNo, // TODO: use real mipmap setting here
392                                       renderable, srcData[0].addr(), srcData[0].rowBytes(),
393                                       nullptr, isProtected);
394  }
395