diff options
-rw-r--r-- | gm/gammaencodedpremul.cpp | 131 | ||||
-rw-r--r-- | gn/gm.gni | 1 |
2 files changed, 132 insertions, 0 deletions
diff --git a/gm/gammaencodedpremul.cpp b/gm/gammaencodedpremul.cpp new file mode 100644 index 0000000000..327368f879 --- /dev/null +++ b/gm/gammaencodedpremul.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkColorSpaceXform.h" +#include "SkColorSpaceXformPriv.h" +#include "SkOpts.h" +#include "SkUtils.h" + +static void clamp_to_alpha(uint32_t* pixels, int count) { + for (int i = 0; i < count; i++) { + uint8_t a = SkGetPackedA32(pixels[i]); + uint8_t r = SkGetPackedR32(pixels[i]); + uint8_t g = SkGetPackedG32(pixels[i]); + uint8_t b = SkGetPackedB32(pixels[i]); + pixels[i] = SkPackARGB32(a, + SkTMin(a, r), + SkTMin(a, g), + SkTMin(a, b)); + } +} + +class GammaEncodedPremulGM : public skiagm::GM { +public: + GammaEncodedPremulGM(sk_sp<SkColorSpace> dst, sk_sp<SkColorSpace> src, const char* desc) + : fDstSpace(dst) + , fSrcSpace(src) + , fXform(SkColorSpaceXform::New(src.get(), dst.get())) + , fName(SkStringPrintf("gamma_encoded_premul_dst-v-src_%s", desc)) + { + int i = 0; + for (int r = 0; r < kColorSteps; r++) { + for (int g = 0; g < kColorSteps; g++) { + for (int b = 0; b < kColorSteps; b++) { + fColors[i++] = SkColorSetARGBInline(0xFF, + r * kColorScale, + g * kColorScale, + b * kColorScale); + } + } + } + + } + +protected: + virtual SkISize onISize() override { + return SkISize::Make(kAlphaMax, kNumColors * 2 * kStripeHeight); + } + + SkString onShortName() override { + return fName; + } + + void onDraw(SkCanvas* canvas) override { + if (canvas->imageInfo().isOpaque()) { + return; + } + + SkBitmap bitmap; + SkImageInfo bitmapInfo = SkImageInfo::MakeN32Premul(kAlphaMax, 1, + canvas->imageInfo().refColorSpace()); + bitmap.allocPixels(bitmapInfo); + uint32_t* pixels = bitmap.getAddr32(0, 0); + + for (int i = 0; i < kNumColors; i++) { + // Create an entire row of the same color, with the alpha from 0 to kAlphaMax. + uint32_t row[kAlphaMax]; + sk_memset32(row, fColors[i], kAlphaMax); + for (int a = 0; a < kAlphaMax; a++) { + row[a] = (row[a] & 0x00FFFFFF) | (a << 24); + } + + // Tranform row to dst, then premultiply. + fXform->apply(select_xform_format(kN32_SkColorType), pixels, + SkColorSpaceXform::kBGRA_8888_ColorFormat, row, kAlphaMax, + kUnpremul_SkAlphaType); + SkOpts::RGBA_to_rgbA(pixels, pixels, kAlphaMax); + + // Write the dst space premultiplied row to the canvas. + for (int j = 0; j < kStripeHeight; j++) { + canvas->drawBitmap(bitmap, 0, 2 * i * kStripeHeight + j); + } + + // Premultiply, then transform the row to dst. + SkOpts::RGBA_to_rgbA(pixels, row, kAlphaMax); + fXform->apply(select_xform_format(kN32_SkColorType), pixels, + SkColorSpaceXform::kBGRA_8888_ColorFormat, pixels, kAlphaMax, + kUnpremul_SkAlphaType); + clamp_to_alpha(pixels, kAlphaMax); + + // Write the src space premultiplied row to the canvas. + for (int j = 0; j < kStripeHeight; j++) { + canvas->drawBitmap(bitmap, 0, (2 * i + 1) * kStripeHeight + j); + } + } + } + +private: + static constexpr int kColorSteps = 4; + static constexpr int kNumColors = kColorSteps * kColorSteps * kColorSteps; + static constexpr int kColorScale = 255 / (kColorSteps - 1); + static constexpr int kStripeHeight = 10; + static constexpr int kAlphaMax = 255; + + sk_sp<SkColorSpace> fDstSpace; + sk_sp<SkColorSpace> fSrcSpace; + std::unique_ptr<SkColorSpaceXform> fXform; + SkString fName; + SkColor fColors[kNumColors]; + + typedef GM INHERITED; +}; + +DEF_GM(return new GammaEncodedPremulGM(SkColorSpace::MakeSRGB(), + SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kRec2020_Gamut), + "toWideGamut");) +DEF_GM(return new GammaEncodedPremulGM(SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, + SkColorSpace::kRec2020_Gamut), SkColorSpace::MakeSRGB(), "fromWideGamut");) +DEF_GM(return new GammaEncodedPremulGM(SkColorSpace::MakeSRGB(), + SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, SkColorSpace::kSRGB_Gamut), + "toLinear");) +DEF_GM(return new GammaEncodedPremulGM( + SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, SkColorSpace::kSRGB_Gamut), + SkColorSpace::MakeSRGB(), "fromLinear");) +DEF_GM(return new GammaEncodedPremulGM( + SkColorSpace::MakeRGB({ 1.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, + SkColorSpace::kSRGB_Gamut), SkColorSpace::MakeSRGB(), "from1.8");) @@ -129,6 +129,7 @@ gm_sources = [ "$_gm/fontscaler.cpp", "$_gm/fontscalerdistortable.cpp", "$_gm/gamma.cpp", + "$_gm/gammaencodedpremul.cpp", "$_gm/gammatext.cpp", "$_gm/gamut.cpp", "$_gm/gaussianedge.cpp", |