add new blit2 methods in support of antialiased hairlines
before: 9M 1 528µs 530µs 539µs 607µs 5% ▁▁▁▁▁▁▁▁█▂ 8888 path_hairline_small_AA_quad after: 9M 1 355µs 356µs 358µs 375µs 2% ▂▁▁▁▁▁▁▁▁█ 8888 path_hairline_small_AA_quad BUG=skia: does require new baselines (bug chrome is guarded) Review URL: https://codereview.chromium.org/1060153003
This commit is contained in:
parent
c3c5990ac0
commit
dd83031b98
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2006 The Android Open Source Project
|
* Copyright 2006 The Android Open Source Project
|
||||||
*
|
*
|
||||||
@ -6,10 +5,15 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef SkBlitter_DEFINED
|
#ifndef SkBlitter_DEFINED
|
||||||
#define SkBlitter_DEFINED
|
#define SkBlitter_DEFINED
|
||||||
|
|
||||||
|
#ifdef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
#define SK_BLITANTIH2V2_VIRTUAL
|
||||||
|
#else
|
||||||
|
#define SK_BLITANTIH2V2_VIRTUAL virtual
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "SkBitmap.h"
|
#include "SkBitmap.h"
|
||||||
#include "SkBitmapProcShader.h"
|
#include "SkBitmapProcShader.h"
|
||||||
#include "SkMask.h"
|
#include "SkMask.h"
|
||||||
@ -55,6 +59,35 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual const SkBitmap* justAnOpaqueColor(uint32_t* value);
|
virtual const SkBitmap* justAnOpaqueColor(uint32_t* value);
|
||||||
|
|
||||||
|
// (x, y), (x + 1, y)
|
||||||
|
SK_BLITANTIH2V2_VIRTUAL void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
int16_t runs[3];
|
||||||
|
uint8_t aa[2];
|
||||||
|
|
||||||
|
runs[0] = 1;
|
||||||
|
runs[1] = 1;
|
||||||
|
runs[2] = 0;
|
||||||
|
aa[0] = SkToU8(a0);
|
||||||
|
aa[1] = SkToU8(a1);
|
||||||
|
this->blitAntiH(x, y, aa, runs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (x, y), (x, y + 1)
|
||||||
|
SK_BLITANTIH2V2_VIRTUAL void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
int16_t runs[2];
|
||||||
|
uint8_t aa[1];
|
||||||
|
|
||||||
|
runs[0] = 1;
|
||||||
|
runs[1] = 0;
|
||||||
|
aa[0] = SkToU8(a0);
|
||||||
|
this->blitAntiH(x, y, aa, runs);
|
||||||
|
// reset in case the clipping blitter modified runs
|
||||||
|
runs[0] = 1;
|
||||||
|
runs[1] = 0;
|
||||||
|
aa[0] = SkToU8(a1);
|
||||||
|
this->blitAntiH(x, y + 1, aa, runs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special method just to identify the null blitter, which is returned
|
* Special method just to identify the null blitter, which is returned
|
||||||
* from Choose() if the request cannot be fulfilled. Default impl
|
* from Choose() if the request cannot be fulfilled. Default impl
|
||||||
|
@ -106,6 +106,25 @@ void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
void SkARGB32_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
uint32_t* device = fDevice.getAddr32(x, y);
|
||||||
|
SkDEBUGCODE((void)fDevice.getAddr32(x + 1, y);)
|
||||||
|
|
||||||
|
device[0] = SkBlendARGB32(fPMColor, device[0], a0);
|
||||||
|
device[1] = SkBlendARGB32(fPMColor, device[1], a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkARGB32_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
uint32_t* device = fDevice.getAddr32(x, y);
|
||||||
|
SkDEBUGCODE((void)fDevice.getAddr32(x, y + 1);)
|
||||||
|
|
||||||
|
device[0] = SkBlendARGB32(fPMColor, device[0], a0);
|
||||||
|
device = (uint32_t*)((char*)device + fDevice.rowBytes());
|
||||||
|
device[0] = SkBlendARGB32(fPMColor, device[0], a1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define solid_8_pixels(mask, dst, color) \
|
#define solid_8_pixels(mask, dst, color) \
|
||||||
@ -180,6 +199,25 @@ void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
void SkARGB32_Opaque_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
uint32_t* device = fDevice.getAddr32(x, y);
|
||||||
|
SkDEBUGCODE((void)fDevice.getAddr32(x + 1, y);)
|
||||||
|
|
||||||
|
device[0] = SkFastFourByteInterp(fPMColor, device[0], a0);
|
||||||
|
device[1] = SkFastFourByteInterp(fPMColor, device[1], a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkARGB32_Opaque_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
uint32_t* device = fDevice.getAddr32(x, y);
|
||||||
|
SkDEBUGCODE((void)fDevice.getAddr32(x, y + 1);)
|
||||||
|
|
||||||
|
device[0] = SkFastFourByteInterp(fPMColor, device[0], a0);
|
||||||
|
device = (uint32_t*)((char*)device + fDevice.rowBytes());
|
||||||
|
device[0] = SkFastFourByteInterp(fPMColor, device[0], a1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
|
void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
|
||||||
@ -256,6 +294,25 @@ void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
void SkARGB32_Black_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
uint32_t* device = fDevice.getAddr32(x, y);
|
||||||
|
SkDEBUGCODE((void)fDevice.getAddr32(x + 1, y);)
|
||||||
|
|
||||||
|
device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0);
|
||||||
|
device[1] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[1], 256 - a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkARGB32_Black_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
|
||||||
|
uint32_t* device = fDevice.getAddr32(x, y);
|
||||||
|
SkDEBUGCODE((void)fDevice.getAddr32(x, y + 1);)
|
||||||
|
|
||||||
|
device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0);
|
||||||
|
device = (uint32_t*)((char*)device + fDevice.rowBytes());
|
||||||
|
device[0] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode,
|
// Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode,
|
||||||
|
@ -120,6 +120,10 @@ public:
|
|||||||
virtual void blitRect(int x, int y, int width, int height);
|
virtual void blitRect(int x, int y, int width, int height);
|
||||||
virtual void blitMask(const SkMask&, const SkIRect&);
|
virtual void blitMask(const SkMask&, const SkIRect&);
|
||||||
virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
|
virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
|
||||||
|
#ifndef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override;
|
||||||
|
void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkColor fColor;
|
SkColor fColor;
|
||||||
@ -140,6 +144,10 @@ public:
|
|||||||
SkARGB32_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint)
|
SkARGB32_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint)
|
||||||
: INHERITED(device, paint) { SkASSERT(paint.getAlpha() == 0xFF); }
|
: INHERITED(device, paint) { SkASSERT(paint.getAlpha() == 0xFF); }
|
||||||
virtual void blitMask(const SkMask&, const SkIRect&);
|
virtual void blitMask(const SkMask&, const SkIRect&);
|
||||||
|
#ifndef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override;
|
||||||
|
void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SkARGB32_Blitter INHERITED;
|
typedef SkARGB32_Blitter INHERITED;
|
||||||
@ -150,6 +158,10 @@ public:
|
|||||||
SkARGB32_Black_Blitter(const SkBitmap& device, const SkPaint& paint)
|
SkARGB32_Black_Blitter(const SkBitmap& device, const SkPaint& paint)
|
||||||
: INHERITED(device, paint) {}
|
: INHERITED(device, paint) {}
|
||||||
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
|
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
|
||||||
|
#ifndef SK_SUPPORT_LEGACY_BLITANTIH2V2
|
||||||
|
void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override;
|
||||||
|
void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SkARGB32_Opaque_Blitter INHERITED;
|
typedef SkARGB32_Opaque_Blitter INHERITED;
|
||||||
|
@ -154,70 +154,29 @@ public:
|
|||||||
class Horish_SkAntiHairBlitter : public SkAntiHairBlitter {
|
class Horish_SkAntiHairBlitter : public SkAntiHairBlitter {
|
||||||
public:
|
public:
|
||||||
SkFixed drawCap(int x, SkFixed fy, SkFixed dy, int mod64) override {
|
SkFixed drawCap(int x, SkFixed fy, SkFixed dy, int mod64) override {
|
||||||
int16_t runs[2];
|
|
||||||
uint8_t aa[1];
|
|
||||||
|
|
||||||
runs[0] = 1;
|
|
||||||
runs[1] = 0;
|
|
||||||
|
|
||||||
fy += SK_Fixed1/2;
|
fy += SK_Fixed1/2;
|
||||||
SkBlitter* blitter = this->getBlitter();
|
|
||||||
|
|
||||||
int lower_y = fy >> 16;
|
int lower_y = fy >> 16;
|
||||||
uint8_t a = (uint8_t)(fy >> 8);
|
uint8_t a = (uint8_t)(fy >> 8);
|
||||||
unsigned ma = SmallDot6Scale(a, mod64);
|
unsigned a0 = SmallDot6Scale(255 - a, mod64);
|
||||||
if (ma) {
|
unsigned a1 = SmallDot6Scale(a, mod64);
|
||||||
aa[0] = ApplyGamma(gamma, ma);
|
this->getBlitter()->blitAntiV2(x, lower_y - 1, a0, a1);
|
||||||
blitter->blitAntiH(x, lower_y, aa, runs);
|
|
||||||
// the clipping blitters might edit runs, but should not affect us
|
return fy + dy - SK_Fixed1/2;
|
||||||
SkASSERT(runs[0] == 1);
|
|
||||||
SkASSERT(runs[1] == 0);
|
|
||||||
}
|
|
||||||
ma = SmallDot6Scale(255 - a, mod64);
|
|
||||||
if (ma) {
|
|
||||||
aa[0] = ApplyGamma(gamma, ma);
|
|
||||||
blitter->blitAntiH(x, lower_y - 1, aa, runs);
|
|
||||||
// the clipping blitters might edit runs, but should not affect us
|
|
||||||
SkASSERT(runs[0] == 1);
|
|
||||||
SkASSERT(runs[1] == 0);
|
|
||||||
}
|
|
||||||
fy += dy;
|
|
||||||
|
|
||||||
return fy - SK_Fixed1/2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkFixed drawLine(int x, int stopx, SkFixed fy, SkFixed dy) override {
|
SkFixed drawLine(int x, int stopx, SkFixed fy, SkFixed dy) override {
|
||||||
SkASSERT(x < stopx);
|
SkASSERT(x < stopx);
|
||||||
|
|
||||||
int16_t runs[2];
|
|
||||||
uint8_t aa[1];
|
|
||||||
|
|
||||||
runs[0] = 1;
|
|
||||||
runs[1] = 0;
|
|
||||||
|
|
||||||
fy += SK_Fixed1/2;
|
fy += SK_Fixed1/2;
|
||||||
SkBlitter* blitter = this->getBlitter();
|
SkBlitter* blitter = this->getBlitter();
|
||||||
do {
|
do {
|
||||||
int lower_y = fy >> 16;
|
int lower_y = fy >> 16;
|
||||||
uint8_t a = (uint8_t)(fy >> 8);
|
uint8_t a = (uint8_t)(fy >> 8);
|
||||||
if (a) {
|
blitter->blitAntiV2(x, lower_y - 1, 255 - a, a);
|
||||||
aa[0] = a;
|
|
||||||
blitter->blitAntiH(x, lower_y, aa, runs);
|
|
||||||
// the clipping blitters might edit runs, but should not affect us
|
|
||||||
SkASSERT(runs[0] == 1);
|
|
||||||
SkASSERT(runs[1] == 0);
|
|
||||||
}
|
|
||||||
a = 255 - a;
|
|
||||||
if (a) {
|
|
||||||
aa[0] = a;
|
|
||||||
blitter->blitAntiH(x, lower_y - 1, aa, runs);
|
|
||||||
// the clipping blitters might edit runs, but should not affect us
|
|
||||||
SkASSERT(runs[0] == 1);
|
|
||||||
SkASSERT(runs[1] == 0);
|
|
||||||
}
|
|
||||||
fy += dy;
|
fy += dy;
|
||||||
} while (++x < stopx);
|
} while (++x < stopx);
|
||||||
|
|
||||||
return fy - SK_Fixed1/2;
|
return fy - SK_Fixed1/2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -266,53 +225,26 @@ public:
|
|||||||
class Vertish_SkAntiHairBlitter : public SkAntiHairBlitter {
|
class Vertish_SkAntiHairBlitter : public SkAntiHairBlitter {
|
||||||
public:
|
public:
|
||||||
SkFixed drawCap(int y, SkFixed fx, SkFixed dx, int mod64) override {
|
SkFixed drawCap(int y, SkFixed fx, SkFixed dx, int mod64) override {
|
||||||
int16_t runs[3];
|
|
||||||
uint8_t aa[2];
|
|
||||||
|
|
||||||
runs[0] = 1;
|
|
||||||
runs[2] = 0;
|
|
||||||
|
|
||||||
fx += SK_Fixed1/2;
|
fx += SK_Fixed1/2;
|
||||||
|
|
||||||
int x = fx >> 16;
|
int x = fx >> 16;
|
||||||
uint8_t a = (uint8_t)(fx >> 8);
|
uint8_t a = (uint8_t)(fx >> 8);
|
||||||
|
this->getBlitter()->blitAntiH2(x - 1, y,
|
||||||
aa[0] = SmallDot6Scale(255 - a, mod64);
|
SmallDot6Scale(255 - a, mod64), SmallDot6Scale(a, mod64));
|
||||||
aa[1] = SmallDot6Scale(a, mod64);
|
|
||||||
// the clippng blitters might overwrite this guy, so we have to reset it each time
|
return fx + dx - SK_Fixed1/2;
|
||||||
runs[1] = 1;
|
|
||||||
this->getBlitter()->blitAntiH(x - 1, y, aa, runs);
|
|
||||||
// the clipping blitters might edit runs, but should not affect us
|
|
||||||
SkASSERT(runs[0] == 1);
|
|
||||||
SkASSERT(runs[2] == 0);
|
|
||||||
fx += dx;
|
|
||||||
|
|
||||||
return fx - SK_Fixed1/2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkFixed drawLine(int y, int stopy, SkFixed fx, SkFixed dx) override {
|
SkFixed drawLine(int y, int stopy, SkFixed fx, SkFixed dx) override {
|
||||||
SkASSERT(y < stopy);
|
SkASSERT(y < stopy);
|
||||||
int16_t runs[3];
|
|
||||||
uint8_t aa[2];
|
|
||||||
|
|
||||||
runs[0] = 1;
|
|
||||||
runs[2] = 0;
|
|
||||||
|
|
||||||
fx += SK_Fixed1/2;
|
fx += SK_Fixed1/2;
|
||||||
do {
|
do {
|
||||||
int x = fx >> 16;
|
int x = fx >> 16;
|
||||||
uint8_t a = (uint8_t)(fx >> 8);
|
uint8_t a = (uint8_t)(fx >> 8);
|
||||||
|
this->getBlitter()->blitAntiH2(x - 1, y, 255 - a, a);
|
||||||
aa[0] = 255 - a;
|
|
||||||
aa[1] = a;
|
|
||||||
// the clippng blitters might overwrite this guy, so we have to reset it each time
|
|
||||||
runs[1] = 1;
|
|
||||||
this->getBlitter()->blitAntiH(x - 1, y, aa, runs);
|
|
||||||
// the clipping blitters might edit runs, but should not affect us
|
|
||||||
SkASSERT(runs[0] == 1);
|
|
||||||
SkASSERT(runs[2] == 0);
|
|
||||||
fx += dx;
|
fx += dx;
|
||||||
} while (++y < stopy);
|
} while (++y < stopy);
|
||||||
|
|
||||||
return fx - SK_Fixed1/2;
|
return fx - SK_Fixed1/2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user