aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/gammaencodedpremul.cpp131
-rw-r--r--gn/gm.gni1
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");)
diff --git a/gn/gm.gni b/gn/gm.gni
index 32c22d7f06..3b94be509e 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -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",