extend gm to test aa[] parameter on xfer4f procs
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1663643002 Review URL: https://codereview.chromium.org/1663643002
This commit is contained in:
parent
afb188de27
commit
ef5252e48f
@ -10,6 +10,8 @@
|
||||
#include "SkString.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
#define USE_AA (1 << 31) // merge with Xfermode::PMFlags w/o conflict
|
||||
|
||||
#define INNER_LOOPS 1000
|
||||
|
||||
// Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
|
||||
@ -17,17 +19,27 @@ class Xfer4fBench : public Benchmark {
|
||||
public:
|
||||
Xfer4fBench(SkXfermode::Mode mode, const char name[], bool doN, uint32_t flags)
|
||||
: fDoN(doN)
|
||||
, fFlags(flags)
|
||||
, fFlags(flags & ~USE_AA)
|
||||
{
|
||||
fProc1 = SkXfermode::GetPM4fProc1(mode, flags);
|
||||
fProcN = SkXfermode::GetPM4fProcN(mode, flags);
|
||||
fName.printf("xfer4f_%s_%c_%s_%s", name, fDoN ? 'N' : '1',
|
||||
fProc1 = SkXfermode::GetPM4fProc1(mode, fFlags);
|
||||
fProcN = SkXfermode::GetPM4fProcN(mode, fFlags);
|
||||
fName.printf("xfer4f_%s_%s_%c_%s_%s",
|
||||
name,
|
||||
(flags & USE_AA) ? "aa" : "bw",
|
||||
fDoN ? 'N' : '1',
|
||||
(flags & SkXfermode::kSrcIsOpaque_PM4fFlag) ? "opaque" : "alpha",
|
||||
(flags & SkXfermode::kDstIsSRGB_PM4fFlag) ? "srgb" : "linear");
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
fSrc[i] = {{ 1, 1, 1, 1 }};
|
||||
fDst[i] = 0;
|
||||
fAAStorage[i] = i * 255 / (N - 1);
|
||||
}
|
||||
|
||||
if (flags & USE_AA) {
|
||||
fAA = fAAStorage;
|
||||
} else {
|
||||
fAA = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,13 +50,12 @@ protected:
|
||||
|
||||
void onDraw(int loops, SkCanvas*) override {
|
||||
const SkXfermode::PM4fState state{ nullptr, fFlags };
|
||||
const uint8_t* aa = nullptr;
|
||||
|
||||
for (int i = 0; i < loops * INNER_LOOPS; ++i) {
|
||||
if (fDoN) {
|
||||
fProcN(state, fDst, fSrc, N, aa);
|
||||
fProcN(state, fDst, fSrc, N, fAA);
|
||||
} else {
|
||||
fProc1(state, fDst, fSrc[0], N, aa);
|
||||
fProc1(state, fDst, fSrc[0], N, fAA);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,6 +64,7 @@ private:
|
||||
SkString fName;
|
||||
SkXfermode::PM4fProc1 fProc1;
|
||||
SkXfermode::PM4fProcN fProcN;
|
||||
const SkAlpha* fAA;
|
||||
bool fDoN;
|
||||
uint32_t fFlags;
|
||||
|
||||
@ -61,6 +73,7 @@ private:
|
||||
};
|
||||
SkPM4f fSrc[N];
|
||||
SkPMColor fDst[N];
|
||||
uint8_t fAAStorage[N];
|
||||
|
||||
typedef Benchmark INHERITED;
|
||||
};
|
||||
@ -79,3 +92,13 @@ DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F00); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F11); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F01); )
|
||||
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", false, F10 | USE_AA); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", false, F00 | USE_AA); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", false, F11 | USE_AA); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", false, F01 | USE_AA); )
|
||||
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F10 | USE_AA); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F00 | USE_AA); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F11 | USE_AA); )
|
||||
DEF_BENCH( return new Xfer4fBench(SkXfermode::kSrcOver_Mode, "srcover", true, F01 | USE_AA); )
|
||||
|
@ -10,7 +10,8 @@
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
static void draw_rect(SkCanvas* canvas, const SkRect& r, SkColor c, SkColorProfileType profile) {
|
||||
static void draw_rect(SkCanvas* canvas, const SkRect& r, SkColor c, SkColorProfileType profile,
|
||||
const SkAlpha aa[]) {
|
||||
const SkIRect ir = r.round();
|
||||
|
||||
SkBitmap bm;
|
||||
@ -32,7 +33,7 @@ static void draw_rect(SkCanvas* canvas, const SkRect& r, SkColor c, SkColorProfi
|
||||
const SkPM4f src = SkColor4f::FromColor(c).premul();
|
||||
auto proc1 = SkXfermode::GetPM4fProc1(SkXfermode::kSrcOver_Mode, flags);
|
||||
for (int y = 0; y < ir.height()/2; ++y) {
|
||||
proc1(state, pm.writable_addr32(0, y), src, ir.width(), nullptr);
|
||||
proc1(state, pm.writable_addr32(0, y), src, ir.width(), aa);
|
||||
}
|
||||
|
||||
SkPM4f srcRow[1000];
|
||||
@ -42,7 +43,7 @@ static void draw_rect(SkCanvas* canvas, const SkRect& r, SkColor c, SkColorProfi
|
||||
auto procN = SkXfermode::GetPM4fProcN(SkXfermode::kSrcOver_Mode, flags);
|
||||
// +1 to skip a row, so we can see the boundary between proc1 and procN
|
||||
for (int y = ir.height()/2 + 1; y < ir.height(); ++y) {
|
||||
procN(state, pm.writable_addr32(0, y), srcRow, ir.width(), nullptr);
|
||||
procN(state, pm.writable_addr32(0, y), srcRow, ir.width(), aa);
|
||||
}
|
||||
|
||||
canvas->drawBitmap(bm, r.left(), r.top(), nullptr);
|
||||
@ -51,8 +52,9 @@ static void draw_rect(SkCanvas* canvas, const SkRect& r, SkColor c, SkColorProfi
|
||||
/*
|
||||
* Test SkXfer4fProcs directly for src-over, comparing them to current SkColor blits.
|
||||
*/
|
||||
DEF_SIMPLE_GM(xfer4f_srcover, canvas, 580, 380) {
|
||||
const SkScalar W = 50;
|
||||
DEF_SIMPLE_GM(xfer4f_srcover, canvas, 580, 760) {
|
||||
const int IW = 50;
|
||||
const SkScalar W = IW;
|
||||
const SkScalar H = 100;
|
||||
|
||||
const int profiles[] = {
|
||||
@ -64,22 +66,41 @@ DEF_SIMPLE_GM(xfer4f_srcover, canvas, 580, 380) {
|
||||
SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
|
||||
0x88000000, 0x88FF0000, 0x8800FF00, 0x880000FF
|
||||
};
|
||||
|
||||
uint8_t aa_scanline[IW];
|
||||
for (int i = 0; i < IW; ++i) {
|
||||
aa_scanline[i] = i * 255 / (IW - 1);
|
||||
}
|
||||
uint8_t const* aa_table[] = { nullptr, aa_scanline };
|
||||
|
||||
SkBitmap mask;
|
||||
mask.installPixels(SkImageInfo::MakeA8(IW, 1), aa_scanline, IW);
|
||||
|
||||
canvas->translate(20, 20);
|
||||
|
||||
const SkRect r = SkRect::MakeWH(W, H);
|
||||
for (auto profile : profiles) {
|
||||
for (const uint8_t* aa : aa_table) {
|
||||
canvas->save();
|
||||
for (SkColor c : colors) {
|
||||
if (profile < 0) {
|
||||
SkPaint p;
|
||||
p.setColor(c);
|
||||
canvas->drawRect(r, p);
|
||||
} else {
|
||||
draw_rect(canvas, r, c, (SkColorProfileType)profile);
|
||||
for (auto profile : profiles) {
|
||||
canvas->save();
|
||||
for (SkColor c : colors) {
|
||||
if (profile < 0) {
|
||||
SkPaint p;
|
||||
p.setColor(c);
|
||||
if (aa) {
|
||||
canvas->drawBitmapRect(mask, r, &p);
|
||||
} else {
|
||||
canvas->drawRect(r, p);
|
||||
}
|
||||
} else {
|
||||
draw_rect(canvas, r, c, (SkColorProfileType)profile, aa);
|
||||
}
|
||||
canvas->translate(W + 20, 0);
|
||||
}
|
||||
canvas->translate(W + 20, 0);
|
||||
canvas->restore();
|
||||
canvas->translate(0, H + 20);
|
||||
}
|
||||
canvas->restore();
|
||||
canvas->translate(0, H + 20);
|
||||
canvas->translate(0, (H + 20) * SK_ARRAY_COUNT(profiles) + 20);
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,6 @@ template <DstType D> uint32_t store_dst(const Sk4f& x4) {
|
||||
return (D == kSRGB_Dst) ? Sk4f_toS32(x4) : Sk4f_toL32(x4);
|
||||
}
|
||||
|
||||
static uint32_t linear_unit_to_srgb_32(const Sk4f& l4) {
|
||||
return Sk4f_toL32(l4);
|
||||
}
|
||||
|
||||
static Sk4f linear_unit_to_srgb_255f(const Sk4f& l4) {
|
||||
return linear_to_srgb(l4) * Sk4f(255) + Sk4f(0.5f);
|
||||
}
|
||||
@ -268,8 +264,8 @@ template <DstType D> void srcover_n(const SkXfermode::PM4fState& state, uint32_t
|
||||
|
||||
static void srcover_linear_dst_1(const SkXfermode::PM4fState& state, uint32_t dst[],
|
||||
const SkPM4f& src, int count, const SkAlpha aa[]) {
|
||||
Sk4f s4 = Sk4f::Load(src.fVec);
|
||||
Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
|
||||
const Sk4f s4 = Sk4f::Load(src.fVec);
|
||||
const Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
|
||||
|
||||
if (aa) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
@ -280,31 +276,31 @@ static void srcover_linear_dst_1(const SkXfermode::PM4fState& state, uint32_t ds
|
||||
Sk4f d4 = Sk4f_fromL32(dst[i]);
|
||||
Sk4f r4;
|
||||
if (a != 0xFF) {
|
||||
s4 = scale_by_coverage(s4, a);
|
||||
r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
|
||||
Sk4f s4_aa = scale_by_coverage(s4, a);
|
||||
r4 = s4_aa + d4 * Sk4f(1 - get_alpha(s4_aa));
|
||||
} else {
|
||||
r4 = s4 + d4 * dst_scale;
|
||||
}
|
||||
dst[i] = Sk4f_toL32(r4);
|
||||
}
|
||||
} else {
|
||||
s4 = s4 * Sk4f(255) + Sk4f(0.5f); // +0.5 to pre-bias for rounding
|
||||
const Sk4f s4_255 = s4 * Sk4f(255) + Sk4f(0.5f); // +0.5 to pre-bias for rounding
|
||||
while (count >= 4) {
|
||||
Sk4f d0 = to_4f(dst[0]);
|
||||
Sk4f d1 = to_4f(dst[1]);
|
||||
Sk4f d2 = to_4f(dst[2]);
|
||||
Sk4f d3 = to_4f(dst[3]);
|
||||
Sk4f_ToBytes((uint8_t*)dst,
|
||||
s4 + d0 * dst_scale,
|
||||
s4 + d1 * dst_scale,
|
||||
s4 + d2 * dst_scale,
|
||||
s4 + d3 * dst_scale);
|
||||
s4_255 + d0 * dst_scale,
|
||||
s4_255 + d1 * dst_scale,
|
||||
s4_255 + d2 * dst_scale,
|
||||
s4_255 + d3 * dst_scale);
|
||||
dst += 4;
|
||||
count -= 4;
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Sk4f d4 = to_4f(dst[i]);
|
||||
dst[i] = to_4b(s4 + d4 * dst_scale);
|
||||
dst[i] = to_4b(s4_255 + d4 * dst_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -323,12 +319,12 @@ static void srcover_srgb_dst_1(const SkXfermode::PM4fState& state, uint32_t dst[
|
||||
Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
|
||||
Sk4f r4;
|
||||
if (a != 0xFF) {
|
||||
s4 = scale_by_coverage(s4, a);
|
||||
r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
|
||||
const Sk4f s4_aa = scale_by_coverage(s4, a);
|
||||
r4 = s4_aa + d4 * Sk4f(1 - get_alpha(s4_aa));
|
||||
} else {
|
||||
r4 = s4 + d4 * dst_scale;
|
||||
}
|
||||
dst[i] = linear_unit_to_srgb_32(r4);
|
||||
dst[i] = to_4b(linear_unit_to_srgb_255f(r4));
|
||||
}
|
||||
} else {
|
||||
while (count >= 4) {
|
||||
|
Loading…
Reference in New Issue
Block a user