rough clamped tracking in SkRasterPipeline
This should make srgb_color_filter draw correctly in software. Previously the Rec2020 block would overflow. Change-Id: Ied4516728039e54214886d55bba92662beee9a26 Reviewed-on: https://skia-review.googlesource.com/26562 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
parent
066f020bb6
commit
159db0a6a1
@ -15,6 +15,7 @@ void SkRasterPipeline::reset() {
|
||||
fStages = nullptr;
|
||||
fNumStages = 0;
|
||||
fSlotsNeeded = 1; // We always need one extra slot for just_return().
|
||||
fClamped = true;
|
||||
}
|
||||
|
||||
void SkRasterPipeline::append(StockStage stage, void* ctx) {
|
||||
@ -46,6 +47,7 @@ void SkRasterPipeline::extend(const SkRasterPipeline& src) {
|
||||
fStages = &stages[src.fNumStages - 1];
|
||||
fNumStages += src.fNumStages;
|
||||
fSlotsNeeded += src.fSlotsNeeded - 1; // Don't double count just_returns().
|
||||
fClamped = fClamped && src.fClamped;
|
||||
}
|
||||
|
||||
void SkRasterPipeline::dump() const {
|
||||
@ -162,3 +164,12 @@ void SkRasterPipeline::append_matrix(SkArenaAlloc* alloc, const SkMatrix& matrix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkRasterPipeline::clamp_if_unclamped(SkAlphaType alphaType) {
|
||||
if (!fClamped) {
|
||||
this->append(SkRasterPipeline::clamp_0);
|
||||
this->append(alphaType == kPremul_SkAlphaType ? SkRasterPipeline::clamp_a
|
||||
: SkRasterPipeline::clamp_1);
|
||||
fClamped = true;
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +138,11 @@ public:
|
||||
|
||||
bool empty() const { return fStages == nullptr; }
|
||||
|
||||
// Used to track if we're handling values outside [0.0f, 1.0f],
|
||||
// and to clamp back to [0.0f, 1.0f] if so.
|
||||
void set_clamped(bool clamped) { fClamped = clamped; }
|
||||
void clamp_if_unclamped(SkAlphaType);
|
||||
|
||||
private:
|
||||
struct StageList {
|
||||
StageList* prev;
|
||||
@ -152,6 +157,7 @@ private:
|
||||
StageList* fStages;
|
||||
int fNumStages;
|
||||
int fSlotsNeeded;
|
||||
bool fClamped;
|
||||
};
|
||||
|
||||
template <size_t bytes>
|
||||
|
@ -256,6 +256,10 @@ void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p) const {
|
||||
p->append(SkRasterPipeline::dither, &fDitherRate);
|
||||
}
|
||||
|
||||
if (fDst.info().colorType() != kRGBA_F16_SkColorType) {
|
||||
p->clamp_if_unclamped(kPremul_SkAlphaType);
|
||||
}
|
||||
|
||||
switch (fDst.info().colorType()) {
|
||||
case kGray_8_SkColorType: p->append(SkRasterPipeline::luminance_to_alpha); // fallthru
|
||||
case kAlpha_8_SkColorType: p->append(SkRasterPipeline::store_a8, &fDstPtr); break;
|
||||
@ -318,6 +322,7 @@ void SkRasterPipelineBlitter::blitRect(int x, int y, int w, int h) {
|
||||
&& !fDst.colorSpace()
|
||||
&& fDst.info().alphaType() != kUnpremul_SkAlphaType
|
||||
&& fDitherRate == 0.0f) {
|
||||
p.clamp_if_unclamped(kPremul_SkAlphaType);
|
||||
p.append(SkRasterPipeline::srcover_rgba_8888, &fDstPtr);
|
||||
} else {
|
||||
if (fBlend != SkBlendMode::kSrc) {
|
||||
|
@ -39,11 +39,18 @@ void SkToSRGBColorFilter::onAppendStages(SkRasterPipeline* p,
|
||||
}
|
||||
|
||||
// Step 2: Transform to sRGB gamut, without clamping.
|
||||
float* gamut_transform = alloc->makeArrayDefault<float>(12);
|
||||
(void)append_gamut_transform_noclamp(p,
|
||||
alloc->makeArrayDefault<float>(12),
|
||||
gamut_transform,
|
||||
fSrcColorSpace.get(),
|
||||
SkColorSpace::MakeSRGB().get());
|
||||
|
||||
bool needs_clamp_0, needs_clamp_1;
|
||||
analyze_3x4_matrix(gamut_transform, &needs_clamp_0, &needs_clamp_1);
|
||||
if (needs_clamp_0 || needs_clamp_1) {
|
||||
p->set_clamped(false);
|
||||
}
|
||||
|
||||
// Step 3: Back to sRGB encoding.
|
||||
p->append(SkRasterPipeline::to_srgb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user