add srgb gamma colorfilters
... faster and more accurate than using SkTableColorFilter todo: update blink after this lands Bug:737981 Change-Id: I55b5c60dd23b9d2cbe9d60f83c74be1a8f3dcfcf Reviewed-on: https://skia-review.googlesource.com/21368 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
2d171397f8
commit
412cda7379
@ -113,6 +113,14 @@ public:
|
||||
*/
|
||||
static sk_sp<SkColorFilter> MakeMatrixFilterRowMajor255(const SkScalar array[20]);
|
||||
|
||||
/** Construct a colorfilter that applies the srgb gamma curve to the RGB channels */
|
||||
static sk_sp<SkColorFilter> MakeLinearToSRGBGamma();
|
||||
|
||||
/** Construct a colorfilter that applies the inverse of the srgb gamma curve to the
|
||||
* RGB channels
|
||||
*/
|
||||
static sk_sp<SkColorFilter> MakeSRGBToLinearGamma();
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
/**
|
||||
* A subclass may implement this factory function to work with the GPU backend. It returns
|
||||
|
@ -370,7 +370,7 @@ public:
|
||||
SkPaint gammaPaint;
|
||||
gammaPaint.setBlendMode(SkBlendMode::kSrc);
|
||||
if (doGamma) {
|
||||
gammaPaint.setColorFilter(sk_tool_utils::MakeLinearToSRGBColorFilter());
|
||||
gammaPaint.setColorFilter(SkColorFilter::MakeLinearToSRGBGamma());
|
||||
}
|
||||
|
||||
gpuCanvas->drawImage(offscreenImage, 0, 0, &gammaPaint);
|
||||
|
@ -174,8 +174,6 @@ sk_sp<SkFlattenable> SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) {
|
||||
return MakeComposeFilter(std::move(outer), std::move(inner));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer,
|
||||
sk_sp<SkColorFilter> inner) {
|
||||
if (!outer) {
|
||||
@ -198,9 +196,91 @@ sk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer
|
||||
return sk_sp<SkColorFilter>(new SkComposeColorFilter(std::move(outer), std::move(inner),count));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "../gpu/effects/GrSRGBEffect.h"
|
||||
#endif
|
||||
|
||||
class SkSRGBGammaColorFilter : public SkColorFilter {
|
||||
public:
|
||||
enum class Direction {
|
||||
kLinearToSRGB,
|
||||
kSRGBToLinear,
|
||||
};
|
||||
SkSRGBGammaColorFilter(Direction dir) : fDir(dir) {}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* x, SkColorSpace* cs) const override {
|
||||
switch (fDir) {
|
||||
case Direction::kLinearToSRGB:
|
||||
return GrSRGBEffect::Make(GrSRGBEffect::Mode::kLinearToSRGB);
|
||||
case Direction::kSRGBToLinear:
|
||||
return GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSRGBGammaColorFilter)
|
||||
|
||||
void onAppendStages(SkRasterPipeline* p, SkColorSpace*, SkArenaAlloc* alloc,
|
||||
bool shaderIsOpaque) const override {
|
||||
switch (fDir) {
|
||||
case Direction::kLinearToSRGB:
|
||||
p->append(SkRasterPipeline::to_srgb);
|
||||
break;
|
||||
case Direction::kSRGBToLinear:
|
||||
p->append_from_srgb(shaderIsOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer& buffer) const override {
|
||||
buffer.write32(static_cast<uint32_t>(fDir));
|
||||
}
|
||||
|
||||
private:
|
||||
const Direction fDir;
|
||||
|
||||
friend class SkColorFilter;
|
||||
typedef SkColorFilter INHERITED;
|
||||
};
|
||||
|
||||
sk_sp<SkFlattenable> SkSRGBGammaColorFilter::CreateProc(SkReadBuffer& buffer) {
|
||||
uint32_t dir = buffer.read32();
|
||||
if (dir <= 1) {
|
||||
return sk_sp<SkFlattenable>(new SkSRGBGammaColorFilter(static_cast<Direction>(dir)));
|
||||
}
|
||||
buffer.validate(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifndef SK_IGNORE_TO_STRING
|
||||
void SkSRGBGammaColorFilter::toString(SkString* str) const {
|
||||
str->append("srgbgamma");
|
||||
}
|
||||
#endif
|
||||
|
||||
sk_sp<SkColorFilter> SkColorFilter::MakeLinearToSRGBGamma() {
|
||||
return sk_sp<SkColorFilter>(new SkSRGBGammaColorFilter(
|
||||
SkSRGBGammaColorFilter::Direction::kLinearToSRGB));
|
||||
}
|
||||
|
||||
sk_sp<SkColorFilter> SkColorFilter::MakeSRGBToLinearGamma() {
|
||||
return sk_sp<SkColorFilter>(new SkSRGBGammaColorFilter(
|
||||
SkSRGBGammaColorFilter::Direction::kSRGBToLinear));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkModeColorFilter.h"
|
||||
|
||||
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter)
|
||||
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter)
|
||||
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter)
|
||||
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSRGBGammaColorFilter)
|
||||
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
|
||||
|
@ -546,16 +546,6 @@ sk_sp<GrFragmentProcessor> SkTable_ColorFilter::asFragmentProcessor(GrContext* c
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_CPU_BENDIAN
|
||||
#else
|
||||
#define SK_A32_INDEX (3 - (SK_A32_SHIFT >> 3))
|
||||
#define SK_R32_INDEX (3 - (SK_R32_SHIFT >> 3))
|
||||
#define SK_G32_INDEX (3 - (SK_G32_SHIFT >> 3))
|
||||
#define SK_B32_INDEX (3 - (SK_B32_SHIFT >> 3))
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sk_sp<SkColorFilter> SkTableColorFilter::Make(const uint8_t table[256]) {
|
||||
return sk_make_sp<SkTable_ColorFilter>(table, table, table, table);
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkUtils.h"
|
||||
#include "sk_tool_utils.h"
|
||||
|
||||
/** convert 0..1 linear value to 0..1 srgb */
|
||||
static float linear_to_srgb(float linear) {
|
||||
@ -112,8 +111,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ApplyGamma, reporter, ctxInfo) {
|
||||
|
||||
SkPaint gammaPaint;
|
||||
gammaPaint.setBlendMode(SkBlendMode::kSrc);
|
||||
gammaPaint.setColorFilter(toSRGB ? sk_tool_utils::MakeLinearToSRGBColorFilter()
|
||||
: sk_tool_utils::MakeSRGBToLinearColorFilter());
|
||||
gammaPaint.setColorFilter(toSRGB ? SkColorFilter::MakeLinearToSRGBGamma()
|
||||
: SkColorFilter::MakeSRGBToLinearGamma());
|
||||
|
||||
dstCanvas->drawBitmap(bm, 0, 0, &gammaPaint);
|
||||
dstCanvas->flush();
|
||||
|
@ -22,38 +22,6 @@
|
||||
|
||||
DEFINE_bool(portableFonts, false, "Use portable fonts");
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "effects/GrSRGBEffect.h"
|
||||
#include "SkColorFilter.h"
|
||||
|
||||
// Color filter that just wraps GrSRGBEffect
|
||||
class SkSRGBColorFilter : public SkColorFilter {
|
||||
public:
|
||||
static sk_sp<SkColorFilter> Make(GrSRGBEffect::Mode mode) {
|
||||
return sk_sp<SkColorFilter>(new SkSRGBColorFilter(mode));
|
||||
}
|
||||
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override {
|
||||
return GrSRGBEffect::Make(fMode);
|
||||
}
|
||||
|
||||
void onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool) const override {
|
||||
SK_ABORT("SkSRGBColorFilter is only implemented for GPU");
|
||||
}
|
||||
Factory getFactory() const override { return nullptr; }
|
||||
|
||||
#ifndef SK_IGNORE_TO_STRING
|
||||
void toString(SkString* str) const override {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
SkSRGBColorFilter(GrSRGBEffect::Mode mode) : fMode(mode) {}
|
||||
|
||||
GrSRGBEffect::Mode fMode;
|
||||
typedef SkColorFilter INHERITED;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace sk_tool_utils {
|
||||
|
||||
/* these are the default fonts chosen by Chrome for serif, sans-serif, and monospace */
|
||||
@ -655,14 +623,4 @@ void copy_to_g8(SkBitmap* dst, const SkBitmap& src) {
|
||||
}
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<SkColorFilter> MakeLinearToSRGBColorFilter() {
|
||||
return SkSRGBColorFilter::Make(GrSRGBEffect::Mode::kLinearToSRGB);
|
||||
}
|
||||
|
||||
sk_sp<SkColorFilter> MakeSRGBToLinearColorFilter() {
|
||||
return SkSRGBColorFilter::Make(GrSRGBEffect::Mode::kSRGBToLinear);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace sk_tool_utils
|
||||
|
@ -256,11 +256,6 @@ namespace sk_tool_utils {
|
||||
bool copy_to(SkBitmap* dst, SkColorType dstCT, const SkBitmap& src);
|
||||
void copy_to_g8(SkBitmap* dst, const SkBitmap& src);
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<SkColorFilter> MakeLinearToSRGBColorFilter();
|
||||
sk_sp<SkColorFilter> MakeSRGBToLinearColorFilter();
|
||||
#endif
|
||||
|
||||
} // namespace sk_tool_utils
|
||||
|
||||
#endif // sk_tool_utils_DEFINED
|
||||
|
Loading…
Reference in New Issue
Block a user