SkImageFilter.h revision a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60ad
1894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com/* 2894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Copyright 2011 Google Inc. 3894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * 4894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Use of this source code is governed by a BSD-style license that can be 5894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * found in the LICENSE file. 6894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com */ 7894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com 8894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#ifndef SkImageFilter_DEFINED 9894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#define SkImageFilter_DEFINED 10894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com 11f3c15b7cfc4eed2528f7db87ea6c1444b55ee856bungeman#include "../private/SkTemplates.h" 128c874eee943bdea0fab5b4d2707083c863e37c55senorblanco#include "SkFilterQuality.h" 13894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#include "SkFlattenable.h" 144cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org#include "SkMatrix.h" 15194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org#include "SkRect.h" 162c55d7b7f3c2c834085d019bf6b1519b315c8aa1reed#include "SkSurfaceProps.h" 17894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com 182c55d7b7f3c2c834085d019bf6b1519b315c8aa1reedclass GrFragmentProcessor; 192c55d7b7f3c2c834085d019bf6b1519b315c8aa1reedclass GrTexture; 202c55d7b7f3c2c834085d019bf6b1519b315c8aa1reedclass SkBaseDevice; 2115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comclass SkBitmap; 228d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.orgclass SkColorFilter; 23c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.comstruct SkIPoint; 2415356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com 2515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com/** 2615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com * Base class for image filters. If one is installed in the paint, then 2715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com * all drawing occurs as usual, but it is as if the drawing happened into an 2815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com * offscreen (before the xfermode is applied). This offscreen bitmap will 2915356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com * then be handed to the imagefilter, who in turn creates a new bitmap which 3015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com * is what will finally be drawn to the device (using the original xfermode). 3115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com */ 3254e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.orgclass SK_API SkImageFilter : public SkFlattenable { 33894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.compublic: 3455b6d8be997a447ef9ce0f029697677a940bfc24senorblanco // This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to 3555b6d8be997a447ef9ce0f029697677a940bfc24senorblanco // (result, offset). 36be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco class Cache : public SkRefCnt { 3755b6d8be997a447ef9ce0f029697677a940bfc24senorblanco public: 3855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco struct Key; 39be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco virtual ~Cache() {} 40be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco static Cache* Create(size_t maxBytes); 41be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco static Cache* Get(); 4255b6d8be997a447ef9ce0f029697677a940bfc24senorblanco virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0; 4355b6d8be997a447ef9ce0f029697677a940bfc24senorblanco virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0; 44242397a1c95e34e3e2e5e85c85c81090317115cbmtklein virtual void purge() {} 45627769144d233b3abce5ee86cf315df61fa8dcd7xidachen virtual void purgeByImageFilterId(uint32_t) {} 4655b6d8be997a447ef9ce0f029697677a940bfc24senorblanco }; 4755b6d8be997a447ef9ce0f029697677a940bfc24senorblanco 484cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org class Context { 494cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org public: 504e23cdaa6b892afeaa150c6d74099dc6c2065b7ereed Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache) 51c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed : fCTM(ctm) 52c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed , fClipBounds(clipBounds) 53c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed , fCache(cache) 54c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed {} 55c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed 564cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkMatrix& ctm() const { return fCTM; } 574cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkIRect& clipBounds() const { return fClipBounds; } 58be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco Cache* cache() const { return fCache; } 59c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed 604cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org private: 61c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed SkMatrix fCTM; 62c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed SkIRect fClipBounds; 63c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed Cache* fCache; 644cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org }; 654cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org 66189186337eb91b0b21c15db42377bbf3ae4acf23reed class CropRect { 67189186337eb91b0b21c15db42377bbf3ae4acf23reed public: 68189186337eb91b0b21c15db42377bbf3ae4acf23reed enum CropEdge { 69189186337eb91b0b21c15db42377bbf3ae4acf23reed kHasLeft_CropEdge = 0x01, 70189186337eb91b0b21c15db42377bbf3ae4acf23reed kHasTop_CropEdge = 0x02, 71ed7cf273226ca5818a9d58b0f9183d665bb1ff58senorblanco kHasWidth_CropEdge = 0x04, 72ed7cf273226ca5818a9d58b0f9183d665bb1ff58senorblanco kHasHeight_CropEdge = 0x08, 73189186337eb91b0b21c15db42377bbf3ae4acf23reed kHasAll_CropEdge = 0x0F, 74189186337eb91b0b21c15db42377bbf3ae4acf23reed }; 75189186337eb91b0b21c15db42377bbf3ae4acf23reed CropRect() {} 76189186337eb91b0b21c15db42377bbf3ae4acf23reed explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) 77189186337eb91b0b21c15db42377bbf3ae4acf23reed : fRect(rect), fFlags(flags) {} 78189186337eb91b0b21c15db42377bbf3ae4acf23reed uint32_t flags() const { return fFlags; } 79189186337eb91b0b21c15db42377bbf3ae4acf23reed const SkRect& rect() const { return fRect; } 80189186337eb91b0b21c15db42377bbf3ae4acf23reed#ifndef SK_IGNORE_TO_STRING 81189186337eb91b0b21c15db42377bbf3ae4acf23reed void toString(SkString* str) const; 82189186337eb91b0b21c15db42377bbf3ae4acf23reed#endif 83189186337eb91b0b21c15db42377bbf3ae4acf23reed 84189186337eb91b0b21c15db42377bbf3ae4acf23reed /** 85189186337eb91b0b21c15db42377bbf3ae4acf23reed * Apply this cropRect to the imageBounds. If a given edge of the cropRect is not 86189186337eb91b0b21c15db42377bbf3ae4acf23reed * set, then the corresponding edge from imageBounds will be used. 87189186337eb91b0b21c15db42377bbf3ae4acf23reed * 88189186337eb91b0b21c15db42377bbf3ae4acf23reed * Note: imageBounds is in "device" space, as the output cropped rectangle will be, 89189186337eb91b0b21c15db42377bbf3ae4acf23reed * so the context's CTM is ignore for those. It is only applied the croprect's bounds. 90189186337eb91b0b21c15db42377bbf3ae4acf23reed * 91189186337eb91b0b21c15db42377bbf3ae4acf23reed * The resulting rect will be intersected with the context's clip. If that intersection is 92189186337eb91b0b21c15db42377bbf3ae4acf23reed * empty, then this returns false and cropped is unmodified. 93189186337eb91b0b21c15db42377bbf3ae4acf23reed */ 94189186337eb91b0b21c15db42377bbf3ae4acf23reed bool applyTo(const SkIRect& imageBounds, const Context&, SkIRect* cropped) const; 95189186337eb91b0b21c15db42377bbf3ae4acf23reed 96189186337eb91b0b21c15db42377bbf3ae4acf23reed private: 97189186337eb91b0b21c15db42377bbf3ae4acf23reed SkRect fRect; 98189186337eb91b0b21c15db42377bbf3ae4acf23reed uint32_t fFlags; 99189186337eb91b0b21c15db42377bbf3ae4acf23reed }; 100189186337eb91b0b21c15db42377bbf3ae4acf23reed 101a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco enum TileUsage { 102a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco kPossible_TileUsage, //!< the created device may be drawn tiled 103a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco kNever_TileUsage, //!< the created device will never be drawn tiled 104a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco }; 105a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco 10676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com class Proxy { 10776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com public: 10888d064d0e481949184305c7b1d6b282dddffac39reed virtual ~Proxy() {} 1092766c00fc0b6a07d46e5f74cdad45da2ef625237mtklein 110a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco virtual SkBaseDevice* createDevice(int width, int height, 111a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco TileUsage usage = kNever_TileUsage) = 0; 11288d064d0e481949184305c7b1d6b282dddffac39reed 11388d064d0e481949184305c7b1d6b282dddffac39reed // Returns true if the proxy handled the filter itself. If this returns 11488d064d0e481949184305c7b1d6b282dddffac39reed // false then the filter's code will be called. 11588d064d0e481949184305c7b1d6b282dddffac39reed virtual bool filterImage(const SkImageFilter*, const SkBitmap& src, 11688d064d0e481949184305c7b1d6b282dddffac39reed const SkImageFilter::Context&, 11788d064d0e481949184305c7b1d6b282dddffac39reed SkBitmap* result, SkIPoint* offset) = 0; 11888d064d0e481949184305c7b1d6b282dddffac39reed }; 11988d064d0e481949184305c7b1d6b282dddffac39reed 12088d064d0e481949184305c7b1d6b282dddffac39reed class DeviceProxy : public Proxy { 12188d064d0e481949184305c7b1d6b282dddffac39reed public: 12288d064d0e481949184305c7b1d6b282dddffac39reed DeviceProxy(SkBaseDevice* device) : fDevice(device) {} 12388d064d0e481949184305c7b1d6b282dddffac39reed 124a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco SkBaseDevice* createDevice(int width, int height, 125a9fbd1676cf8bd0078c5be1f1c4abd4c76ea60adsenorblanco TileUsage usage = kNever_TileUsage) override; 126efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips 127efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // Returns true if the proxy handled the filter itself. If this returns 12876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com // false then the filter's code will be called. 1292c55d7b7f3c2c834085d019bf6b1519b315c8aa1reed bool filterImage(const SkImageFilter*, const SkBitmap& src, const SkImageFilter::Context&, 130d82bc7b90ab0a88d6fb401994f3763d3057ab6e7reed SkBitmap* result, SkIPoint* offset) override; 131efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips 1322c55d7b7f3c2c834085d019bf6b1519b315c8aa1reed private: 133efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkBaseDevice* fDevice; 13476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com }; 1352766c00fc0b6a07d46e5f74cdad45da2ef625237mtklein 136894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com /** 137894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Request a new (result) image to be created from the src image. 138894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * If the src has no pixels (isNull()) then the request just wants to 139894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * receive the config and width/height of the result. 140894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * 141894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * The matrix is the current matrix on the canvas. 142894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * 143894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * Offset is the amount to translate the resulting image relative to the 1446776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * src when it is drawn. This is an out-param. 145894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * 146894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * If the result image cannot be created, return false, in which case both 147894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com * the result and offset parameters will be ignored by the caller. 148894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com */ 1494cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org bool filterImage(Proxy*, const SkBitmap& src, const Context&, 150ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const; 15115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com 15215356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com /** 15332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com * Given the src bounds of an image, this returns the bounds of the result 15432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com * image after the filter has been applied. 15532d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com */ 156c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const; 15732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com 15832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com /** 159302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org * Returns true if the filter can be processed on the GPU. This is most 160302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org * often used for multi-pass effects, where intermediate results must be 161b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * rendered to textures. For single-pass effects, use asFragmentProcessor(). 162b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * The default implementation returns asFragmentProcessor(NULL, NULL, SkMatrix::I(), 1637938bae14af94c1d48d122a2d686e123b66411a7senorblanco@chromium.org * SkIRect()). 16405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org */ 165302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org virtual bool canFilterImageGPU() const; 16605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 16705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org /** 1683284017a60ea4fc3dc5b95838ba0c301ee1e4e8dskia.committer@gmail.com * Process this image filter on the GPU. This is most often used for 169d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org * multi-pass effects, where intermediate results must be rendered to 170b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * textures. For single-pass effects, use asFragmentProcessor(). src is the 171d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org * source image for processing, as a texture-backed bitmap. result is 172d043ccee3788ea4192806bd8c94484ed003fa828senorblanco@chromium.org * the destination bitmap, which should contain a texture-backed pixelref 173de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com * on success. offset is the amount to translate the resulting image 1747b320703d47ff2b242ae74faba5e4b0af3560d71commit-bot@chromium.org * relative to the src when it is drawn. The default implementation does 175b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * single-pass processing using asFragmentProcessor(). 17605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org */ 1774cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&, 178ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const; 17905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1808d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org /** 181a1c511b8704c6c266b90860a4c68f30ca7514f9bsugoi@google.com * Returns whether this image filter is a color filter and puts the color filter into the 1824b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com * "filterPtr" parameter if it can. Does nothing otherwise. 1834b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com * If this returns false, then the filterPtr is unchanged. 1844b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com * If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler 1854b6d432f1e4ea0a6556dfff1b4d19b69ca005c27sugoi@google.com * (i.e. it may not be set to NULL). 1868d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org */ 187cedc36f18b2254c5ee21f6348124886b6db4f4c2reed bool isColorFilterNode(SkColorFilter** filterPtr) const { 188cedc36f18b2254c5ee21f6348124886b6db4f4c2reed return this->onIsColorFilterNode(filterPtr); 189cedc36f18b2254c5ee21f6348124886b6db4f4c2reed } 190cedc36f18b2254c5ee21f6348124886b6db4f4c2reed 191cedc36f18b2254c5ee21f6348124886b6db4f4c2reed // DEPRECATED : use isColorFilterNode() instead 192cedc36f18b2254c5ee21f6348124886b6db4f4c2reed bool asColorFilter(SkColorFilter** filterPtr) const { 193cedc36f18b2254c5ee21f6348124886b6db4f4c2reed return this->isColorFilterNode(filterPtr); 194cedc36f18b2254c5ee21f6348124886b6db4f4c2reed } 195cedc36f18b2254c5ee21f6348124886b6db4f4c2reed 196cedc36f18b2254c5ee21f6348124886b6db4f4c2reed /** 197cedc36f18b2254c5ee21f6348124886b6db4f4c2reed * Returns true (and optionally returns a ref'd filter) if this imagefilter can be completely 198cedc36f18b2254c5ee21f6348124886b6db4f4c2reed * replaced by the returned colorfilter. i.e. the two effects will affect drawing in the 199cedc36f18b2254c5ee21f6348124886b6db4f4c2reed * same way. 200cedc36f18b2254c5ee21f6348124886b6db4f4c2reed */ 201a544eda5ddea215037b1ada6ba5cfc98f6c8ee15senorblanco bool asAColorFilter(SkColorFilter** filterPtr) const; 2028d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org 2038d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org /** 2048d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org * Returns the number of inputs this filter will accept (some inputs can 2058d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org * be NULL). 2068d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org */ 2078d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org int countInputs() const { return fInputCount; } 2088d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org 2098d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org /** 2108d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org * Returns the input filter at a given index, or NULL if no input is 2118d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org * connected. The indices used are filter-specific. 2128d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org */ 2138d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org SkImageFilter* getInput(int i) const { 2148d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org SkASSERT(i < fInputCount); 2158d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org return fInputs[i]; 2168d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org } 2178d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org 218194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org /** 2193f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * Returns whether any edges of the crop rect have been set. The crop 2203f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * rect is set at construction time, and determines which pixels from the 221189186337eb91b0b21c15db42377bbf3ae4acf23reed * input image will be processed, and which pixels in the output image will be allowed. 222189186337eb91b0b21c15db42377bbf3ae4acf23reed * The size of the crop rect should be 2233f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * used as the size of the destination image. The origin of this rect 2243f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * should be used to offset access to the input images, and should also 2253f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * be added to the "offset" parameter in onFilterImage and 2263f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * filterImageGPU(). (The latter ensures that the resulting buffer is 2273f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org * drawn in the correct location.) 228194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org */ 2293f1f2a3a59c43e5bce67ab98e55df45bc7c933a3senorblanco@chromium.org bool cropRectIsSet() const { return fCropRect.flags() != 0x0; } 230194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 231b3fe1b87e0ceefa27c183420c02d93d8fdf495dcreed CropRect getCropRect() const { return fCropRect; } 232b3fe1b87e0ceefa27c183420c02d93d8fdf495dcreed 233336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org // Default impl returns union of all input bounds. 234336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org virtual void computeFastBounds(const SkRect&, SkRect*) const; 235336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 2360abdf766d395ed3b7059511425f431589eca05f6senorblanco // Can this filter DAG compute the resulting bounds of an object-space rectangle? 237a544eda5ddea215037b1ada6ba5cfc98f6c8ee15senorblanco virtual bool canComputeFastBounds() const; 2380abdf766d395ed3b7059511425f431589eca05f6senorblanco 2398c874eee943bdea0fab5b4d2707083c863e37c55senorblanco /** 24094dd7a52d3fe0632cd830f2e9cd14103c2726aacreed * If this filter can be represented by another filter + a localMatrix, return that filter, 24194dd7a52d3fe0632cd830f2e9cd14103c2726aacreed * else return null. 24294dd7a52d3fe0632cd830f2e9cd14103c2726aacreed */ 24394dd7a52d3fe0632cd830f2e9cd14103c2726aacreed SkImageFilter* newWithLocalMatrix(const SkMatrix& matrix) const; 24494dd7a52d3fe0632cd830f2e9cd14103c2726aacreed 24594dd7a52d3fe0632cd830f2e9cd14103c2726aacreed /** 2468c874eee943bdea0fab5b4d2707083c863e37c55senorblanco * Create an SkMatrixImageFilter, which transforms its input by the given matrix. 2478c874eee943bdea0fab5b4d2707083c863e37c55senorblanco */ 2488c874eee943bdea0fab5b4d2707083c863e37c55senorblanco static SkImageFilter* CreateMatrixFilter(const SkMatrix& matrix, 2498c874eee943bdea0fab5b4d2707083c863e37c55senorblanco SkFilterQuality, 2508c874eee943bdea0fab5b4d2707083c863e37c55senorblanco SkImageFilter* input = NULL); 2518c874eee943bdea0fab5b4d2707083c863e37c55senorblanco 2524509517e03fd245298d4059f4568435d640a1758kkinnunen#if SK_SUPPORT_GPU 2536aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org /** 2546aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org * Wrap the given texture in a texture-backed SkBitmap. 2556aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org */ 2566aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org static void WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result); 2576aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 2589a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco // Helper function which invokes GPU filter processing on the 2599a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco // input at the specified "index". If the input is null, it leaves 2609a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco // "result" and "offset" untouched, and returns true. If the input 2619a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco // has a GPU implementation, it will be invoked directly. 2629a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco // Otherwise, the filter will be processed in software and 2639a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco // uploaded to the GPU. 2649a70b6ef59c38f3cbe6646aed624f22155326d05senorblanco bool filterInputGPU(int index, SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&, 2652c3176c18fcb0ef1594ca9dfbcabcb5e86086301robertphillips SkBitmap* result, SkIPoint* offset) const; 2666aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org#endif 2676aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org 268f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips SK_TO_STRING_PUREVIRT() 269c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter) 270c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org 271894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.comprotected: 272b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed class Common { 273b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed public: 274b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed Common() {} 275b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed ~Common(); 276b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed 2779fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed /** 2789fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * Attempt to unflatten the cropRect and the expected number of input filters. 2799fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * If any number of input filters is valid, pass -1. 2809fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * If this fails (i.e. corrupt buffer or contents) then return false and common will 2819fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * be left uninitialized. 2829fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * If this returns true, then inputCount() is the number of found input filters, each 2839fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * of which may be NULL or a valid imagefilter. 2849fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed */ 2859fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed bool unflatten(SkReadBuffer&, int expectedInputs); 2869fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 2879fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const CropRect& cropRect() const { return fCropRect; } 288b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed int inputCount() const { return fInputs.count(); } 289b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed SkImageFilter** inputs() const { return fInputs.get(); } 290b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed 2919fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkImageFilter* getInput(int index) const { return fInputs[index]; } 2929fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 293b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed // If the caller wants a copy of the inputs, call this and it will transfer ownership 294b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed // of the unflattened input filters to the caller. This is just a short-cut for copying 295b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed // the inputs, calling ref() on each, and then waiting for Common's destructor to call 296b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed // unref() on each. 297b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed void detachInputs(SkImageFilter** inputs); 298b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed 299b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed private: 300b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed CropRect fCropRect; 301b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed // most filters accept at most 2 input-filters 302b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed SkAutoSTArray<2, SkImageFilter*> fInputs; 303b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed 304b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed void allocInputs(int count); 305b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed }; 306b959ec7815ae0f65f2aabdeaf280a2a2ee6db955reed 30724e06d5244ae96e440410e1d76e039983b2efac9senorblanco SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL); 3089f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 3099f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org virtual ~SkImageFilter(); 3109f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 311c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org /** 3128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org * Constructs a new SkImageFilter read from an SkReadBuffer object. 313c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org * 314c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org * @param inputCount The exact number of inputs expected for this SkImageFilter object. 315c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org * -1 can be used if the filter accepts any number of inputs. 3168b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org * @param rb SkReadBuffer object from which the SkImageFilter is read. 317c84728d72a47415929464c5cf062300d86a91246commit-bot@chromium.org */ 3188b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org explicit SkImageFilter(int inputCount, SkReadBuffer& rb); 3199f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org 32036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer&) const override; 32132d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com 3226776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org /** 3236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * This is the virtual which should be overridden by the derived class 3246776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * to perform image filtering. 3256776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * 3266776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * src is the original primitive bitmap. If the filter has a connected 3276776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * input, it should recurse on that input and use that in place of src. 3286776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * 3296776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * The matrix is the current matrix on the canvas. 3306776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * 3316776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * Offset is the amount to translate the resulting image relative to the 3326776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * src when it is drawn. This is an out-param. 3336776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * 3346776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * If the result image cannot be created, this should false, in which 3356776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * case both the result and offset parameters will be ignored by the 3366776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org * caller. 3376776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org */ 3384cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, 339ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const; 340c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Given the bounds of the destination rect to be filled in device 341c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // coordinates (first parameter), and the CTM, compute (conservatively) 342c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // which rect of the source image would be required (third parameter). 343c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Used for clipping and temp-buffer allocations, so the result need not 344c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // be exact, but should never be smaller than the real answer. The default 345c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // implementation recursively unions all input bounds, or returns false if 346c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // no inputs. 347c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const; 348db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco enum MapDirection { 349db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco kForward_MapDirection, 350db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco kReverse_MapDirection 351db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco }; 352db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco 353db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco /** 354db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * Performs a forwards or reverse mapping of the given rect to accommodate 355db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * this filter's margin requirements. kForward_MapDirection is used to 356db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * determine the destination pixels which would be touched by filtering 357db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * the given given source rect (e.g., given source bitmap bounds, 358db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * determine the optimal bounds of the filtered offscreen bitmap). 359db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * kReverse_MapDirection is used to determine which pixels of the 360db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * input(s) would be required to fill the given destination rect 361db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * (e.g., clip bounds). NOTE: these operations may not be the 362db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * inverse of the other. For example, blurring expands the given rect 363db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * in both forward and reverse directions. Unlike 364db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * onFilterBounds(), this function is non-recursive. 365db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco */ 366db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco virtual void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const; 367894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com 368b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco // Helper function which invokes filter processing on the input at the 369b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco // specified "index". If the input is null, it leaves "result" and 370b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco // "offset" untouched, and returns true. If the input is non-null, it 371b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco // calls filterImage() on that input, and returns true on success. 372b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco // i.e., return !getInput(index) || getInput(index)->filterImage(...); 373b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco bool filterInput(int index, Proxy*, const SkBitmap& src, const Context&, 3744e23cdaa6b892afeaa150c6d74099dc6c2065b7ereed SkBitmap* result, SkIPoint* offset) const; 375b9519f86bbce946e505980a4fa950fdc4bcf74absenorblanco 376cedc36f18b2254c5ee21f6348124886b6db4f4c2reed /** 377cedc36f18b2254c5ee21f6348124886b6db4f4c2reed * Return true (and return a ref'd colorfilter) if this node in the DAG is just a 378cedc36f18b2254c5ee21f6348124886b6db4f4c2reed * colorfilter w/o CropRect constraints. 379cedc36f18b2254c5ee21f6348124886b6db4f4c2reed */ 380cedc36f18b2254c5ee21f6348124886b6db4f4c2reed virtual bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const { 381cedc36f18b2254c5ee21f6348124886b6db4f4c2reed return false; 382cedc36f18b2254c5ee21f6348124886b6db4f4c2reed } 383cedc36f18b2254c5ee21f6348124886b6db4f4c2reed 3844449398b324a7d6226a71e766561ace0028b5153senorblanco /** Given a "src" bitmap and its "srcOffset", computes source and 3854449398b324a7d6226a71e766561ace0028b5153senorblanco * destination bounds for this filter. Initial bounds are the 3864449398b324a7d6226a71e766561ace0028b5153senorblanco * "src" bitmap bounds offset by "srcOffset". "dstBounds" are 3874449398b324a7d6226a71e766561ace0028b5153senorblanco * computed by transforming the crop rect by the context's CTM, 3884449398b324a7d6226a71e766561ace0028b5153senorblanco * applying it to the initial bounds, and intersecting the result 3894449398b324a7d6226a71e766561ace0028b5153senorblanco * with the context's clip bounds. "srcBounds" (if non-null) are 3904449398b324a7d6226a71e766561ace0028b5153senorblanco * computed by intersecting the initial bounds with "dstBounds", to 3914449398b324a7d6226a71e766561ace0028b5153senorblanco * ensure that we never sample outside of the crop rect (this restriction 3924449398b324a7d6226a71e766561ace0028b5153senorblanco * may be relaxed in the future). 393118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org */ 394118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset, 3954449398b324a7d6226a71e766561ace0028b5153senorblanco SkIRect* dstBounds, SkIRect* srcBounds = nullptr) const; 396118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org 397118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org /** Same as the above call, except that if the resulting crop rect is not 398118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org * entirely contained by the source bitmap's bounds, it creates a new 399118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org * bitmap in "result" and pads the edges with transparent black. In that 400118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org * case, the srcOffset is modified to be the same as the bounds, since no 401118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org * further adjustment is needed by the caller. This version should only 402118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org * be used by filters which are not capable of processing a smaller 403118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org * source bitmap into a larger destination. 404118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org */ 405118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset, 406118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org SkIRect* bounds, SkBitmap* result) const; 407194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 4081aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org /** 4091aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * Returns true if the filter can be expressed a single-pass 410b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * GrProcessor, used to process this filter on the GPU, or false if 4111aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * not. 4121aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * 413b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * If effect is non-NULL, a new GrProcessor instance is stored 4141aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * in it. The caller assumes ownership of the stage, and it is up to the 4151aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * caller to unref it. 4161aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * 4171aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * The effect can assume its vertexCoords space maps 1-to-1 with texels 4181aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * in the texture. "matrix" is a transformation to apply to filter 4191aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * parameters before they are used in the effect. Note that this function 4201aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * will be called with (NULL, NULL, SkMatrix::I()) to query for support, 4211aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org * so returning "true" indicates support for all possible matrices. 4221aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org */ 4234a339529612a43871d021877e58698e067d6c4cdbsalomon virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&, 4244a339529612a43871d021877e58698e067d6c4cdbsalomon const SkIRect& bounds) const; 4251aa68723b8ef4ce0b6db9fe51e7d8051cdd543ffsenorblanco@chromium.org 426db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco /** 427db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * Creates a modified Context for use when recursing up the image filter DAG. 428db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * The clip bounds are adjusted to accommodate any margins that this 429db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * filter requires by calling this node's 430db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco * onFilterNodeBounds(..., kReverse_MapDirection). 431db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco */ 432db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco Context mapContext(const Context& ctx) const; 433db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco 434894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.comprivate: 435242397a1c95e34e3e2e5e85c85c81090317115cbmtklein friend class SkGraphics; 436242397a1c95e34e3e2e5e85c85c81090317115cbmtklein static void PurgeCache(); 437242397a1c95e34e3e2e5e85c85c81090317115cbmtklein 43855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco bool usesSrcInput() const { return fUsesSrcInput; } 43955b6d8be997a447ef9ce0f029697677a940bfc24senorblanco 44054e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org typedef SkFlattenable INHERITED; 4418d21f6c7a9d0cf4f87d77c235c6da7203620c7e5senorblanco@chromium.org int fInputCount; 4429f25de79009ce721aa13abe71c38179d5a6710e2senorblanco@chromium.org SkImageFilter** fInputs; 44355b6d8be997a447ef9ce0f029697677a940bfc24senorblanco bool fUsesSrcInput; 444b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org CropRect fCropRect; 44555b6d8be997a447ef9ce0f029697677a940bfc24senorblanco uint32_t fUniqueID; // Globally unique 446894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com}; 447894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com 4489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed/** 4499fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed * Helper to unflatten the common data, and return NULL if we fail. 4509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed */ 4519fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount) \ 4529fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed Common localVar; \ 4539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed do { \ 4549fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (!localVar.unflatten(buffer, expectedCount)) { \ 4559fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; \ 4569fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } \ 4579fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } while (0) 4589fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 459894aa9a7af0e5598600df694d184d3c7d2e454b0reed@google.com#endif 460