123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef SkBlitter_DEFINED
- #define SkBlitter_DEFINED
- #include "include/core/SkColor.h"
- #include "include/core/SkRect.h"
- #include "include/core/SkRegion.h"
- #include "include/private/SkTo.h"
- #include "src/core/SkAutoMalloc.h"
- #include "src/core/SkImagePriv.h"
- #include "src/shaders/SkShaderBase.h"
- class SkArenaAlloc;
- class SkMatrix;
- class SkPaint;
- class SkPixmap;
- struct SkMask;
- /** SkBlitter and its subclasses are responsible for actually writing pixels
- into memory. Besides efficiency, they handle clipping and antialiasing.
- A SkBlitter subclass contains all the context needed to generate pixels
- for the destination and how src/generated pixels map to the destination.
- The coordinates passed to the blitX calls are in destination pixel space.
- */
- class SkBlitter {
- public:
- virtual ~SkBlitter();
- /// Blit a horizontal run of one or more pixels.
- virtual void blitH(int x, int y, int width) = 0;
- /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
- /// zero-terminated run-length encoding of spans of constant alpha values.
- /// The runs[] and antialias[] work together to represent long runs of pixels with the same
- /// alphas. The runs[] contains the number of pixels with the same alpha, and antialias[]
- /// contain the coverage value for that number of pixels. The runs[] (and antialias[]) are
- /// encoded in a clever way. The runs array is zero terminated, and has enough entries for
- /// each pixel plus one, in most cases some of the entries will not contain valid data. An entry
- /// in the runs array contains the number of pixels (np) that have the same alpha value. The
- /// next np value is found np entries away. For example, if runs[0] = 7, then the next valid
- /// entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the
- /// np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88.
- /// This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45.
- virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) = 0;
- /// Blit a vertical run of pixels with a constant alpha value.
- virtual void blitV(int x, int y, int height, SkAlpha alpha);
- /// Blit a solid rectangle one or more pixels wide.
- virtual void blitRect(int x, int y, int width, int height);
- /** Blit a rectangle with one alpha-blended column on the left,
- width (zero or more) opaque pixels, and one alpha-blended column
- on the right.
- The result will always be at least two pixels wide.
- */
- virtual void blitAntiRect(int x, int y, int width, int height,
- SkAlpha leftAlpha, SkAlpha rightAlpha);
- // Blit a rect in AA with size at least 3 x 3 (small rect has too many edge cases...)
- void blitFatAntiRect(const SkRect& rect);
- /// Blit a pattern of pixels defined by a rectangle-clipped mask;
- /// typically used for text.
- virtual void blitMask(const SkMask&, const SkIRect& clip);
- /** If the blitter just sets a single value for each pixel, return the
- bitmap it draws into, and assign value. If not, return nullptr and ignore
- the value parameter.
- */
- virtual const SkPixmap* justAnOpaqueColor(uint32_t* value);
- // (x, y), (x + 1, y)
- 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)
- 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
- * from Choose() if the request cannot be fulfilled. Default impl
- * returns false.
- */
- virtual bool isNullBlitter() const;
- /**
- * Special methods for blitters that can blit more than one row at a time.
- * This function returns the number of rows that this blitter could optimally
- * process at a time. It is still required to support blitting one scanline
- * at a time.
- */
- virtual int requestRowsPreserved() const { return 1; }
- /**
- * This function allocates memory for the blitter that the blitter then owns.
- * The memory can be used by the calling function at will, but it will be
- * released when the blitter's destructor is called. This function returns
- * nullptr if no persistent memory is needed by the blitter.
- */
- virtual void* allocBlitMemory(size_t sz) {
- return fBlitMemory.reset(sz, SkAutoMalloc::kReuse_OnShrink);
- }
- ///@name non-virtual helpers
- void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
- void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
- void blitRegion(const SkRegion& clip);
- ///@}
- /** @name Factories
- Return the correct blitter to use given the specified context.
- */
- static SkBlitter* Choose(const SkPixmap& dst,
- const SkMatrix& matrix,
- const SkPaint& paint,
- SkArenaAlloc*,
- bool drawCoverage = false);
- static SkBlitter* ChooseSprite(const SkPixmap& dst,
- const SkPaint&,
- const SkPixmap& src,
- int left, int top,
- SkArenaAlloc*);
- ///@}
- static bool UseRasterPipelineBlitter(const SkPixmap&, const SkPaint&, const SkMatrix&);
- protected:
- SkAutoMalloc fBlitMemory;
- };
- /** This blitter silently never draws anything.
- */
- class SkNullBlitter : public SkBlitter {
- public:
- void blitH(int x, int y, int width) override;
- void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
- void blitV(int x, int y, int height, SkAlpha alpha) override;
- void blitRect(int x, int y, int width, int height) override;
- void blitMask(const SkMask&, const SkIRect& clip) override;
- const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
- bool isNullBlitter() const override;
- };
- /** Wraps another (real) blitter, and ensures that the real blitter is only
- called with coordinates that have been clipped by the specified clipRect.
- This means the caller need not perform the clipping ahead of time.
- */
- class SkRectClipBlitter : public SkBlitter {
- public:
- void init(SkBlitter* blitter, const SkIRect& clipRect) {
- SkASSERT(!clipRect.isEmpty());
- fBlitter = blitter;
- fClipRect = clipRect;
- }
- void blitH(int x, int y, int width) override;
- void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
- void blitV(int x, int y, int height, SkAlpha alpha) override;
- void blitRect(int x, int y, int width, int height) override;
- virtual void blitAntiRect(int x, int y, int width, int height,
- SkAlpha leftAlpha, SkAlpha rightAlpha) override;
- void blitMask(const SkMask&, const SkIRect& clip) override;
- const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
- int requestRowsPreserved() const override {
- return fBlitter->requestRowsPreserved();
- }
- void* allocBlitMemory(size_t sz) override {
- return fBlitter->allocBlitMemory(sz);
- }
- private:
- SkBlitter* fBlitter;
- SkIRect fClipRect;
- };
- /** Wraps another (real) blitter, and ensures that the real blitter is only
- called with coordinates that have been clipped by the specified clipRgn.
- This means the caller need not perform the clipping ahead of time.
- */
- class SkRgnClipBlitter : public SkBlitter {
- public:
- void init(SkBlitter* blitter, const SkRegion* clipRgn) {
- SkASSERT(clipRgn && !clipRgn->isEmpty());
- fBlitter = blitter;
- fRgn = clipRgn;
- }
- void blitH(int x, int y, int width) override;
- void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
- void blitV(int x, int y, int height, SkAlpha alpha) override;
- void blitRect(int x, int y, int width, int height) override;
- void blitAntiRect(int x, int y, int width, int height,
- SkAlpha leftAlpha, SkAlpha rightAlpha) override;
- void blitMask(const SkMask&, const SkIRect& clip) override;
- const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
- int requestRowsPreserved() const override {
- return fBlitter->requestRowsPreserved();
- }
- void* allocBlitMemory(size_t sz) override {
- return fBlitter->allocBlitMemory(sz);
- }
- private:
- SkBlitter* fBlitter;
- const SkRegion* fRgn;
- };
- #ifdef SK_DEBUG
- class SkRectClipCheckBlitter : public SkBlitter {
- public:
- void init(SkBlitter* blitter, const SkIRect& clipRect) {
- SkASSERT(blitter);
- SkASSERT(!clipRect.isEmpty());
- fBlitter = blitter;
- fClipRect = clipRect;
- }
- void blitH(int x, int y, int width) override;
- void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
- void blitV(int x, int y, int height, SkAlpha alpha) override;
- void blitRect(int x, int y, int width, int height) override;
- void blitAntiRect(int x, int y, int width, int height,
- SkAlpha leftAlpha, SkAlpha rightAlpha) override;
- void blitMask(const SkMask&, const SkIRect& clip) override;
- const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
- void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override;
- void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
- int requestRowsPreserved() const override {
- return fBlitter->requestRowsPreserved();
- }
- void* allocBlitMemory(size_t sz) override {
- return fBlitter->allocBlitMemory(sz);
- }
- private:
- SkBlitter* fBlitter;
- SkIRect fClipRect;
- };
- #endif
- /** Factory to set up the appropriate most-efficient wrapper blitter
- to apply a clip. Returns a pointer to a member, so lifetime must
- be managed carefully.
- */
- class SkBlitterClipper {
- public:
- SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip,
- const SkIRect* bounds = nullptr);
- private:
- SkNullBlitter fNullBlitter;
- SkRectClipBlitter fRectBlitter;
- SkRgnClipBlitter fRgnBlitter;
- };
- #define SHARD(code) fA->code; fB->code;
- class SkPairBlitter : public SkBlitter {
- SkBlitter* fA = nullptr;
- SkBlitter* fB = nullptr;
- public:
- SkPairBlitter(SkBlitter* a, SkBlitter* b) : fA(a), fB(b) {}
- void blitH(int x, int y, int width) override { SHARD(blitH(x, y, width)) }
- void blitAntiH(int x, int y, const SkAlpha alphas[], const int16_t runs[]) override {
- SHARD(blitAntiH(x, y, alphas, runs))
- }
- void blitV(int x, int y, int height, SkAlpha alpha) override {
- SHARD(blitV(x, y, height, alpha))
- }
- void blitRect(int x, int y, int width, int height) override {
- SHARD(blitRect(x, y, width, height))
- }
- void blitAntiRect(int x, int y, int width, int height,
- SkAlpha leftAlpha, SkAlpha rightAlpha) override {
- SHARD(blitAntiRect(x, y, width, height, leftAlpha, rightAlpha))
- }
- void blitMask(const SkMask& mask, const SkIRect& clip) override { SHARD(blitMask(mask, clip)) }
- const SkPixmap* justAnOpaqueColor(uint32_t* value) override { return nullptr; }
- void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override { SHARD(blitAntiH2(x, y, a0, a1)) }
- void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override { SHARD(blitAntiV2(x, y, a0, a1)) }
- };
- #undef SHARD
- #endif
|