skia2/gm/colorspace.cpp
Mike Klein f8f01d44b4 SkCanvas::makeSurface() can fail
This should fix the --preAbandonGpuContext bots.

Cq-Include-Trybots: luci.skia.skia.primary:Test-Ubuntu18-Clang-Golo-GPU-QuadroP400-x86_64-Debug-All-PreAbandonGpuContext
Change-Id: I5df65e730414c670e255eb786f16a43fee49c22f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352087
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-01-08 20:49:36 +00:00

121 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright 2021 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkSurface.h"
#include "tools/Resources.h"
static const skcms_TransferFunction gTFs[] = {
SkNamedTransferFn::kSRGB,
SkNamedTransferFn::k2Dot2,
SkNamedTransferFn::kLinear,
SkNamedTransferFn::kRec2020,
SkNamedTransferFn::kPQ,
SkNamedTransferFn::kHLG,
{-3.0f, 2.0f, 2.0f, 1/0.17883277f, 0.28466892f, 0.55991073f, 3.0f }, // HLG scaled 4x
};
static const skcms_Matrix3x3 gGamuts[] = {
SkNamedGamut::kSRGB,
SkNamedGamut::kAdobeRGB,
SkNamedGamut::kDisplayP3,
SkNamedGamut::kRec2020,
SkNamedGamut::kXYZ,
};
static const int W = 128,
H = 128;
// These GMs demonstrate that our color space management is self-consistent.
// (Important to note, self-consistent, not necessarily correct in an objective sense.)
//
// Let's let,
//
// SkColorSpace* imgCS = img->colorSpace();
// SkColorSpace* dstCS = canvas->imageInfo().colorSpace();
//
// Ordinarily we'd just
//
// canvas->drawImage(img, 0,0);
//
// which would convert that img's pixels from imgCS to dstCS while drawing.
//
// But before we draw in these GMs, we convert the image to an arbitrarily different color space,
// letting midCS range over the cross-product gTFs × gGamuts:
//
// canvas->drawImage(img->makeColorSpace(midCS), 0,0);
//
// This converts img first from imgCS to midCS, treating midCS as a destination color space,
// and then draws that midCS image to the dstCS canvas, treating midCS as a source color space.
// This should draw a grid of images that look identical except for small precision loss.
//
// If instead of calling SkImage::makeColorSpace() we use SkCanvas::makeSurface() to create a
// midCS offscreen, we construct the same logical imgCS -> midCS -> dstCS transform chain while
// exercising different drawing code paths. Both strategies should draw roughly the same.
namespace {
enum Strategy { SkImage_makeColorSpace, SkCanvas_makeSurface };
}
static void draw_colorspace_gm(Strategy strategy, SkCanvas* canvas) {
if (!canvas->imageInfo().colorSpace()) {
canvas->drawString("This GM only makes sense with color-managed drawing.",
W,H, SkFont{}, SkPaint{});
return;
}
sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
if (!img) {
canvas->drawString("Could not load our test image!",
W,H, SkFont{}, SkPaint{});
return;
}
SkASSERT(img->width() == W);
SkASSERT(img->height() == H);
SkASSERT(img->colorSpace());
for (skcms_Matrix3x3 gamut : gGamuts) {
canvas->save();
for (skcms_TransferFunction tf : gTFs) {
sk_sp<SkColorSpace> midCS = SkColorSpace::MakeRGB(tf, gamut);
switch (strategy) {
case SkImage_makeColorSpace: {
canvas->drawImage(img->makeColorSpace(midCS), 0,0);
} break;
case SkCanvas_makeSurface: {
sk_sp<SkSurface> offscreen =
canvas->makeSurface(canvas->imageInfo().makeColorSpace(midCS));
if (!offscreen) {
canvas->drawString("Could not allocate offscreen surface!",
W,H, SkFont{}, SkPaint{});
return;
}
offscreen->getCanvas()->drawImage(img, 0,0);
canvas->drawImage(offscreen->makeImageSnapshot(), 0,0);
} break;
}
canvas->translate(W, 0);
}
canvas->restore();
canvas->translate(0, H);
}
}
DEF_SIMPLE_GM(colorspace, canvas, W*SK_ARRAY_COUNT(gTFs), H*SK_ARRAY_COUNT(gGamuts)) {
draw_colorspace_gm(SkImage_makeColorSpace, canvas);
}
DEF_SIMPLE_GM(colorspace2, canvas, W*SK_ARRAY_COUNT(gTFs), H*SK_ARRAY_COUNT(gGamuts)) {
draw_colorspace_gm(SkCanvas_makeSurface, canvas);
}