This has all the different source types in and working. There are many SkDiffs, but they seem to be due to better resolution.

This seems to fix all the bugs involved with make all the images produced by the codec to default to sRGB.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1967283002

Review-Url: https://codereview.chromium.org/1967283002
This commit is contained in:
herb 2016-05-13 10:04:46 -07:00 committed by Commit bot
parent 36632f46a6
commit 670f01f2fc
7 changed files with 127 additions and 53 deletions

View File

@ -146,7 +146,7 @@ struct SkBitmapFPGeneral final : public CommonBitmapFPBenchmark {
SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};
SkLinearBitmapPipeline pipeline{
fInvert, filterQuality, fXTile, fYTile, 1.0f, srcPixmap};
fInvert, filterQuality, fXTile, fYTile, SK_ColorBLACK, srcPixmap};
int count = 100;

View File

@ -121,7 +121,7 @@ static void draw_rect_fp(SkCanvas* canvas, const SkRect& r, SkColor c, const SkM
SkLinearBitmapPipeline pipeline{
inv, filterQuality,
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, 1.0f, pmsrc};
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, SK_ColorBLACK, pmsrc};
for (int y = 0; y < ir.height(); y++) {
pipeline.shadeSpan4f(0, y, dstBits, ir.width());

View File

@ -132,9 +132,9 @@ public:
// Need to ensure that our pipeline is created at a 16byte aligned address
fShaderPipeline = (SkLinearBitmapPipeline*)SkAlign16((intptr_t)fShaderStorage);
new (fShaderPipeline) SkLinearBitmapPipeline(info->fRealInvMatrix, info->fFilterQuality,
info->fTileModeX, info->fTileModeY,
fAlpha,
info->fPixmap);
info->fTileModeX, info->fTileModeY,
info->fPaintColor,
info->fPixmap);
// To implement the old shadeSpan entry-point, we need to efficiently convert our native
// floats into SkPMColor. The SkXfermode::D32Procs do exactly that.
@ -223,16 +223,6 @@ private:
///////////////////////////////////////////////////////////////////////////////////////////////////
static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) {
// These src attributes are not supported in the new 4f context (yet)
//
if (srcInfo.profileType() != kSRGB_SkColorProfileType) { return false; }
if (srcInfo.colorType() != kRGBA_8888_SkColorType
&& srcInfo.colorType() != kBGRA_8888_SkColorType
&& srcInfo.colorType() != kIndex_8_SkColorType
&& srcInfo.colorType() != kRGBA_F16_SkColorType) {
return false;
}
// If we get here, we can reasonably use either context, respect the caller's preference
//
return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType;
@ -264,12 +254,7 @@ SkShader::Context* SkBitmapProcShader::MakeContext(const SkShader& shader,
info->~SkBitmapProcInfo();
return nullptr;
}
if (info->fPixmap.colorType() != kRGBA_8888_SkColorType
&& info->fPixmap.colorType() != kBGRA_8888_SkColorType
&& info->fPixmap.colorType() != kIndex_8_SkColorType
&& info->fPixmap.colorType() != kRGBA_F16_SkColorType) {
return nullptr;
}
return new (storage) LinearPipelineContext(shader, rec, info);
} else {
void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);

View File

