SkImageFilter.h revision d686ac77c2c485c4a3302eda9c1de597a6f8c568
1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef SkImageFilter_DEFINED 9#define SkImageFilter_DEFINED 10 11#include "SkFlattenable.h" 12 13class SkBitmap; 14class SkColorFilter; 15class SkDevice; 16class SkMatrix; 17struct SkIPoint; 18struct SkIRect; 19class GrEffectRef; 20class GrTexture; 21 22/** 23 * Experimental. 24 * 25 * Base class for image filters. If one is installed in the paint, then 26 * all drawing occurs as usual, but it is as if the drawing happened into an 27 * offscreen (before the xfermode is applied). This offscreen bitmap will 28 * then be handed to the imagefilter, who in turn creates a new bitmap which 29 * is what will finally be drawn to the device (using the original xfermode). 30 * 31 * THIS SIGNATURE IS TEMPORARY 32 * 33 * There are several weaknesses in this function signature: 34 * 1. Does not expose the destination/target device, so filters that can draw 35 * directly to it are unable to take advantage of that optimization. 36 * 2. Does not expose a way to create a "compabitible" image (i.e. gpu -> gpu) 37 * 3. As with #1, the filter is unable to "read" the dest (which would be slow) 38 * 39 * Therefore, we should not create any real dependencies on this API yet -- it 40 * is being checked in as a check-point so we can explore these and other 41 * considerations. 42 */ 43class SK_API SkImageFilter : public SkFlattenable { 44public: 45 SK_DECLARE_INST_COUNT(SkImageFilter) 46 47 class Proxy { 48 public: 49 virtual ~Proxy() {}; 50 51 virtual SkDevice* createDevice(int width, int height) = 0; 52 // returns true if the proxy can handle this filter natively 53 virtual bool canHandleImageFilter(SkImageFilter*) = 0; 54 // returns true if the proxy handled the filter itself. if this returns 55 // false then the filter's code will be called. 56 virtual bool filterImage(SkImageFilter*, const SkBitmap& src, 57 const SkMatrix& ctm, 58 SkBitmap* result, SkIPoint* offset) = 0; 59 }; 60 61 /** 62 * Request a new (result) image to be created from the src image. 63 * If the src has no pixels (isNull()) then the request just wants to 64 * receive the config and width/height of the result. 65 * 66 * The matrix is the current matrix on the canvas. 67 * 68 * Offset is the amount to translate the resulting image relative to the 69 * src when it is drawn. 70 * 71 * If the result image cannot be created, return false, in which case both 72 * the result and offset parameters will be ignored by the caller. 73 */ 74 bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm, 75 SkBitmap* result, SkIPoint* offset); 76 77 /** 78 * Given the src bounds of an image, this returns the bounds of the result 79 * image after the filter has been applied. 80 */ 81 bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst); 82 83 /** 84 * Returns true if the filter can be expressed a single-pass 85 * GrEffect, used to process this filter on the GPU, or false if 86 * not. 87 * 88 * If effect is non-NULL, a new GrEffect instance is stored 89 * in it. The caller assumes ownership of the stage, and it is up to the 90 * caller to unref it. 91 * 92 * The effect can assume its vertexCoords space maps 1-to-1 with texels 93 * in the texture. 94 */ 95 virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const; 96 97 /** 98 * Returns true if the filter can be processed on the GPU. This is most 99 * often used for multi-pass effects, where intermediate results must be 100 * rendered to textures. For single-pass effects, use asNewEffect(). 101 * The default implementation returns false. 102 */ 103 virtual bool canFilterImageGPU() const; 104 105 /** 106 * Process this image filter on the GPU. src is the source image for 107 * processing, as a texture-backed bitmap. result is the destination 108 * bitmap, which should contain a texture-backed pixelref on success. 109 * The default implementation returns returns false and ignores the 110 * result parameter. 111 */ 112 virtual bool filterImageGPU(Proxy*, const SkBitmap& src, SkBitmap* result); 113 114 /** 115 * Returns this image filter as a color filter if possible, 116 * NULL otherwise. 117 */ 118 virtual SkColorFilter* asColorFilter() const; 119 120 /** 121 * Returns the number of inputs this filter will accept (some inputs can 122 * be NULL). 123 */ 124 int countInputs() const { return fInputCount; } 125 126 /** 127 * Returns the input filter at a given index, or NULL if no input is 128 * connected. The indices used are filter-specific. 129 */ 130 SkImageFilter* getInput(int i) const { 131 SkASSERT(i < fInputCount); 132 return fInputs[i]; 133 } 134 135protected: 136 SkImageFilter(int inputCount, SkImageFilter** inputs); 137 138 // Convenience constructor for 1-input filters. 139 explicit SkImageFilter(SkImageFilter* input); 140 141 // Convenience constructor for 2-input filters. 142 SkImageFilter(SkImageFilter* input1, SkImageFilter* input2); 143 144 virtual ~SkImageFilter(); 145 146 explicit SkImageFilter(SkFlattenableReadBuffer& rb); 147 148 virtual void flatten(SkFlattenableWriteBuffer& wb) const SK_OVERRIDE; 149 150 // Default impl returns false 151 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, 152 SkBitmap* result, SkIPoint* offset); 153 // Default impl copies src into dst and returns true 154 virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*); 155 156 // Return the result of processing the given input, or the source bitmap 157 // if we have no connected input at that index. 158 SkBitmap getInputResult(int index, Proxy*, const SkBitmap& src, const SkMatrix&, 159 SkIPoint*); 160 161private: 162 typedef SkFlattenable INHERITED; 163 int fInputCount; 164 SkImageFilter** fInputs; 165}; 166 167#endif 168