SkColorFilter_Matrix.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Copyright 2011 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/SkRefCnt.h"
  8. #include "include/core/SkString.h"
  9. #include "include/core/SkUnPreMultiply.h"
  10. #include "include/effects/SkColorMatrix.h"
  11. #include "include/private/SkColorData.h"
  12. #include "include/private/SkNx.h"
  13. #include "src/core/SkColorFilter_Matrix.h"
  14. #include "src/core/SkRasterPipeline.h"
  15. #include "src/core/SkReadBuffer.h"
  16. #include "src/core/SkWriteBuffer.h"
  17. void SkColorFilter_Matrix::initState() {
  18. const float* srcA = fMatrix + 15;
  19. fFlags = (srcA[0] == 0 && srcA[1] == 0 && srcA[2] == 0 && srcA[3] == 1 && srcA[4] == 0)
  20. ? kAlphaUnchanged_Flag : 0;
  21. }
  22. SkColorFilter_Matrix::SkColorFilter_Matrix(const float array[20]) {
  23. memcpy(fMatrix, array, 20 * sizeof(float));
  24. this->initState();
  25. }
  26. uint32_t SkColorFilter_Matrix::getFlags() const {
  27. return this->INHERITED::getFlags() | fFlags;
  28. }
  29. void SkColorFilter_Matrix::flatten(SkWriteBuffer& buffer) const {
  30. SkASSERT(sizeof(fMatrix)/sizeof(float) == 20);
  31. buffer.writeScalarArray(fMatrix, 20);
  32. }
  33. sk_sp<SkFlattenable> SkColorFilter_Matrix::CreateProc(SkReadBuffer& buffer) {
  34. float matrix[20];
  35. if (buffer.readScalarArray(matrix, 20)) {
  36. return SkColorFilters::Matrix(matrix);
  37. }
  38. return nullptr;
  39. }
  40. bool SkColorFilter_Matrix::onAsAColorMatrix(float matrix[20]) const {
  41. if (matrix) {
  42. memcpy(matrix, fMatrix, 20 * sizeof(float));
  43. }
  44. return true;
  45. }
  46. bool SkColorFilter_Matrix::onAppendStages(const SkStageRec& rec,
  47. bool shaderIsOpaque) const {
  48. const bool willStayOpaque = shaderIsOpaque && (fFlags & kAlphaUnchanged_Flag);
  49. SkRasterPipeline* p = rec.fPipeline;
  50. if (!shaderIsOpaque) { p->append(SkRasterPipeline::unpremul); }
  51. if ( true) { p->append(SkRasterPipeline::matrix_4x5, fMatrix); }
  52. if ( true) { p->append(SkRasterPipeline::clamp_0); }
  53. if ( true) { p->append(SkRasterPipeline::clamp_1); }
  54. if (!willStayOpaque) { p->append(SkRasterPipeline::premul); }
  55. return true;
  56. }
  57. #if SK_SUPPORT_GPU
  58. #include "src/gpu/effects/generated/GrColorMatrixFragmentProcessor.h"
  59. std::unique_ptr<GrFragmentProcessor> SkColorFilter_Matrix::asFragmentProcessor(
  60. GrRecordingContext*, const GrColorSpaceInfo&) const {
  61. return GrColorMatrixFragmentProcessor::Make(fMatrix,
  62. /* premulInput = */ true,
  63. /* clampRGBOutput = */ true,
  64. /* premulOutput = */ true);
  65. }
  66. #endif
  67. ///////////////////////////////////////////////////////////////////////////////
  68. sk_sp<SkColorFilter> SkColorFilters::Matrix(const float array[20]) {
  69. if (!sk_floats_are_finite(array, 20)) {
  70. return nullptr;
  71. }
  72. return sk_sp<SkColorFilter>(new SkColorFilter_Matrix(array));
  73. }
  74. sk_sp<SkColorFilter> SkColorFilters::Matrix(const SkColorMatrix& cm) {
  75. return Matrix(cm.fMat);
  76. }
  77. void SkColorFilter_Matrix::RegisterFlattenables() {
  78. SK_REGISTER_FLATTENABLE(SkColorFilter_Matrix);
  79. // This subclass was removed 4/2019
  80. SkFlattenable::Register("SkColorMatrixFilterRowMajor255",
  81. [](SkReadBuffer& buffer) -> sk_sp<SkFlattenable> {
  82. float matrix[20];
  83. if (buffer.readScalarArray(matrix, 20)) {
  84. matrix[ 4] *= (1.0f/255);
  85. matrix[ 9] *= (1.0f/255);
  86. matrix[14] *= (1.0f/255);
  87. matrix[19] *= (1.0f/255);
  88. return SkColorFilters::Matrix(matrix);
  89. }
  90. return nullptr;
  91. });
  92. }