@ -708,39 +708,52 @@ private:
using Blender = SkLinearBitmapPipeline::BlendProcessorInterface;
template <SkColorType colorType, template <SkColorType, SkColorProfileType, typename> class Sampler>
static void choose_specific_sampler(
Blender* next,
const SkPixmap& srcPixmap,
SkLinearBitmapPipeline::SampleStage* sampleStage)
{
if (srcPixmap.info().profileType() == kSRGB_SkColorProfileType) {
using S = Sampler<colorType, kSRGB_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
} else {
using S = Sampler<colorType, kLinear_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
}
}
template<template <SkColorType, SkColorProfileType, typename> class Sampler>
static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_base(
Blender* next,
const SkPixmap& srcPixmap,
SkLinearBitmapPipeline::SampleStage* sampleStage) {
const SkColor A8TintColor,
SkLinearBitmapPipeline::SampleStage* sampleStage)
{
const SkImageInfo& imageInfo = srcPixmap.info();
switch (imageInfo.colorType()) {
case kRGBA_8888_SkColorType:
if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
using S = Sampler<kRGBA_8888_SkColorType, kSRGB_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
} else {
using S = Sampler<kRGBA_8888_SkColorType, kLinear_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
case kAlpha_8_SkColorType: {
using S = Sampler<kAlpha_8_SkColorType, kLinear_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap, A8TintColor);
}
break;
case kARGB_4444_SkColorType:
choose_specific_sampler<kARGB_4444_SkColorType, Sampler>(next, srcPixmap, sampleStage);
break;
case kRGB_565_SkColorType:
choose_specific_sampler<kRGB_565_SkColorType, Sampler>(next, srcPixmap, sampleStage);
break;
case kRGBA_8888_SkColorType:
choose_specific_sampler<kRGBA_8888_SkColorType, Sampler>(next, srcPixmap, sampleStage);
break;
case kBGRA_8888_SkColorType:
if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
using S = Sampler<kBGRA_8888_SkColorType, kSRGB_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
} else {
using S = Sampler<kBGRA_8888_SkColorType, kLinear_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
}
choose_specific_sampler<kBGRA_8888_SkColorType, Sampler>(next, srcPixmap, sampleStage);
break;
case kIndex_8_SkColorType:
if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
using S = Sampler<kIndex_8_SkColorType, kSRGB_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
} else {
using S = Sampler<kIndex_8_SkColorType, kLinear_SkColorProfileType, Blender>;
sampleStage->initStage<S>(next, srcPixmap);
}
choose_specific_sampler<kIndex_8_SkColorType, Sampler>(next, srcPixmap, sampleStage);
break;
case kGray_8_SkColorType:
choose_specific_sampler<kGray_8_SkColorType, Sampler>(next, srcPixmap, sampleStage);
break;
case kRGBA_F16_SkColorType: {
using S = Sampler<kRGBA_F16_SkColorType, kLinear_SkColorProfileType, Blender>;
@ -758,12 +771,14 @@ SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler(
Blender* next,
SkFilterQuality filterQuality,
const SkPixmap& srcPixmap,
const SkColor A8TintColor,
SkLinearBitmapPipeline::SampleStage* sampleStage)
{
if (filterQuality == kNone_SkFilterQuality) {
return choose_pixel_sampler_base<NearestNeighborSampler>(next, srcPixmap, sampleStage);
return choose_pixel_sampler_base<NearestNeighborSampler>(
next, srcPixmap, A8TintColor, sampleStage);
} else {
return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, sampleStage);
return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, A8TintColor, sampleStage);
}
}
@ -837,7 +852,7 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline(
const SkMatrix& inverse,
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
float postAlpha,
SkColor paintColor,
const SkPixmap& srcPixmap)
{
SkISize dimensions = srcPixmap.info().dimensions();
@ -863,10 +878,12 @@ SkLinearBitmapPipeline::SkLinearBitmapPipeline(
alphaType = kUnpremul_SkAlphaType;
}
float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f);
// As the stages are built, the chooser function may skip a stage. For example, with the
// identity matrix, the matrix stage is skipped, and the tilerStage is the first stage.
auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlenderStage);
auto samplerStage = choose_pixel_sampler(blenderStage, filterQuality, srcPixmap, &fSampleStage);
auto samplerStage = choose_pixel_sampler(
blenderStage, filterQuality, srcPixmap, paintColor, &fSampleStage);
auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile,
filterQuality, dx, &fTileStage);
fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage);

View File

@ -19,7 +19,7 @@ public:
const SkMatrix& inverse,
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
float postAlpha,
SkColor paintColor,
const SkPixmap& srcPixmap);

View File

