SkImageFilter.h revision 9c39744a00573b7133fc765b0a9d50a0ceace7b8
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 SkDevice; 15class SkMatrix; 16struct SkIPoint; 17struct SkIRect; 18struct SkRect; 19class GrCustomStage; 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 * GrCustomStage, used to process this filter on the GPU, or false if 86 * not. 87 * 88 * If stage is non-NULL, a new GrCustomStage 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 virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const; 93 94 /** 95 * Returns true if the filter can be processed on the GPU. This is most 96 * often used for multi-pass effects, where intermediate results must be 97 * rendered to textures. For single-pass effects, use asNewCustomStage(). 98 * The default implementation returns false. 99 */ 100 virtual bool canFilterImageGPU() const; 101 102 /** 103 * Process this image filter on the GPU. texture is the source texture 104 * for processing, and rect is the effect region to process. The 105 * function must allocate a new texture of at least rect width/height 106 * size, and return it to the caller. The default implementation returns 107 * NULL. 108 */ 109 virtual GrTexture* onFilterImageGPU(Proxy*, GrTexture* texture, const SkRect& rect); 110 111protected: 112 SkImageFilter() {} 113 explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {} 114 115 // Default impl returns false 116 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, 117 SkBitmap* result, SkIPoint* offset); 118 // Default impl copies src into dst and returns true 119 virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*); 120 121private: 122 typedef SkFlattenable INHERITED; 123}; 124 125#endif 126