aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar herb <herb@google.com>2016-05-13 10:04:46 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-13 10:04:46 -0700
commit670f01f2fc88f02ec9a6f1b47af29daeadc3b301 (patch)
tree2540624e093c7445b786d744898fe27493ddc1a1 /src
parent36632f46a6d87d9d9bd5e0ab65350638e8cfb65c (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmapProcShader.cpp23
-rw-r--r--src/core/SkLinearBitmapPipeline.cpp69
-rw-r--r--src/core/SkLinearBitmapPipeline.h2
-rw-r--r--src/core/SkLinearBitmapPipeline_sample.h75
-rw-r--r--src/core/SkPM4fPriv.h7
5 files changed, 125 insertions, 51 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index d230d147cb..ae973a2a59 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -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);
diff --git a/src/core/SkLinearBitmapPipeline.cpp b/src/core/SkLinearBitmapPipeline.cpp
index 6bb88d1bf6..dfc9aa8376 100644
--- a/src/core/SkLinearBitmapPipeline.cpp
+++ b/src/core/SkLinearBitmapPipeline.cpp
@@ -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);
diff --git a/src/core/SkLinearBitmapPipeline.h b/src/core/SkLinearBitmapPipeline.h
index a6a84b5c8c..853e56fd1b 100644
--- a/src/core/SkLinearBitmapPipeline.h
+++ b/src/core/SkLinearBitmapPipeline.h
@@ -19,7 +19,7 @@ public:
const SkMatrix& inverse,
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
- float postAlpha,
+ SkColor paintColor,
const SkPixmap& srcPixmap);
diff --git a/src/core/SkLinearBitmapPipeline_sample.h b/src/core/SkLinearBitmapPipeline_sample.h
index 78af038660..cf13fd57be 100644
--- a/src/core/SkLinearBitmapPipeline_sample.h
+++ b/src/core/SkLinearBitmapPipeline_sample.h
@@ -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
diff --git a/src/core/SkPM4fPriv.h b/src/core/SkPM4fPriv.h
index b75dc71654..9650646d95 100644
--- a/src/core/SkPM4fPriv.h
+++ b/src/core/SkPM4fPriv.h
@@ -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));
}