2017-03-08 16:31:06 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
2017-05-03 19:16:58 +00:00
|
|
|
#include "SkColorPriv.h"
|
2017-03-08 16:31:06 +00:00
|
|
|
#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++) {
|
2018-04-24 18:47:16 +00:00
|
|
|
fColors[i++] = SkColorSetRGB(r * kColorScale,
|
|
|
|
g * kColorScale,
|
|
|
|
b * kColorScale);
|
2017-03-08 16:31:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2017-07-11 13:53:40 +00:00
|
|
|
bitmap.notifyPixelsChanged();
|
2017-03-08 16:31:06 +00:00
|
|
|
|
|
|
|
// 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);
|
2017-07-11 13:53:40 +00:00
|
|
|
bitmap.notifyPixelsChanged();
|
2017-03-08 16:31:06 +00:00
|
|
|
|
|
|
|
// 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");)
|