diff options
author | reed <reed@google.com> | 2015-03-24 05:18:09 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-24 05:18:09 -0700 |
commit | 92b47c49016749249ff8521e424c4373b4a74241 (patch) | |
tree | 610773be56816c44489f9736875195066309e211 | |
parent | b67eb2f9b9ec097aa963245a85be13daec09d2cc (diff) |
Revert of remove colorfilter native-565 support. complicating w/ no real value. (patchset #2 id:20001 of https://codereview.chromium.org/1015533011/)
Reason for revert:
skia/ext/benchmarking_canvas.cc references HasFilter16 :(
Original issue's description:
> remove colorfilter native-565 support. complicating w/ no real value.
>
> BUG=skia:
> TBR=
>
> Committed: https://skia.googlesource.com/skia/+/2151353d161fe389cdc0db62cfe1932c7680f710
TBR=reed@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Review URL: https://codereview.chromium.org/1022673007
-rw-r--r-- | include/core/SkColorFilter.h | 22 | ||||
-rw-r--r-- | include/effects/SkColorMatrixFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkModeColorFilter.h | 2 | ||||
-rw-r--r-- | src/core/SkColorFilter.cpp | 15 | ||||
-rw-r--r-- | src/core/SkFilterShader.cpp | 19 | ||||
-rw-r--r-- | src/core/SkFilterShader.h | 1 | ||||
-rw-r--r-- | src/effects/SkColorFilters.cpp | 54 | ||||
-rw-r--r-- | src/effects/SkColorMatrixFilter.cpp | 39 |
8 files changed, 136 insertions, 18 deletions
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h index ea314811ba..fe151a2533 100644 --- a/include/core/SkColorFilter.h +++ b/include/core/SkColorFilter.h @@ -68,15 +68,31 @@ public: @param count the number of entries in the src[] and result[] arrays @param result written by the filter */ - virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) const = 0; + virtual void filterSpan(const SkPMColor src[], int count, + SkPMColor result[]) const = 0; + /** Called with a scanline of colors, as if there was a shader installed. + The implementation writes out its filtered version into result[]. + Note: shader and result may be the same buffer. + @param src array of colors, possibly generated by a shader + @param count the number of entries in the src[] and result[] arrays + @param result written by the filter + */ + virtual void filterSpan16(const uint16_t shader[], int count, + uint16_t result[]) const; enum Flags { - /** If set the filter methods will not change the alpha channel of the colors. + /** If set the filter methods will not change the alpha channel of the + colors. */ kAlphaUnchanged_Flag = 0x01, + /** If set, this subclass implements filterSpan16(). If this flag is + set, then kAlphaUnchanged_Flag must also be set. + */ + kHasFilter16_Flag = 0x02 }; - /** Returns the flags for this filter. Override in subclasses to return custom flags. + /** Returns the flags for this filter. Override in subclasses to return + custom flags. */ virtual uint32_t getFlags() const { return 0; } diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h index 4cb24bad5d..7ec0a6f65c 100644 --- a/include/effects/SkColorMatrixFilter.h +++ b/include/effects/SkColorMatrixFilter.h @@ -20,7 +20,9 @@ public: return SkNEW_ARGS(SkColorMatrixFilter, (array)); } + // overrides from SkColorFilter void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE; + void filterSpan16(const uint16_t src[], int count, uint16_t[]) const SK_OVERRIDE; uint32_t getFlags() const SK_OVERRIDE; bool asColorMatrix(SkScalar matrix[20]) const SK_OVERRIDE; SkColorFilter* newComposed(const SkColorFilter*) const SK_OVERRIDE; diff --git a/include/effects/SkModeColorFilter.h b/include/effects/SkModeColorFilter.h index 6d0d3ccaa0..4bb7a43db4 100644 --- a/include/effects/SkModeColorFilter.h +++ b/include/effects/SkModeColorFilter.h @@ -28,6 +28,7 @@ public: bool asColorMode(SkColor*, SkXfermode::Mode*) const SK_OVERRIDE; uint32_t getFlags() const SK_OVERRIDE; void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const SK_OVERRIDE; + void filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const SK_OVERRIDE; #ifndef SK_IGNORE_TO_STRING void toString(SkString* str) const SK_OVERRIDE { @@ -52,6 +53,7 @@ private: // cache SkPMColor fPMColor; SkXfermodeProc fProc; + SkXfermodeProc16 fProc16; void updateCache(); diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index 45950ad0b5..0a9cd93e34 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -22,6 +22,15 @@ bool SkColorFilter::asComponentTable(SkBitmap*) const { return false; } +void SkColorFilter::filterSpan16(const uint16_t s[], int count, uint16_t d[]) const { + SkASSERT(this->getFlags() & SkColorFilter::kHasFilter16_Flag); + SkDEBUGFAIL("missing implementation of SkColorFilter::filterSpan16"); + + if (d != s) { + memcpy(d, s, count * sizeof(uint16_t)); + } +} + SkColor SkColorFilter::filterColor(SkColor c) const { SkPMColor dst, src = SkPreMultiplyColor(c); this->filterSpan(&src, 1, &dst); @@ -52,6 +61,12 @@ public: fOuter->filterSpan(result, count, result); } + void filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const SK_OVERRIDE { + SkASSERT(this->getFlags() & kHasFilter16_Flag); + fInner->filterSpan16(shader, count, result); + fOuter->filterSpan16(result, count, result); + } + #ifndef SK_IGNORE_TO_STRING void toString(SkString* str) const SK_OVERRIDE { SkString outerS, innerS; diff --git a/src/core/SkFilterShader.cpp b/src/core/SkFilterShader.cpp index a10a7c9d77..48c4b8b477 100644 --- a/src/core/SkFilterShader.cpp +++ b/src/core/SkFilterShader.cpp @@ -46,12 +46,13 @@ uint32_t SkFilterShader::FilterShaderContext::getFlags() const { uint32_t shaderF = fShaderContext->getFlags(); uint32_t filterF = filterShader.fFilter->getFlags(); - // filters don't support 16bit, so clear the matching bit in the shader - shaderF &= ~SkShader::kHasSpan16_Flag; - + // if the filter doesn't support 16bit, clear the matching bit in the shader + if (!(filterF & SkColorFilter::kHasFilter16_Flag)) { + shaderF &= ~SkShader::kHasSpan16_Flag; + } // if the filter might change alpha, clear the opaque flag in the shader if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { - shaderF &= ~SkShader::kOpaqueAlpha_Flag; + shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag); } return shaderF; } @@ -86,6 +87,16 @@ void SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor resu filterShader.fFilter->filterSpan(result, count, result); } +void SkFilterShader::FilterShaderContext::shadeSpan16(int x, int y, uint16_t result[], int count) { + const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); + + SkASSERT(fShaderContext->getFlags() & SkShader::kHasSpan16_Flag); + SkASSERT(filterShader.fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag); + + fShaderContext->shadeSpan16(x, y, result, count); + filterShader.fFilter->filterSpan16(result, count, result); +} + #ifndef SK_IGNORE_TO_STRING void SkFilterShader::toString(SkString* str) const { str->append("SkFilterShader: ("); diff --git a/src/core/SkFilterShader.h b/src/core/SkFilterShader.h index 65291c8f39..dca9567e66 100644 --- a/src/core/SkFilterShader.h +++ b/src/core/SkFilterShader.h @@ -28,6 +28,7 @@ public: uint32_t getFlags() const SK_OVERRIDE; void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; + void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; void set3DMask(const SkMask* mask) SK_OVERRIDE { // forward to our proxy diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp index 8c021e452b..8bcd0ebc5d 100644 --- a/src/effects/SkColorFilters.cpp +++ b/src/effects/SkColorFilters.cpp @@ -27,14 +27,7 @@ bool SkModeColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) cons } uint32_t SkModeColorFilter::getFlags() const { - switch (fMode) { - case SkXfermode::kDst_Mode: //!< [Da, Dc] - case SkXfermode::kSrcATop_Mode: //!< [Da, Sc * Da + (1 - Sa) * Dc] - return kAlphaUnchanged_Flag; - default: - break; - } - return 0; + return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0; } void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const { @@ -46,6 +39,16 @@ void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColo } } +void SkModeColorFilter::filterSpan16(const uint16_t shader[], int count, uint16_t result[]) const { + SkASSERT(this->getFlags() & kHasFilter16_Flag); + + SkPMColor color = fPMColor; + SkXfermodeProc16 proc16 = fProc16; + + for (int i = 0; i < count; i++) { + result[i] = proc16(color, shader[i]); + } +} void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeColor(fColor); buffer.writeUInt(fMode); @@ -54,6 +57,7 @@ void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const { void SkModeColorFilter::updateCache() { fPMColor = SkPreMultiplyColor(fColor); fProc = SkXfermode::GetProc(fMode); + fProc16 = SkXfermode::GetProc16(fMode, fColor); } SkFlattenable* SkModeColorFilter::CreateProc(SkReadBuffer& buffer) { @@ -384,10 +388,25 @@ class Src_SkModeColorFilter : public SkModeColorFilter { public: Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {} - void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const SK_OVERRIDE { + uint32_t getFlags() const SK_OVERRIDE { + if (SkGetPackedA32(this->getPMColor()) == 0xFF) { + return kAlphaUnchanged_Flag | kHasFilter16_Flag; + } else { + return 0; + } + } + + virtual void filterSpan(const SkPMColor shader[], int count, + SkPMColor result[]) const SK_OVERRIDE { sk_memset32(result, this->getPMColor(), count); } + virtual void filterSpan16(const uint16_t shader[], int count, + uint16_t result[]) const SK_OVERRIDE { + SkASSERT(this->getFlags() & kHasFilter16_Flag); + sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count); + } + private: typedef SkModeColorFilter INHERITED; }; @@ -399,10 +418,25 @@ public: fColor32Proc = SkBlitRow::ColorProcFactory(); } - void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const SK_OVERRIDE { + uint32_t getFlags() const SK_OVERRIDE { + if (SkGetPackedA32(this->getPMColor()) == 0xFF) { + return kAlphaUnchanged_Flag | kHasFilter16_Flag; + } else { + return 0; + } + } + + virtual void filterSpan(const SkPMColor shader[], int count, + SkPMColor result[]) const SK_OVERRIDE { fColor32Proc(result, shader, count, this->getPMColor()); } + virtual void filterSpan16(const uint16_t shader[], int count, + uint16_t result[]) const SK_OVERRIDE { + SkASSERT(this->getFlags() & kHasFilter16_Flag); + sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count); + } + private: SkBlitRow::ColorProc fColor32Proc; diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp index 3bdda61187..04c00c951f 100644 --- a/src/effects/SkColorMatrixFilter.cpp +++ b/src/effects/SkColorMatrixFilter.cpp @@ -139,6 +139,9 @@ static void Add16(const SkColorMatrixFilter::State& state, result[3] = a; } +#define kNO_ALPHA_FLAGS (SkColorFilter::kAlphaUnchanged_Flag | \ + SkColorFilter::kHasFilter16_Flag) + // src is [20] but some compilers won't accept __restrict__ on anything // but an raw pointer or reference void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) { @@ -180,7 +183,7 @@ void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) { fProc = shiftIs16 ? General16 : General; fFlags = changesAlpha ? 0 : SkColorFilter::kAlphaUnchanged_Flag; } else { - fFlags = SkColorFilter::kAlphaUnchanged_Flag; + fFlags = kNO_ALPHA_FLAGS; int32_t needsScale = (array[SkColorMatrix::kR_Scale] - one) | (array[SkColorMatrix::kG_Scale] - one) | @@ -362,6 +365,40 @@ void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count, SkPMColor } } +void SkColorMatrixFilter::filterSpan16(const uint16_t src[], int count, + uint16_t dst[]) const { + SkASSERT(fFlags & SkColorFilter::kHasFilter16_Flag); + + Proc proc = fProc; + const State& state = fState; + int32_t result[4]; + + if (NULL == proc) { + if (src != dst) { + memcpy(dst, src, count * sizeof(uint16_t)); + } + return; + } + + for (int i = 0; i < count; i++) { + uint16_t c = src[i]; + + // expand to 8bit components (since our matrix translate is 8bit biased + unsigned r = SkPacked16ToR32(c); + unsigned g = SkPacked16ToG32(c); + unsigned b = SkPacked16ToB32(c); + + proc(state, r, g, b, 0, result); + + r = pin(result[0], SK_R32_MASK); + g = pin(result[1], SK_G32_MASK); + b = pin(result[2], SK_B32_MASK); + + // now packed it back down to 16bits (hmmm, could dither...) + dst[i] = SkPack888ToRGB16(r, g, b); + } +} + /////////////////////////////////////////////////////////////////////////////// void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const { |