}
}
- if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL))
- {
- // xfermodes require shaders for our current set of blitters
+ if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL)) {
+ // xfermodes (and filters) require shaders for our current blitters
shader = SkNEW(SkColorShader);
((SkPaint*)&paint)->setShader(shader)->unref();
}
SkASSERT(shader);
shader = SkNEW_ARGS(SkFilterShader, (shader, paint.getColorFilter()));
((SkPaint*)&paint)->setShader(shader)->unref();
+ // blitters should ignore the presence/absence of a filter, since
+ // if there is one, the shader will take care of it.
}
if (shader && !shader->setContext(device, paint, matrix)) {
break;
case SkBitmap::kRGB_565_Config:
- if (shader)
- {
- if (mode)
- SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, storage, storageSize, (device, paint));
- else if (shader->canCallShadeSpan16())
- SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, storage, storageSize, (device, paint));
- else
- SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, storage, storageSize, (device, paint));
- } else {
- SkColor color = paint.getColor();
- if (0 == SkColorGetA(color)) {
- SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
- } else if (SK_ColorBLACK == color) {
- SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage,
- storageSize, (device, paint));
- } else if (0xFF == SkColorGetA(color)) {
- SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage,
- storageSize, (device, paint));
- } else {
- SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage,
- storageSize, (device, paint));
- }
- }
+ blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize);
break;
case SkBitmap::kARGB_8888_Config:
#include "SkColorPriv.h"
#include "SkDither.h"
#include "SkShader.h"
+#include "SkTemplatesPriv.h"
#include "SkUtils.h"
#include "SkXfermode.h"
///////////////////////////////////////////////////////////////////////////////
+class SkRGB16_Blitter : public SkRasterBlitter {
+public:
+ SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual void blitH(int x, int y, int width);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+ virtual void blitV(int x, int y, int height, SkAlpha alpha);
+ virtual void blitRect(int x, int y, int width, int height);
+ virtual void blitMask(const SkMask&, const SkIRect&);
+ virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
+
+protected:
+ SkPMColor fSrcColor32;
+ unsigned fScale;
+ uint16_t fColor16; // already scaled by fScale
+ uint16_t fRawColor16; // unscaled
+ uint16_t fRawDither16; // unscaled
+ SkBool8 fDoDither;
+
+ // illegal
+ SkRGB16_Blitter& operator=(const SkRGB16_Blitter&);
+
+ typedef SkRasterBlitter INHERITED;
+};
+
+class SkRGB16_Opaque_Blitter : public SkRGB16_Blitter {
+public:
+ SkRGB16_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual void blitH(int x, int y, int width);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+ virtual void blitRect(int x, int y, int width, int height);
+ virtual void blitMask(const SkMask&, const SkIRect&);
+
+private:
+ typedef SkRGB16_Blitter INHERITED;
+};
+
+class SkRGB16_Black_Blitter : public SkRGB16_Opaque_Blitter {
+public:
+ SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual void blitMask(const SkMask&, const SkIRect&);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+
+private:
+ typedef SkRGB16_Opaque_Blitter INHERITED;
+};
+
+class SkRGB16_Shader_Blitter : public SkShaderBlitter {
+public:
+ SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual ~SkRGB16_Shader_Blitter();
+ virtual void blitH(int x, int y, int width);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+ virtual void blitRect(int x, int y, int width, int height);
+
+protected:
+ SkPMColor* fBuffer;
+ SkBlitRow::Proc fOpaqueProc;
+ SkBlitRow::Proc fAlphaProc;
+
+private:
+ // illegal
+ SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&);
+
+ typedef SkShaderBlitter INHERITED;
+};
+
+// used only if the shader can perform shadSpan16
+class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter {
+public:
+ SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual void blitH(int x, int y, int width);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+ virtual void blitRect(int x, int y, int width, int height);
+
+private:
+ typedef SkRGB16_Shader_Blitter INHERITED;
+};
+
+class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter {
+public:
+ SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint);
+ virtual ~SkRGB16_Shader_Xfermode_Blitter();
+ virtual void blitH(int x, int y, int width);
+ virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
+
+private:
+ SkXfermode* fXfermode;
+ SkPMColor* fBuffer;
+ uint8_t* fAAExpand;
+
+ // illegal
+ SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&);
+
+ typedef SkShaderBlitter INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
SkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint)
: INHERITED(device, paint) {
SkASSERT(paint.getShader() == NULL);
}
}
-////////////////////////
+///////////////////////////////////////////////////////////////////////////////
-#if 0
-static inline uint16_t aa_blendS32D16(SkPMColor src, U16CPU dst, int aa
-#ifdef DITHER_SHADER
- , int dither
-#endif
- )
-{
- SkASSERT((unsigned)aa <= 255);
-
- int src_scale = SkAlpha255To256(aa);
- int sa = SkGetPackedA32(src);
- int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale));
-
-#ifdef DITHER_SHADER
- int sr = SkGetPackedR32(src);
- int sg = SkGetPackedG32(src);
- int sb = SkGetPackedB32(src);
- sr = SkDITHER_R32To16(sr, dither);
- sg = SkDITHER_G32To16(sg, dither);
- sb = SkDITHER_B32To16(sb, dither);
-#else
- int sr = SkPacked32ToR16(src);
- int sg = SkPacked32ToG16(src);
- int sb = SkPacked32ToB16(src);
-#endif
-
- int dr = (sr * src_scale + SkGetPackedR16(dst) * dst_scale) >> 8;
- int dg = (sg * src_scale + SkGetPackedG16(dst) * dst_scale) >> 8;
- int db = (sb * src_scale + SkGetPackedB16(dst) * dst_scale) >> 8;
+SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint,
+ void* storage, size_t storageSize) {
+ SkBlitter* blitter;
+ SkShader* shader = paint.getShader();
+ SkXfermode* mode = paint.getXfermode();
+
+ // we require a shader if there is an xfermode, handled by our caller
+ SkASSERT(NULL == mode || NULL != shader);
+
+ if (shader) {
+ if (mode) {
+ SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter,
+ storage, storageSize, (device, paint));
+ } else if (shader->canCallShadeSpan16()) {
+ SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter,
+ storage, storageSize, (device, paint));
+ } else {
+ SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter,
+ storage, storageSize, (device, paint));
+ }
+ } else {
+ // no shader, no xfermode, (and we always ignore colorfilter)
+ SkColor color = paint.getColor();
+ if (0 == SkColorGetA(color)) {
+ SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
+ } else if (SK_ColorBLACK == color) {
+ SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage,
+ storageSize, (device, paint));
+ } else if (0xFF == SkColorGetA(color)) {
+ SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage,
+ storageSize, (device, paint));
+ } else {
+ SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage,
+ storageSize, (device, paint));
+ }
+ }
- return SkPackRGB16(dr, dg, db);
+ return blitter;
}
-#endif
-
typedef SkShaderBlitter INHERITED;
};
-////////////////////////////////////////////////////////////////
-
-class SkRGB16_Blitter : public SkRasterBlitter {
-public:
- SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual void blitH(int x, int y, int width);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
- virtual void blitV(int x, int y, int height, SkAlpha alpha);
- virtual void blitRect(int x, int y, int width, int height);
- virtual void blitMask(const SkMask&, const SkIRect&);
- virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
-
-protected:
- SkPMColor fSrcColor32;
- unsigned fScale;
- uint16_t fColor16; // already scaled by fScale
- uint16_t fRawColor16; // unscaled
- uint16_t fRawDither16; // unscaled
- SkBool8 fDoDither;
-
- // illegal
- SkRGB16_Blitter& operator=(const SkRGB16_Blitter&);
-
- typedef SkRasterBlitter INHERITED;
-};
-
-class SkRGB16_Opaque_Blitter : public SkRGB16_Blitter {
-public:
- SkRGB16_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual void blitH(int x, int y, int width);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
- virtual void blitRect(int x, int y, int width, int height);
- virtual void blitMask(const SkMask&, const SkIRect&);
-
-private:
- typedef SkRGB16_Blitter INHERITED;
-};
-
-class SkRGB16_Black_Blitter : public SkRGB16_Opaque_Blitter {
-public:
- SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual void blitMask(const SkMask&, const SkIRect&);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
-
-private:
- typedef SkRGB16_Opaque_Blitter INHERITED;
-};
-
-class SkRGB16_Shader_Blitter : public SkShaderBlitter {
-public:
- SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual ~SkRGB16_Shader_Blitter();
- virtual void blitH(int x, int y, int width);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
- virtual void blitRect(int x, int y, int width, int height);
-
-protected:
- SkPMColor* fBuffer;
- SkBlitRow::Proc fOpaqueProc;
- SkBlitRow::Proc fAlphaProc;
-
-private:
- // illegal
- SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&);
-
- typedef SkShaderBlitter INHERITED;
-};
-
-// used only if the shader can perform shadSpan16
-class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter {
-public:
- SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual void blitH(int x, int y, int width);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
- virtual void blitRect(int x, int y, int width, int height);
-
-private:
- typedef SkRGB16_Shader_Blitter INHERITED;
-};
-
-class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter {
-public:
- SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint);
- virtual ~SkRGB16_Shader_Xfermode_Blitter();
- virtual void blitH(int x, int y, int width);
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]);
-
-private:
- SkXfermode* fXfermode;
- SkPMColor* fBuffer;
- uint8_t* fAAExpand;
-
- // illegal
- SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&);
-
- typedef SkShaderBlitter INHERITED;
-};
-
-/////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
class SkA1_Blitter : public SkRasterBlitter {
public:
typedef SkRasterBlitter INHERITED;
};
+///////////////////////////////////////////////////////////////////////////////
+
+/* These return the correct subclass of blitter for their device config.
+
+ Currently, they make the following assumptions about the state of the
+ paint:
+
+ 1. If there is an xfermode, there will also be a shader
+ 2. If there is a colorfilter, there will be a shader that itself handles
+ calling the filter, so the blitter can always ignore the colorfilter obj
+
+ These pre-conditions must be handled by the caller, in our case
+ SkBlitter::Choose(...)
+ */
extern SkBlitter* SkBlitter_ChooseD4444(const SkBitmap& device,
const SkPaint& paint,
void* storage, size_t storageSize);
+extern SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device,
+ const SkPaint& paint,
+ void* storage, size_t storageSize);
+
#endif
fRestoreOffsetStack.push(0);
validate();
- /* Don't actually call saveLayer, because that will try to allocate an
- offscreen device (potentially very big) which we don't actually need
- at this time (and may not be able to afford since during record our
- clip starts out the size of the picture, which is often much larger
- than the size of the actual device we'll use during playback).
- */
- return this->INHERITED::save(flags);
+ return this->INHERITED::saveLayer(bounds, paint, flags);
}
void SkPictureRecord::restore() {