diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/core/SkDeviceLooper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/core/SkDeviceLooper.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,96 @@ +/* + * 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 SkDeviceLooper_DEFINED +#define SkDeviceLooper_DEFINED + +#include "SkBitmap.h" +#include "SkMatrix.h" +#include "SkRasterClip.h" + +/** + * Helper class to manage "tiling" a large coordinate space into managable + * chunks, where managable means areas that are <= some max critical coordinate + * size. + * + * The constructor takes an antialiasing bool, which affects what this maximum + * allowable size is: If we're drawing BW, then we need coordinates to stay + * safely within fixed-point range (we use +- 16K, to give ourselves room to + * add/subtract two fixed values and still be in range. If we're drawing AA, + * then we reduce that size by the amount that the supersampler scan converter + * needs (at the moment, that is 4X, so the "safe" range is +- 4K). + * + * For performance reasons, the class first checks to see if any help is needed + * at all, and if not (i.e. the specified bounds and base bitmap area already + * in the safe-zone, then the class does nothing (effectively). + */ +class SkDeviceLooper { +public: + SkDeviceLooper(const SkBitmap& base, const SkRasterClip&, + const SkIRect& bounds, bool aa); + ~SkDeviceLooper(); + + const SkBitmap& getBitmap() const { + SkASSERT(kDone_State != fState); + SkASSERT(fCurrBitmap); + return *fCurrBitmap; + } + + const SkRasterClip& getRC() const { + SkASSERT(kDone_State != fState); + SkASSERT(fCurrRC); + return *fCurrRC; + } + + void mapRect(SkRect* dst, const SkRect& src) const; + void mapMatrix(SkMatrix* dst, const SkMatrix& src) const; + + /** + * Call next to setup the looper to return a valid coordinate chunk. + * Each time this returns true, it is safe to call mapRect() and + * mapMatrix(), to convert from "global" coordinate values to ones that + * are local to this chunk. + * + * When next() returns false, the list of chunks is done, and mapRect() + * and mapMatrix() should no longer be called. + */ + bool next(); + +private: + const SkBitmap& fBaseBitmap; + const SkRasterClip& fBaseRC; + + enum State { + kDone_State, // iteration is complete, getters will assert + kSimple_State, // no translate/clip mods needed + kComplex_State + }; + + // storage for our tiled versions. Perhaps could use SkTLazy + SkBitmap fSubsetBitmap; + SkRasterClip fSubsetRC; + + const SkBitmap* fCurrBitmap; + const SkRasterClip* fCurrRC; + SkIRect fClippedBounds; + SkIPoint fCurrOffset; + int fDelta; + State fState; + + enum Delta { + kBW_Delta = 1 << 14, // 16K, gives room to spare for fixedpoint + kAA_Delta = kBW_Delta >> 2 // supersample 4x + }; + + bool fitsInDelta(const SkIRect& r) const { + return r.right() < fDelta && r.bottom() < fDelta; + } + + bool computeCurrBitmapAndClip(); +}; + +#endif