add SkLerpXfermode
BUG=
R=bsalomon@google.com
Review URL: https://codereview.chromium.org/15602003
git-svn-id: http://skia.googlecode.com/svn/trunk/include@9229 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkColorPriv.h b/core/SkColorPriv.h
index 46f7d27..5d2df62 100644
--- a/core/SkColorPriv.h
+++ b/core/SkColorPriv.h
@@ -273,16 +273,16 @@
* architectures than an equivalent 64b version and 30% faster than
* SkFourByteInterp(). Third parameter controls blending of the first two:
* (src, dst, 0) returns dst
- * (src, dst, 0xFF) returns src
- * ** Does not match the results of SkFourByteInterp() because we use
+ * (src, dst, 256) returns src
+ * ** Does not match the results of SkFourByteInterp256() because we use
* a more accurate scale computation!
* TODO: migrate Skia function to using an accurate 255->266 alpha
* conversion.
*/
-static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
- SkPMColor dst,
- U8CPU srcWeight) {
- SkASSERT(srcWeight < 256);
+static inline SkPMColor SkFastFourByteInterp256(SkPMColor src,
+ SkPMColor dst,
+ unsigned scale) {
+ SkASSERT(scale <= 256);
// Reorders ARGB to AG-RB in order to reduce the number of operations.
const uint32_t mask = 0xFF00FF;
@@ -291,16 +291,21 @@
uint32_t dst_rb = dst & mask;
uint32_t dst_ag = (dst >> 8) & mask;
- // scale = srcWeight + (srcWeight >> 7) is more accurate than
- // scale = srcWeight + 1, but 7% slower
- int scale = srcWeight + (srcWeight >> 7);
-
uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8);
}
+static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
+ SkPMColor dst,
+ U8CPU srcWeight) {
+ SkASSERT(srcWeight <= 255);
+ // scale = srcWeight + (srcWeight >> 7) is more accurate than
+ // scale = srcWeight + 1, but 7% slower
+ return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7));
+}
+
/**
* Same as SkPackARGB32, but this version guarantees to not check that the
* values are premultiplied in the debug version.
diff --git a/effects/SkLerpXfermode.h b/effects/SkLerpXfermode.h
new file mode 100644
index 0000000..6151f3d
--- /dev/null
+++ b/effects/SkLerpXfermode.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLerpXfermode_DEFINED
+#define SkLerpXfermode_DEFINED
+
+#include "SkXfermode.h"
+
+class SK_API SkLerpXfermode : public SkXfermode {
+public:
+ /**
+ * result = scale * src + (1 - scale) * dst
+ *
+ * When scale == 1, this is the same as kSrc_Mode
+ * When scale == 0, this is the same as kDst_Mode
+ */
+ static SkXfermode* Create(SkScalar scale);
+
+ // overrides from SkXfermode
+ virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+ virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+ virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
+ const SkAlpha aa[]) const SK_OVERRIDE;
+
+ SK_DEVELOPER_TO_STRING()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLerpXfermode)
+
+protected:
+ SkLerpXfermode(SkFlattenableReadBuffer&);
+ virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkLerpXfermode(unsigned scale256);
+
+ unsigned fScale256; // 0..256
+
+ typedef SkXfermode INHERITED;
+};
+
+#endif