8499e372ce
While I was fixing up Chrome's uses, I found some failures there that I did not see in Skia, and tracked them down to a few other places where we include SkColorSpace and it is not strictly necessary - SkCustomMesh.h - GrColorInfo.h - GrColorSpaceXform.h - SkColorSpaceXformSteps.h For these files (and their .cpp files), I added enforcement of include-what-you-use, and then fixed the myriad of places which were depending on these transitive includes. One change to help Chrome is the manual overloads of SkImage::MakeFromAdoptedTexture instead of using default parameters. This makes it so callers of that function do not need to include SkColorSpace if they were going to pass nullptr for it anyway. Bug: skia:13052 Change-Id: I16bf8ed5e258225d887f562f2c189623b1ca9c23 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/527056 Reviewed-by: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Kevin Lubick <kjlubick@google.com>
129 lines
3.7 KiB
C++
129 lines
3.7 KiB
C++
/*
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "include/core/SkColorSpace.h"
|
|
#include "include/core/SkTypes.h"
|
|
#include "src/core/SkColorSpaceXformSteps.h"
|
|
#include "src/core/SkRasterPipeline.h"
|
|
#include "tests/Test.h"
|
|
|
|
#include <math.h>
|
|
|
|
DEF_TEST(srgb_roundtrip, r) {
|
|
uint32_t reds[256];
|
|
for (int i = 0; i < 256; i++) {
|
|
reds[i] = i;
|
|
}
|
|
|
|
SkRasterPipeline_MemoryCtx ptr = { reds, 0 };
|
|
|
|
sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB(),
|
|
linear = sRGB->makeLinearGamma();
|
|
const SkAlphaType upm = kUnpremul_SkAlphaType;
|
|
|
|
SkColorSpaceXformSteps linearize{ sRGB.get(),upm, linear.get(),upm},
|
|
reencode {linear.get(),upm, sRGB.get(),upm};
|
|
|
|
SkRasterPipeline_<256> p;
|
|
p.append(SkRasterPipeline::load_8888, &ptr);
|
|
linearize.apply(&p);
|
|
reencode .apply(&p);
|
|
p.append(SkRasterPipeline::store_8888, &ptr);
|
|
|
|
p.run(0,0,256,1);
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
if (reds[i] != (uint32_t)i) {
|
|
ERRORF(r, "%d doesn't round trip, %d", i, reds[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
DEF_TEST(srgb_edge_cases, r) {
|
|
// We need to run at least 4 pixels to make sure we hit all specializations.
|
|
float colors[4][4] = { {0,1,1,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} };
|
|
auto& color = colors[0];
|
|
|
|
SkRasterPipeline_MemoryCtx dst = { &color, 0 };
|
|
|
|
sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB(),
|
|
linear = sRGB->makeLinearGamma();
|
|
const SkAlphaType upm = kUnpremul_SkAlphaType;
|
|
|
|
SkColorSpaceXformSteps steps {linear.get(),upm, sRGB.get(),upm};
|
|
|
|
SkSTArenaAlloc<256> alloc;
|
|
SkRasterPipeline p(&alloc);
|
|
p.append_constant_color(&alloc, color);
|
|
steps.apply(&p);
|
|
p.append(SkRasterPipeline::store_f32, &dst);
|
|
p.run(0,0,4,1);
|
|
|
|
if (color[0] != 0.0f) {
|
|
ERRORF(r, "expected to_srgb() to map 0.0f to 0.0f, got %f", color[0]);
|
|
}
|
|
if (color[1] != 1.0f) {
|
|
float f = color[1];
|
|
uint32_t x;
|
|
memcpy(&x, &f, 4);
|
|
ERRORF(r, "expected to_srgb() to map 1.0f to 1.0f, got %f (%08x)", color[1], x);
|
|
}
|
|
}
|
|
|
|
// Linearize and then re-encode pixel values, testing that the output is close to the input.
|
|
DEF_TEST(srgb_roundtrip_extended, r) {
|
|
static const int kSteps = 128;
|
|
SkColor4f rgba[kSteps];
|
|
|
|
auto expected = [=](int i) {
|
|
float scale = 10000.0f / (3*kSteps);
|
|
return SkColor4f{
|
|
(3*i+0) * scale,
|
|
(3*i+1) * scale,
|
|
(3*i+2) * scale,
|
|
1.0f,
|
|
};
|
|
};
|
|
|
|
for (int i = 0; i < kSteps; i++) {
|
|
rgba[i] = expected(i);
|
|
}
|
|
|
|
SkRasterPipeline_MemoryCtx ptr = { rgba, 0 };
|
|
|
|
sk_sp<SkColorSpace> cs = SkColorSpace::MakeSRGB();
|
|
sk_sp<SkColorSpace> linear = cs->makeLinearGamma();
|
|
const SkAlphaType upm = kUnpremul_SkAlphaType;
|
|
|
|
SkColorSpaceXformSteps linearize{ cs.get(),upm, linear.get(),upm},
|
|
reencode {linear.get(),upm, cs.get(),upm};
|
|
|
|
SkRasterPipeline_<256> p;
|
|
p.append(SkRasterPipeline::load_f32, &ptr);
|
|
linearize.apply(&p);
|
|
reencode .apply(&p);
|
|
p.append(SkRasterPipeline::store_f32, &ptr);
|
|
p.run(0,0,kSteps,1);
|
|
|
|
auto close = [=](float x, float y) {
|
|
return x == y
|
|
|| (x/y < 1.001f && y/x < 1.001f);
|
|
};
|
|
|
|
for (int i = 0; i < kSteps; i++) {
|
|
SkColor4f want = expected(i);
|
|
#if 0
|
|
SkDebugf("got %g %g %g, want %g %g %g\n",
|
|
rgba[i].fR, rgba[i].fG, rgba[i].fB,
|
|
want.fR, want.fG, want.fB);
|
|
#endif
|
|
REPORTER_ASSERT(r, close(rgba[i].fR, want.fR));
|
|
REPORTER_ASSERT(r, close(rgba[i].fG, want.fG));
|
|
REPORTER_ASSERT(r, close(rgba[i].fB, want.fB));
|
|
}
|
|
}
|