GrVkSecondaryCBDrawContext.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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/vk/GrVkSecondaryCBDrawContext.h"
  8. #include "include/core/SkImageInfo.h"
  9. #include "include/core/SkSurfaceCharacterization.h"
  10. #include "include/gpu/GrContext.h"
  11. #include "include/gpu/vk/GrVkTypes.h"
  12. #include "include/private/SkDeferredDisplayList.h"
  13. #include "src/core/SkSurfacePriv.h"
  14. #include "src/gpu/GrContextPriv.h"
  15. #include "src/gpu/GrContextThreadSafeProxyPriv.h"
  16. #include "src/gpu/GrRenderTargetContext.h"
  17. #include "src/gpu/SkGpuDevice.h"
  18. sk_sp<GrVkSecondaryCBDrawContext> GrVkSecondaryCBDrawContext::Make(GrContext* ctx,
  19. const SkImageInfo& imageInfo,
  20. const GrVkDrawableInfo& vkInfo,
  21. const SkSurfaceProps* props) {
  22. if (!ctx) {
  23. return nullptr;
  24. }
  25. if (ctx->backend() != GrBackendApi::kVulkan) {
  26. return nullptr;
  27. }
  28. sk_sp<GrRenderTargetContext> rtc(
  29. ctx->priv().makeVulkanSecondaryCBRenderTargetContext(imageInfo, vkInfo, props));
  30. SkASSERT(rtc->asSurfaceProxy()->isInstantiated());
  31. int width = rtc->width();
  32. int height = rtc->height();
  33. sk_sp<SkGpuDevice> device(SkGpuDevice::Make(ctx, std::move(rtc), width, height,
  34. SkGpuDevice::kUninit_InitContents));
  35. if (!device) {
  36. return nullptr;
  37. }
  38. return sk_sp<GrVkSecondaryCBDrawContext>(new GrVkSecondaryCBDrawContext(std::move(device),
  39. props));
  40. }
  41. GrVkSecondaryCBDrawContext::GrVkSecondaryCBDrawContext(sk_sp<SkGpuDevice> device,
  42. const SkSurfaceProps* props)
  43. : fDevice(device)
  44. , fProps(SkSurfacePropsCopyOrDefault(props)) {}
  45. GrVkSecondaryCBDrawContext::~GrVkSecondaryCBDrawContext() {
  46. SkASSERT(!fDevice);
  47. SkASSERT(!fCachedCanvas.get());
  48. }
  49. SkCanvas* GrVkSecondaryCBDrawContext::getCanvas() {
  50. if (!fCachedCanvas) {
  51. fCachedCanvas = std::unique_ptr<SkCanvas>(new SkCanvas(fDevice));
  52. }
  53. return fCachedCanvas.get();
  54. }
  55. void GrVkSecondaryCBDrawContext::flush() {
  56. fDevice->flush();
  57. }
  58. bool GrVkSecondaryCBDrawContext::wait(int numSemaphores,
  59. const GrBackendSemaphore waitSemaphores[]) {
  60. return fDevice->wait(numSemaphores, waitSemaphores);
  61. }
  62. void GrVkSecondaryCBDrawContext::releaseResources() {
  63. fCachedCanvas.reset();
  64. fDevice.reset();
  65. }
  66. bool GrVkSecondaryCBDrawContext::characterize(SkSurfaceCharacterization* characterization) const {
  67. GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
  68. GrContext* ctx = fDevice->context();
  69. int maxResourceCount;
  70. size_t maxResourceBytes;
  71. ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
  72. // We current don't support textured GrVkSecondaryCBDrawContexts.
  73. SkASSERT(!rtc->asTextureProxy());
  74. SkColorType ct = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
  75. if (ct == kUnknown_SkColorType) {
  76. return false;
  77. }
  78. SkImageInfo ii = SkImageInfo::Make(rtc->width(), rtc->height(), ct, kPremul_SkAlphaType,
  79. rtc->colorSpaceInfo().refColorSpace());
  80. GrBackendFormat format = rtc->asRenderTargetProxy()->backendFormat();
  81. characterization->set(ctx->threadSafeProxy(), maxResourceBytes, ii, format,
  82. rtc->origin(), rtc->numSamples(),
  83. SkSurfaceCharacterization::Textureable(false),
  84. SkSurfaceCharacterization::MipMapped(false),
  85. SkSurfaceCharacterization::UsesGLFBO0(false),
  86. SkSurfaceCharacterization::VulkanSecondaryCBCompatible(true),
  87. GrProtected(rtc->asRenderTargetProxy()->isProtected()),
  88. this->props());
  89. return true;
  90. }
  91. bool GrVkSecondaryCBDrawContext::isCompatible(
  92. const SkSurfaceCharacterization& characterization) const {
  93. GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
  94. GrContext* ctx = fDevice->context();
  95. if (!characterization.isValid()) {
  96. return false;
  97. }
  98. if (!characterization.vulkanSecondaryCBCompatible()) {
  99. return false;
  100. }
  101. // As long as the current state in the context allows for greater or equal resources,
  102. // we allow the DDL to be replayed.
  103. // DDL TODO: should we just remove the resource check and ignore the cache limits on playback?
  104. int maxResourceCount;
  105. size_t maxResourceBytes;
  106. ctx->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
  107. if (characterization.isTextureable()) {
  108. // We don't support textureable DDL when rendering to a GrVkSecondaryCBDrawContext.
  109. return false;
  110. }
  111. if (characterization.usesGLFBO0()) {
  112. return false;
  113. }
  114. SkColorType rtColorType = GrColorTypeToSkColorType(rtc->colorSpaceInfo().colorType());
  115. if (rtColorType == kUnknown_SkColorType) {
  116. return false;
  117. }
  118. GrBackendFormat rtcFormat = rtc->asRenderTargetProxy()->backendFormat();
  119. GrProtected isProtected = GrProtected(rtc->asRenderTargetProxy()->isProtected());
  120. return characterization.contextInfo() && characterization.contextInfo()->priv().matches(ctx) &&
  121. characterization.cacheMaxResourceBytes() <= maxResourceBytes &&
  122. characterization.origin() == rtc->origin() &&
  123. characterization.backendFormat() == rtcFormat &&
  124. characterization.width() == rtc->width() &&
  125. characterization.height() == rtc->height() &&
  126. characterization.colorType() == rtColorType &&
  127. characterization.sampleCount() == rtc->numSamples() &&
  128. SkColorSpace::Equals(characterization.colorSpace(),
  129. rtc->colorSpaceInfo().colorSpace()) &&
  130. characterization.isProtected() == isProtected &&
  131. characterization.surfaceProps() == rtc->surfaceProps();
  132. }
  133. bool GrVkSecondaryCBDrawContext::draw(SkDeferredDisplayList* ddl) {
  134. if (!ddl || !this->isCompatible(ddl->characterization())) {
  135. return false;
  136. }
  137. GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
  138. GrContext* ctx = fDevice->context();
  139. ctx->priv().copyOpListsFromDDL(ddl, rtc->asRenderTargetProxy());
  140. return true;
  141. }