GrColorSpaceXform.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 "include/core/SkColorSpace.h"
  8. #include "src/core/SkColorSpacePriv.h"
  9. #include "src/gpu/GrColorSpaceXform.h"
  10. #include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
  11. #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
  12. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  13. sk_sp<GrColorSpaceXform> GrColorSpaceXform::Make(SkColorSpace* src, SkAlphaType srcAT,
  14. SkColorSpace* dst, SkAlphaType dstAT) {
  15. SkColorSpaceXformSteps steps(src, srcAT, dst, dstAT);
  16. return steps.flags.mask() == 0 ? nullptr /* Noop transform */
  17. : sk_make_sp<GrColorSpaceXform>(steps);
  18. }
  19. bool GrColorSpaceXform::Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b) {
  20. if (a == b) {
  21. return true;
  22. }
  23. if (!a || !b || a->fSteps.flags.mask() != b->fSteps.flags.mask()) {
  24. return false;
  25. }
  26. if (a->fSteps.flags.linearize &&
  27. 0 != memcmp(&a->fSteps.srcTF, &b->fSteps.srcTF, sizeof(a->fSteps.srcTF))) {
  28. return false;
  29. }
  30. if (a->fSteps.flags.gamut_transform &&
  31. 0 != memcmp(&a->fSteps.src_to_dst_matrix, &b->fSteps.src_to_dst_matrix,
  32. sizeof(a->fSteps.src_to_dst_matrix))) {
  33. return false;
  34. }
  35. if (a->fSteps.flags.encode &&
  36. 0 != memcmp(&a->fSteps.dstTFInv, &b->fSteps.dstTFInv, sizeof(a->fSteps.dstTFInv))) {
  37. return false;
  38. }
  39. return true;
  40. }
  41. SkColor4f GrColorSpaceXform::apply(const SkColor4f& srcColor) {
  42. SkColor4f result = srcColor;
  43. fSteps.apply(result.vec());
  44. return result;
  45. }
  46. //////////////////////////////////////////////////////////////////////////////
  47. class GrGLColorSpaceXformEffect : public GrGLSLFragmentProcessor {
  48. public:
  49. void emitCode(EmitArgs& args) override {
  50. const GrColorSpaceXformEffect& csxe = args.fFp.cast<GrColorSpaceXformEffect>();
  51. GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
  52. GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
  53. fColorSpaceHelper.emitCode(uniformHandler, csxe.colorXform());
  54. if (this->numChildProcessors()) {
  55. SkString childColor("src_color");
  56. this->emitChild(0, &childColor, args);
  57. SkString xformedColor;
  58. fragBuilder->appendColorGamutXform(&xformedColor, childColor.c_str(), &fColorSpaceHelper);
  59. fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, xformedColor.c_str(),
  60. args.fInputColor);
  61. } else {
  62. SkString xformedColor;
  63. fragBuilder->appendColorGamutXform(&xformedColor, args.fInputColor, &fColorSpaceHelper);
  64. fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, xformedColor.c_str());
  65. }
  66. }
  67. private:
  68. void onSetData(const GrGLSLProgramDataManager& pdman,
  69. const GrFragmentProcessor& processor) override {
  70. const GrColorSpaceXformEffect& csxe = processor.cast<GrColorSpaceXformEffect>();
  71. fColorSpaceHelper.setData(pdman, csxe.colorXform());
  72. }
  73. GrGLSLColorSpaceXformHelper fColorSpaceHelper;
  74. typedef GrGLSLFragmentProcessor INHERITED;
  75. };
  76. //////////////////////////////////////////////////////////////////////////////
  77. GrColorSpaceXformEffect::GrColorSpaceXformEffect(std::unique_ptr<GrFragmentProcessor> child,
  78. sk_sp<GrColorSpaceXform> colorXform)
  79. : INHERITED(kGrColorSpaceXformEffect_ClassID, OptFlags(child.get()))
  80. , fColorXform(std::move(colorXform)) {
  81. if (child) {
  82. this->registerChildProcessor(std::move(child));
  83. }
  84. }
  85. std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::clone() const {
  86. std::unique_ptr<GrFragmentProcessor> child =
  87. this->numChildProcessors() ? this->childProcessor(0).clone() : nullptr;
  88. return std::unique_ptr<GrFragmentProcessor>(
  89. new GrColorSpaceXformEffect(std::move(child), fColorXform));
  90. }
  91. bool GrColorSpaceXformEffect::onIsEqual(const GrFragmentProcessor& s) const {
  92. const GrColorSpaceXformEffect& other = s.cast<GrColorSpaceXformEffect>();
  93. return GrColorSpaceXform::Equals(fColorXform.get(), other.fColorXform.get());
  94. }
  95. void GrColorSpaceXformEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
  96. GrProcessorKeyBuilder* b) const {
  97. b->add32(GrColorSpaceXform::XformKey(fColorXform.get()));
  98. }
  99. GrGLSLFragmentProcessor* GrColorSpaceXformEffect::onCreateGLSLInstance() const {
  100. return new GrGLColorSpaceXformEffect();
  101. }
  102. GrFragmentProcessor::OptimizationFlags GrColorSpaceXformEffect::OptFlags(
  103. const GrFragmentProcessor* child) {
  104. // TODO: Implement constant output for constant input
  105. if (child) {
  106. OptimizationFlags flags = kNone_OptimizationFlags;
  107. if (child->compatibleWithCoverageAsAlpha()) {
  108. flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
  109. }
  110. if (child->preservesOpaqueInput()) {
  111. flags |= kPreservesOpaqueInput_OptimizationFlag;
  112. }
  113. return flags;
  114. } else {
  115. return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
  116. kPreservesOpaqueInput_OptimizationFlag;
  117. }
  118. }
  119. std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make(SkColorSpace* src,
  120. SkAlphaType srcAT,
  121. SkColorSpace* dst,
  122. SkAlphaType dstAT) {
  123. auto xform = GrColorSpaceXform::Make(src, srcAT,
  124. dst, dstAT);
  125. if (!xform) {
  126. return nullptr;
  127. }
  128. return std::unique_ptr<GrFragmentProcessor>(new GrColorSpaceXformEffect(nullptr,
  129. std::move(xform)));
  130. }
  131. std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make(
  132. std::unique_ptr<GrFragmentProcessor> child,
  133. SkColorSpace* src, SkAlphaType srcAT, SkColorSpace* dst) {
  134. if (!child) {
  135. return nullptr;
  136. }
  137. auto xform = GrColorSpaceXform::Make(src, srcAT,
  138. dst, kPremul_SkAlphaType);
  139. if (!xform) {
  140. return child;
  141. }
  142. return std::unique_ptr<GrFragmentProcessor>(new GrColorSpaceXformEffect(std::move(child),
  143. std::move(xform)));
  144. }
  145. std::unique_ptr<GrFragmentProcessor> GrColorSpaceXformEffect::Make(
  146. std::unique_ptr<GrFragmentProcessor> child, sk_sp<GrColorSpaceXform> colorXform) {
  147. if (!child) {
  148. return nullptr;
  149. }
  150. if (!colorXform) {
  151. return child;
  152. }
  153. return std::unique_ptr<GrFragmentProcessor>(new GrColorSpaceXformEffect(std::move(child),
  154. std::move(colorXform)));
  155. }