Planar ramp() for S32 linear gradients

R=mtklein@google.com,reed@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1825333003

Review URL: https://codereview.chromium.org/1825333003
This commit is contained in:
fmalita 2016-03-23 12:28:14 -07:00 committed by Commit bot
parent 39b54951c4
commit 83aa9208da
2 changed files with 41 additions and 5 deletions

View File

@ -108,19 +108,19 @@ struct DstTraits<DstType::S32, premul> {
using PM = PremulTraits<premul>;
using Type = SkPMColor;
// TODO: prescale by something like (255^2, 255^2, 255^2, 255) and use
// linear_to_srgb to save a mult in store?
static Sk4f load(const SkPM4f& c) {
return c.to4f_pmorder();
// Prescaling by (255^2, 255^2, 255^2, 255) on load, to avoid a 255 multiply on
// each store (S32 conversion yields a uniform 255 factor).
return c.to4f_pmorder() * Sk4f(255 * 255, 255 * 255, 255 * 255, 255);
}
static void store(const Sk4f& c, Type* dst) {
// FIXME: this assumes opaque colors. Handle unpremultiplication.
*dst = Sk4f_toS32(PM::apply(c));
*dst = to_4b(linear_to_srgb(PM::apply(c)));
}
static void store(const Sk4f& c, Type* dst, int n) {
sk_memset32(dst, Sk4f_toS32(PM::apply(c)), n);
sk_memset32(dst, to_4b(linear_to_srgb(PM::apply(c))), n);
}
static void store4x(const Sk4f& c0, const Sk4f& c1,

View File

@ -6,6 +6,7 @@
*/
#include "Sk4fLinearGradient.h"
#include "Sk4x4f.h"
#include "SkXfermode.h"
namespace {
@ -42,6 +43,41 @@ void ramp(const Sk4f& c, const Sk4f& dc, typename DstTraits<dstType, premul>::Ty
}
}
// Planar version of ramp (S32 no-premul only).
template<>
void ramp<DstType::S32, ApplyPremul::False>(const Sk4f& c, const Sk4f& dc, SkPMColor dst[], int n) {
SkASSERT(n > 0);
const Sk4f dc4 = dc * 4;
const Sk4x4f dc4x = { Sk4f(dc4[0]), Sk4f(dc4[1]), Sk4f(dc4[2]), Sk4f(dc4[3]) };
Sk4x4f c4x = Sk4x4f::Transpose(c, c + dc, c + dc * 2, c + dc * 3);
while (n >= 4) {
const Sk4x4f cx4s32 = { c4x.r.sqrt(), c4x.g.sqrt(), c4x.b.sqrt(), c4x.a };
cx4s32.transpose((uint8_t*)dst);
c4x.r += dc4x.r;
c4x.g += dc4x.g;
c4x.b += dc4x.b;
c4x.a += dc4x.a;
dst += 4;
n -= 4;
}
if (n & 2) {
DstTraits<DstType::S32, ApplyPremul::False>
::store(Sk4f(c4x.r[0], c4x.g[0], c4x.b[0], c4x.a[0]), dst++);
DstTraits<DstType::S32, ApplyPremul::False>
::store(Sk4f(c4x.r[1], c4x.g[1], c4x.b[1], c4x.a[1]), dst++);
}
if (n & 1) {
DstTraits<DstType::S32, ApplyPremul::False>
::store(Sk4f(c4x.r[n & 2], c4x.g[n & 2], c4x.b[n & 2], c4x.a[n & 2]), dst);
}
}
template<SkShader::TileMode>
SkScalar pinFx(SkScalar);