SkDeferredDisplayListRecorder.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Copyright 2017 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 "include/core/SkDeferredDisplayListRecorder.h"
  8. #include "include/core/SkSurface.h"
  9. #include "include/core/SkSurfaceCharacterization.h"
  10. #include "include/private/SkDeferredDisplayList.h"
  11. #include "src/core/SkMessageBus.h"
  12. #if !SK_SUPPORT_GPU
  13. SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&) {}
  14. SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {}
  15. bool SkDeferredDisplayListRecorder::init() { return false; }
  16. SkCanvas* SkDeferredDisplayListRecorder::getCanvas() { return nullptr; }
  17. std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() { return nullptr; }
  18. sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
  19. const GrBackendFormat& backendFormat,
  20. int width,
  21. int height,
  22. GrMipMapped mipMapped,
  23. GrSurfaceOrigin origin,
  24. SkColorType colorType,
  25. SkAlphaType alphaType,
  26. sk_sp<SkColorSpace> colorSpace,
  27. PromiseImageTextureFulfillProc textureFulfillProc,
  28. PromiseImageTextureReleaseProc textureReleaseProc,
  29. PromiseImageTextureDoneProc textureDoneProc,
  30. PromiseImageTextureContext textureContext,
  31. PromiseImageApiVersion) {
  32. return nullptr;
  33. }
  34. sk_sp<SkImage> SkDeferredDisplayListRecorder::makeYUVAPromiseTexture(
  35. SkYUVColorSpace yuvColorSpace,
  36. const GrBackendFormat yuvaFormats[],
  37. const SkISize yuvaSizes[],
  38. const SkYUVAIndex yuvaIndices[4],
  39. int imageWidth,
  40. int imageHeight,
  41. GrSurfaceOrigin imageOrigin,
  42. sk_sp<SkColorSpace> imageColorSpace,
  43. PromiseImageTextureFulfillProc textureFulfillProc,
  44. PromiseImageTextureReleaseProc textureReleaseProc,
  45. PromiseImageTextureDoneProc textureDoneProc,
  46. PromiseImageTextureContext textureContexts[],
  47. PromiseImageApiVersion) {
  48. return nullptr;
  49. }
  50. #else
  51. #include "include/core/SkPromiseImageTexture.h"
  52. #include "include/core/SkYUVASizeInfo.h"
  53. #include "include/gpu/GrTexture.h"
  54. #include "src/core/SkMakeUnique.h"
  55. #include "src/gpu/GrContextPriv.h"
  56. #include "src/gpu/GrProxyProvider.h"
  57. #include "src/gpu/GrRenderTargetContext.h"
  58. #include "src/gpu/SkGr.h"
  59. #include "src/image/SkImage_Gpu.h"
  60. #include "src/image/SkImage_GpuYUVA.h"
  61. #include "src/image/SkSurface_Gpu.h"
  62. SkDeferredDisplayListRecorder::SkDeferredDisplayListRecorder(const SkSurfaceCharacterization& c)
  63. : fCharacterization(c) {
  64. if (fCharacterization.isValid()) {
  65. fContext = GrContextPriv::MakeDDL(fCharacterization.refContextInfo());
  66. }
  67. }
  68. SkDeferredDisplayListRecorder::~SkDeferredDisplayListRecorder() {
  69. if (fContext) {
  70. auto proxyProvider = fContext->priv().proxyProvider();
  71. // This allows the uniquely keyed proxies to keep their keys but removes their back
  72. // pointer to the about-to-be-deleted proxy provider. The proxies will use their
  73. // unique key to reattach to cached versions of themselves or to appropriately tag new
  74. // resources (if a cached version was not found). This system operates independent of
  75. // the replaying context's proxy provider (i.e., these uniquely keyed proxies will not
  76. // appear in the replaying proxy providers uniquely keyed proxy map). This should be fine
  77. // since no one else should be trying to reconnect to the orphaned proxies and orphaned
  78. // proxies from different DDLs that share the same key should simply reconnect to the
  79. // same cached resource.
  80. proxyProvider->orphanAllUniqueKeys();
  81. }
  82. }
  83. bool SkDeferredDisplayListRecorder::init() {
  84. SkASSERT(fContext);
  85. SkASSERT(!fLazyProxyData);
  86. SkASSERT(!fSurface);
  87. if (!fCharacterization.isValid()) {
  88. return false;
  89. }
  90. fLazyProxyData = sk_sp<SkDeferredDisplayList::LazyProxyData>(
  91. new SkDeferredDisplayList::LazyProxyData);
  92. auto proxyProvider = fContext->priv().proxyProvider();
  93. const GrCaps* caps = fContext->priv().caps();
  94. bool usesGLFBO0 = fCharacterization.usesGLFBO0();
  95. if (usesGLFBO0) {
  96. if (GrBackendApi::kOpenGL != fContext->backend() ||
  97. fCharacterization.isTextureable()) {
  98. return false;
  99. }
  100. }
  101. if (fCharacterization.vulkanSecondaryCBCompatible()) {
  102. // Because of the restrictive API allowed for a GrVkSecondaryCBDrawContext, we know ahead
  103. // of time that we don't be able to support certain parameter combinations. Specifially we
  104. // fail on usesGLFBO0 since we can't mix GL and Vulkan. We can't have a texturable object.
  105. // And finally the GrVkSecondaryCBDrawContext always assumes a top left origin.
  106. if (usesGLFBO0 ||
  107. fCharacterization.isTextureable() ||
  108. fCharacterization.origin() == kBottomLeft_GrSurfaceOrigin) {
  109. return false;
  110. }
  111. }
  112. GrColorType grColorType = SkColorTypeToGrColorType(fCharacterization.colorType());
  113. GrPixelConfig config = caps->getConfigFromBackendFormat(fCharacterization.backendFormat(),
  114. grColorType);
  115. if (config == kUnknown_GrPixelConfig) {
  116. return false;
  117. }
  118. GrSurfaceDesc desc;
  119. desc.fWidth = fCharacterization.width();
  120. desc.fHeight = fCharacterization.height();
  121. desc.fConfig = config;
  122. sk_sp<SkDeferredDisplayList::LazyProxyData> lazyProxyData = fLazyProxyData;
  123. // What we're doing here is we're creating a lazy proxy to back the SkSurface. The lazy
  124. // proxy, when instantiated, will use the GrRenderTarget that backs the SkSurface that the
  125. // DDL is being replayed into.
  126. GrInternalSurfaceFlags surfaceFlags = GrInternalSurfaceFlags::kNone;
  127. if (usesGLFBO0) {
  128. surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
  129. }
  130. static constexpr GrProxyProvider::TextureInfo kTextureInfo{GrMipMapped::kNo,
  131. GrTextureType::k2D};
  132. const GrProxyProvider::TextureInfo* optionalTextureInfo = nullptr;
  133. if (fCharacterization.isTextureable()) {
  134. optionalTextureInfo = &kTextureInfo;
  135. }
  136. sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
  137. [lazyProxyData](GrResourceProvider* resourceProvider) {
  138. // The proxy backing the destination surface had better have been instantiated
  139. // prior to the proxy backing the DLL's surface. Steal its GrRenderTarget.
  140. SkASSERT(lazyProxyData->fReplayDest->peekSurface());
  141. auto surface = sk_ref_sp<GrSurface>(lazyProxyData->fReplayDest->peekSurface());
  142. return GrSurfaceProxy::LazyInstantiationResult(std::move(surface));
  143. },
  144. fCharacterization.backendFormat(),
  145. desc,
  146. fCharacterization.sampleCount(),
  147. fCharacterization.origin(),
  148. surfaceFlags,
  149. optionalTextureInfo,
  150. SkBackingFit::kExact,
  151. SkBudgeted::kYes,
  152. fCharacterization.isProtected(),
  153. fCharacterization.vulkanSecondaryCBCompatible());
  154. if (!proxy) {
  155. return false;
  156. }
  157. sk_sp<GrSurfaceContext> c = fContext->priv().makeWrappedSurfaceContext(
  158. std::move(proxy),
  159. grColorType,
  160. kPremul_SkAlphaType,
  161. fCharacterization.refColorSpace(),
  162. &fCharacterization.surfaceProps());
  163. fSurface = SkSurface_Gpu::MakeWrappedRenderTarget(fContext.get(),
  164. sk_ref_sp(c->asRenderTargetContext()));
  165. return SkToBool(fSurface.get());
  166. }
  167. SkCanvas* SkDeferredDisplayListRecorder::getCanvas() {
  168. if (!fContext) {
  169. return nullptr;
  170. }
  171. if (!fSurface && !this->init()) {
  172. return nullptr;
  173. }
  174. return fSurface->getCanvas();
  175. }
  176. std::unique_ptr<SkDeferredDisplayList> SkDeferredDisplayListRecorder::detach() {
  177. if (!fContext) {
  178. return nullptr;
  179. }
  180. if (fSurface) {
  181. SkCanvas* canvas = fSurface->getCanvas();
  182. canvas->restoreToCount(0);
  183. }
  184. auto ddl = std::unique_ptr<SkDeferredDisplayList>(
  185. new SkDeferredDisplayList(fCharacterization, std::move(fLazyProxyData)));
  186. fContext->priv().moveOpListsToDDL(ddl.get());
  187. // We want a new lazy proxy target for each recorded DDL so force the (lazy proxy-backed)
  188. // SkSurface to be regenerated for each DDL.
  189. fSurface = nullptr;
  190. return ddl;
  191. }
  192. sk_sp<SkImage> SkDeferredDisplayListRecorder::makePromiseTexture(
  193. const GrBackendFormat& backendFormat,
  194. int width,
  195. int height,
  196. GrMipMapped mipMapped,
  197. GrSurfaceOrigin origin,
  198. SkColorType colorType,
  199. SkAlphaType alphaType,
  200. sk_sp<SkColorSpace> colorSpace,
  201. PromiseImageTextureFulfillProc textureFulfillProc,
  202. PromiseImageTextureReleaseProc textureReleaseProc,
  203. PromiseImageTextureDoneProc textureDoneProc,
  204. PromiseImageTextureContext textureContext,
  205. PromiseImageApiVersion version) {
  206. if (!fContext) {
  207. return nullptr;
  208. }
  209. return SkImage_Gpu::MakePromiseTexture(fContext.get(),
  210. backendFormat,
  211. width,
  212. height,
  213. mipMapped,
  214. origin,
  215. colorType,
  216. alphaType,
  217. std::move(colorSpace),
  218. textureFulfillProc,
  219. textureReleaseProc,
  220. textureDoneProc,
  221. textureContext,
  222. version);
  223. }
  224. sk_sp<SkImage> SkDeferredDisplayListRecorder::makeYUVAPromiseTexture(
  225. SkYUVColorSpace yuvColorSpace,
  226. const GrBackendFormat yuvaFormats[],
  227. const SkISize yuvaSizes[],
  228. const SkYUVAIndex yuvaIndices[4],
  229. int imageWidth,
  230. int imageHeight,
  231. GrSurfaceOrigin imageOrigin,
  232. sk_sp<SkColorSpace> imageColorSpace,
  233. PromiseImageTextureFulfillProc textureFulfillProc,
  234. PromiseImageTextureReleaseProc textureReleaseProc,
  235. PromiseImageTextureDoneProc textureDoneProc,
  236. PromiseImageTextureContext textureContexts[],
  237. PromiseImageApiVersion version) {
  238. if (!fContext) {
  239. return nullptr;
  240. }
  241. return SkImage_GpuYUVA::MakePromiseYUVATexture(fContext.get(),
  242. yuvColorSpace,
  243. yuvaFormats,
  244. yuvaSizes,
  245. yuvaIndices,
  246. imageWidth,
  247. imageHeight,
  248. imageOrigin,
  249. std::move(imageColorSpace),
  250. textureFulfillProc,
  251. textureReleaseProc,
  252. textureDoneProc,
  253. textureContexts,
  254. version);
  255. }
  256. #endif