10a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger/* 20a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Copyright 2013 Google Inc. 30a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * 40a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be 50a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * found in the LICENSE file. 60a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */ 70a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 80a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifndef SkDeviceLooper_DEFINED 90a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#define SkDeviceLooper_DEFINED 100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkBitmap.h" 120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkMatrix.h" 130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkRasterClip.h" 140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger/** 160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Helper class to manage "tiling" a large coordinate space into managable 170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * chunks, where managable means areas that are <= some max critical coordinate 180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * size. 190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * 200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * The constructor takes an antialiasing bool, which affects what this maximum 210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * allowable size is: If we're drawing BW, then we need coordinates to stay 220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * safely within fixed-point range (we use +- 16K, to give ourselves room to 230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * add/subtract two fixed values and still be in range. If we're drawing AA, 240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * then we reduce that size by the amount that the supersampler scan converter 250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * needs (at the moment, that is 4X, so the "safe" range is +- 4K). 260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * 270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * For performance reasons, the class first checks to see if any help is needed 280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * at all, and if not (i.e. the specified bounds and base bitmap area already 290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * in the safe-zone, then the class does nothing (effectively). 300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */ 310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass SkDeviceLooper { 320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic: 330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkDeviceLooper(const SkBitmap& base, const SkRasterClip&, 340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkIRect& bounds, bool aa); 350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger ~SkDeviceLooper(); 360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkBitmap& getBitmap() const { 380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(kDone_State != fState); 390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fCurrBitmap); 400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return *fCurrBitmap; 410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkRasterClip& getRC() const { 440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(kDone_State != fState); 450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkASSERT(fCurrRC); 460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return *fCurrRC; 470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger void mapRect(SkRect* dst, const SkRect& src) const; 500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger void mapMatrix(SkMatrix* dst, const SkMatrix& src) const; 510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger /** 530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Call next to setup the looper to return a valid coordinate chunk. 540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * Each time this returns true, it is safe to call mapRect() and 550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * mapMatrix(), to convert from "global" coordinate values to ones that 560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * are local to this chunk. 570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * 580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * When next() returns false, the list of chunks is done, and mapRect() 590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger * and mapMatrix() should no longer be called. 600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger */ 610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool next(); 620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate: 640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkBitmap& fBaseBitmap; 650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkRasterClip& fBaseRC; 660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger enum State { 680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kDone_State, // iteration is complete, getters will assert 690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kSimple_State, // no translate/clip mods needed 700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kComplex_State 710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger }; 720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // storage for our tiled versions. Perhaps could use SkTLazy 740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmap fSubsetBitmap; 750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkRasterClip fSubsetRC; 760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkBitmap* fCurrBitmap; 780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger const SkRasterClip* fCurrRC; 790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkIRect fClippedBounds; 800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkIPoint fCurrOffset; 810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int fDelta; 820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger State fState; 830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger enum Delta { 850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kBW_Delta = 1 << 14, // 16K, gives room to spare for fixedpoint 860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kAA_Delta = kBW_Delta >> 2 // supersample 4x 870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger }; 880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool fitsInDelta(const SkIRect& r) const { 900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger return r.right() < fDelta && r.bottom() < fDelta; 910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool computeCurrBitmapAndClip(); 940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}; 950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif 97