GrTextureMaker.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright 2016 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/GrTextureMaker.h"
  8. #include "include/private/GrRecordingContext.h"
  9. #include "src/gpu/GrColorSpaceXform.h"
  10. #include "src/gpu/GrGpu.h"
  11. #include "src/gpu/GrProxyProvider.h"
  12. #include "src/gpu/GrRecordingContextPriv.h"
  13. sk_sp<GrTextureProxy> GrTextureMaker::onRefTextureProxyForParams(const GrSamplerState& params,
  14. bool willBeMipped,
  15. SkScalar scaleAdjust[2]) {
  16. if (this->width() > this->context()->priv().caps()->maxTextureSize() ||
  17. this->height() > this->context()->priv().caps()->maxTextureSize()) {
  18. return nullptr;
  19. }
  20. CopyParams copyParams;
  21. sk_sp<GrTextureProxy> original(this->refOriginalTextureProxy(willBeMipped,
  22. AllowedTexGenType::kCheap));
  23. bool needsCopyForMipsOnly = false;
  24. if (original) {
  25. if (!params.isRepeated() ||
  26. !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), original.get(),
  27. original->width(), original->height(),
  28. params.filter(), &copyParams, scaleAdjust)) {
  29. needsCopyForMipsOnly = GrGpu::IsACopyNeededForMips(this->context()->priv().caps(),
  30. original.get(), params.filter(),
  31. &copyParams);
  32. if (!needsCopyForMipsOnly) {
  33. return original;
  34. }
  35. }
  36. } else {
  37. if (!params.isRepeated() ||
  38. !GrGpu::IsACopyNeededForRepeatWrapMode(this->context()->priv().caps(), nullptr,
  39. this->width(), this->height(),
  40. params.filter(), &copyParams, scaleAdjust)) {
  41. return this->refOriginalTextureProxy(willBeMipped, AllowedTexGenType::kAny);
  42. }
  43. }
  44. GrProxyProvider* proxyProvider = this->context()->priv().proxyProvider();
  45. GrSurfaceOrigin origOrigin = original ? original->origin() : kTopLeft_GrSurfaceOrigin;
  46. GrUniqueKey copyKey;
  47. this->makeCopyKey(copyParams, &copyKey);
  48. sk_sp<GrTextureProxy> cachedProxy;
  49. if (copyKey.isValid()) {
  50. cachedProxy = proxyProvider->findOrCreateProxyByUniqueKey(copyKey, origOrigin);
  51. if (cachedProxy && (!willBeMipped || GrMipMapped::kYes == cachedProxy->mipMapped())) {
  52. return cachedProxy;
  53. }
  54. }
  55. sk_sp<GrTextureProxy> source;
  56. if (original) {
  57. source = std::move(original);
  58. } else if (cachedProxy) {
  59. source = cachedProxy;
  60. } else {
  61. // Since we will be copying this texture there is no reason to make it mipped
  62. source = this->refOriginalTextureProxy(false, AllowedTexGenType::kAny);
  63. }
  64. if (!source) {
  65. return nullptr;
  66. }
  67. sk_sp<GrTextureProxy> result =
  68. CopyOnGpu(this->context(), source, this->colorType(), copyParams, willBeMipped);
  69. if (!result) {
  70. // If we were unable to make a copy and we only needed a copy for mips, then we will return
  71. // the source texture here and require that the GPU backend is able to fall back to using
  72. // bilerp if mips are required.
  73. if (needsCopyForMipsOnly) {
  74. return source;
  75. }
  76. return nullptr;
  77. }
  78. if (copyKey.isValid()) {
  79. SkASSERT(result->origin() == origOrigin);
  80. if (cachedProxy) {
  81. SkASSERT(GrMipMapped::kYes == result->mipMapped() &&
  82. GrMipMapped::kNo == cachedProxy->mipMapped());
  83. // If we had a cachedProxy, that means there already is a proxy in the cache which
  84. // matches the key, but it does not have mip levels and we require them. Thus we must
  85. // remove the unique key from that proxy.
  86. SkASSERT(cachedProxy->getUniqueKey() == copyKey);
  87. proxyProvider->removeUniqueKeyFromProxy(cachedProxy.get());
  88. }
  89. proxyProvider->assignUniqueKeyToProxy(copyKey, result.get());
  90. this->didCacheCopy(copyKey, proxyProvider->contextID());
  91. }
  92. return result;
  93. }
  94. std::unique_ptr<GrFragmentProcessor> GrTextureMaker::createFragmentProcessor(
  95. const SkMatrix& textureMatrix,
  96. const SkRect& constraintRect,
  97. FilterConstraint filterConstraint,
  98. bool coordsLimitedToConstraintRect,
  99. const GrSamplerState::Filter* filterOrNullForBicubic) {
  100. const GrSamplerState::Filter* fmForDetermineDomain = filterOrNullForBicubic;
  101. if (filterOrNullForBicubic && GrSamplerState::Filter::kMipMap == *filterOrNullForBicubic &&
  102. kYes_FilterConstraint == filterConstraint) {
  103. // TODO: Here we should force a copy restricted to the constraintRect since MIP maps will
  104. // read outside the constraint rect. However, as in the adjuster case, we aren't currently
  105. // doing that.
  106. // We instead we compute the domain as though were bilerping which is only correct if we
  107. // only sample level 0.
  108. static const GrSamplerState::Filter kBilerp = GrSamplerState::Filter::kBilerp;
  109. fmForDetermineDomain = &kBilerp;
  110. }
  111. SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
  112. sk_sp<GrTextureProxy> proxy(this->refTextureProxyForParams(filterOrNullForBicubic,
  113. scaleAdjust));
  114. if (!proxy) {
  115. return nullptr;
  116. }
  117. SkMatrix adjustedMatrix = textureMatrix;
  118. adjustedMatrix.postScale(scaleAdjust[0], scaleAdjust[1]);
  119. SkRect domain;
  120. DomainMode domainMode =
  121. DetermineDomainMode(constraintRect, filterConstraint, coordsLimitedToConstraintRect,
  122. proxy.get(), fmForDetermineDomain, &domain);
  123. SkASSERT(kTightCopy_DomainMode != domainMode);
  124. return this->createFragmentProcessorForDomainAndFilter(
  125. std::move(proxy), adjustedMatrix, domainMode, domain, filterOrNullForBicubic);
  126. }