GrContextPriv.cpp 16 KB

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