@ -10,9 +10,12 @@
#include <tuple>
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkFixed.h"
#include "SkHalf.h"
#include "SkLinearBitmapPipeline_core.h"
#include "SkNx.h"
#include "SkPM4fPriv.h"
namespace {
@ -54,6 +57,53 @@ static Sk4s VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10,
// of the different SkColorTypes.
template <SkColorType colorType, SkColorProfileType colorProfile> class PixelGetter;
// Alpha handling:
// The alpha from the paint (tintColor) is used in the blend part of the pipeline to modulate
// the entire bitmap. So, the tint color is given an alpha of 1.0 so that the later alpha can
// modulate this color later.
template <>
class PixelGetter<kAlpha_8_SkColorType, kLinear_SkColorProfileType> {
public:
using Element = uint8_t;
PixelGetter(const SkPixmap& srcPixmap, SkColor tintColor)
: fTintColor{set_alpha(Sk4f_from_SkColor(tintColor), 1.0f)} { }
Sk4f getPixelAt(const uint8_t* src) {
return fTintColor * (*src * (1.0f/255.0f));
}
private:
const Sk4f fTintColor;
};
template <SkColorProfileType colorProfile>
class PixelGetter<kRGB_565_SkColorType, colorProfile> {
public:
using Element = uint16_t;
PixelGetter(const SkPixmap& srcPixmap) { }
Sk4f getPixelAt(const uint16_t* src) {
SkPMColor pixel = SkPixel16ToPixel32(*src);
return colorProfile == kSRGB_SkColorProfileType
? Sk4f_fromS32(pixel)
: Sk4f_fromL32(pixel);
}
};
template <SkColorProfileType colorProfile>
class PixelGetter<kARGB_4444_SkColorType, colorProfile> {
public:
using Element = uint16_t;
PixelGetter(const SkPixmap& srcPixmap) { }
Sk4f getPixelAt(const uint16_t* src) {
SkPMColor pixel = SkPixel4444ToPixel32(*src);
return colorProfile == kSRGB_SkColorProfileType
? Sk4f_fromS32(pixel)
: Sk4f_fromL32(pixel);
}
};
template <SkColorProfileType colorProfile>
class PixelGetter<kRGBA_8888_SkColorType, colorProfile> {
public:
@ -77,7 +127,7 @@ public:
Sk4f pixel = colorProfile == kSRGB_SkColorProfileType
? Sk4f_fromS32(*src)
: Sk4f_fromL32(*src);
return SkNx_shuffle<2, 1, 0, 3>(pixel);
return swizzle_rb(pixel);
}
};
@ -128,6 +178,21 @@ private:
Sk4f* fColorTable;
};
template <SkColorProfileType colorProfile>
class PixelGetter<kGray_8_SkColorType, colorProfile> {
public:
using Element = uint8_t;
PixelGetter(const SkPixmap& srcPixmap) { }
Sk4f getPixelAt(const uint8_t* src) {
float gray = *src * (1.0f/255.0f);
Sk4f pixel = Sk4f{gray, gray, gray, 1.0f};
return colorProfile == kSRGB_SkColorProfileType
? srgb_to_linear(pixel)
: pixel;
}
};
template <>
class PixelGetter<kRGBA_F16_SkColorType, kLinear_SkColorProfileType> {
public:
@ -145,10 +210,11 @@ template <SkColorType colorType, SkColorProfileType colorProfile>
class PixelAccessor {
using Element = typename PixelGetter<colorType, colorProfile>::Element;
public:
PixelAccessor(const SkPixmap& srcPixmap)
template <typename... Args>
PixelAccessor(const SkPixmap& srcPixmap, Args&&... args)
: fSrc{static_cast<const Element*>(srcPixmap.addr())}
, fWidth{srcPixmap.rowBytesAsPixels()}
, fGetter{srcPixmap} { }
, fGetter{srcPixmap, std::move<Args>(args)...} { }
void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
@ -711,11 +777,10 @@ private:
}
}
Next* const fNext;
Next* const fNext;
PixelAccessor<colorType, colorProfile> fStrategy;
};
} // namespace
#endif // SkLinearBitmapPipeline_sampler_DEFINED

View File

@ -62,6 +62,13 @@ static inline Sk4f Sk4f_fromS32(uint32_t src) {
return srgb_to_linear(to_4f(src) * Sk4f(1.0f/255));
}
// Color handling:
// SkColor has an ordering of (b, g, r, a) if cast to an Sk4f, so the code swizzles r and b to
// produce the needed (r, g, b, a) ordering.
static inline Sk4f Sk4f_from_SkColor(SkColor color) {
return swizzle_rb(gTreatSkColorAsSRGB ? Sk4f_fromS32(color) : Sk4f_fromL32(color));
}
static inline uint32_t Sk4f_toL32(const Sk4f& x4) {
return to_4b(x4 * Sk4f(255) + Sk4f(0.5f));
}