blob: 1c0a05159fd0ab38b42e665aa70a51df24d6368f [file] [log] [blame]
reed@google.com894aa9a2011-09-23 14:49:49 +00001/*
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"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000012#include "SkSize.h"
reed@google.com894aa9a2011-09-23 14:49:49 +000013
reed@google.com15356a62011-11-03 19:29:08 +000014class SkBitmap;
reed@google.com76dd2772012-01-05 21:15:07 +000015class SkDevice;
reed@google.com15356a62011-11-03 19:29:08 +000016class SkMatrix;
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000017struct SkIPoint;
18struct SkIRect;
reed@google.com15356a62011-11-03 19:29:08 +000019struct SkPoint;
djsollen@google.comc73dd5c2012-08-07 15:54:32 +000020struct SkRect;
senorblanco@chromium.org894790d2012-07-11 16:01:22 +000021class GrCustomStage;
tomhudson@google.comd0c1a062012-07-12 17:23:52 +000022class GrTexture;
reed@google.com15356a62011-11-03 19:29:08 +000023
24/**
25 * Experimental.
26 *
27 * Base class for image filters. If one is installed in the paint, then
28 * all drawing occurs as usual, but it is as if the drawing happened into an
29 * offscreen (before the xfermode is applied). This offscreen bitmap will
30 * then be handed to the imagefilter, who in turn creates a new bitmap which
31 * is what will finally be drawn to the device (using the original xfermode).
32 *
reed@google.com32d25b62011-12-20 16:19:00 +000033 * THIS SIGNATURE IS TEMPORARY
34 *
35 * There are several weaknesses in this function signature:
36 * 1. Does not expose the destination/target device, so filters that can draw
37 * directly to it are unable to take advantage of that optimization.
38 * 2. Does not expose a way to create a "compabitible" image (i.e. gpu -> gpu)
39 * 3. As with #1, the filter is unable to "read" the dest (which would be slow)
40 *
41 * Therefore, we should not create any real dependencies on this API yet -- it
42 * is being checked in as a check-point so we can explore these and other
43 * considerations.
reed@google.com15356a62011-11-03 19:29:08 +000044 */
senorblanco@chromium.org54e01b22011-11-16 18:20:47 +000045class SK_API SkImageFilter : public SkFlattenable {
reed@google.com894aa9a2011-09-23 14:49:49 +000046public:
robertphillips@google.com0456e0b2012-06-27 14:03:26 +000047 SK_DECLARE_INST_COUNT(SkImageFilter)
48
reed@google.com76dd2772012-01-05 21:15:07 +000049 class Proxy {
50 public:
reed@google.com8926b162012-03-23 15:36:36 +000051 virtual ~Proxy() {};
52
reed@google.com76dd2772012-01-05 21:15:07 +000053 virtual SkDevice* createDevice(int width, int height) = 0;
reed@google.com8926b162012-03-23 15:36:36 +000054 // returns true if the proxy can handle this filter natively
55 virtual bool canHandleImageFilter(SkImageFilter*) = 0;
reed@google.com76dd2772012-01-05 21:15:07 +000056 // returns true if the proxy handled the filter itself. if this returns
57 // false then the filter's code will be called.
58 virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
59 const SkMatrix& ctm,
60 SkBitmap* result, SkIPoint* offset) = 0;
61 };
reed@google.com894aa9a2011-09-23 14:49:49 +000062
63 /**
64 * Request a new (result) image to be created from the src image.
65 * If the src has no pixels (isNull()) then the request just wants to
66 * receive the config and width/height of the result.
67 *
68 * The matrix is the current matrix on the canvas.
69 *
70 * Offset is the amount to translate the resulting image relative to the
71 * src when it is drawn.
72 *
73 * If the result image cannot be created, return false, in which case both
74 * the result and offset parameters will be ignored by the caller.
75 */
reed@google.com76dd2772012-01-05 21:15:07 +000076 bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
reed@google.com15356a62011-11-03 19:29:08 +000077 SkBitmap* result, SkIPoint* offset);
78
79 /**
reed@google.com32d25b62011-12-20 16:19:00 +000080 * Given the src bounds of an image, this returns the bounds of the result
81 * image after the filter has been applied.
82 */
83 bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst);
84
85 /**
senorblanco@chromium.org894790d2012-07-11 16:01:22 +000086 * Returns true if the filter can be expressed a single-pass
87 * GrCustomStage, used to process this filter on the GPU, or false if
88 * not.
89 *
90 * If stage is non-NULL, a new GrCustomStage instance is stored
91 * in it. The caller assumes ownership of the stage, and it is up to the
92 * caller to unref it.
93 */
tomhudson@google.comd0c1a062012-07-12 17:23:52 +000094 virtual bool asNewCustomStage(GrCustomStage** stage, GrTexture*) const;
senorblanco@chromium.org894790d2012-07-11 16:01:22 +000095
96 /**
senorblanco@chromium.org302cffb2012-08-01 20:16:34 +000097 * Returns true if the filter can be processed on the GPU. This is most
98 * often used for multi-pass effects, where intermediate results must be
99 * rendered to textures. For single-pass effects, use asNewCustomStage().
100 * The default implementation returns false.
reed@google.com15356a62011-11-03 19:29:08 +0000101 */
senorblanco@chromium.org302cffb2012-08-01 20:16:34 +0000102 virtual bool canFilterImageGPU() const;
reed@google.com894aa9a2011-09-23 14:49:49 +0000103
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000104 /**
senorblanco@chromium.org302cffb2012-08-01 20:16:34 +0000105 * Process this image filter on the GPU. texture is the source texture
106 * for processing, and rect is the effect region to process. The
107 * function must allocate a new texture of at least rect width/height
108 * size, and return it to the caller. The default implementation returns
109 * NULL.
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000110 */
senorblanco@chromium.org302cffb2012-08-01 20:16:34 +0000111 virtual GrTexture* onFilterImageGPU(GrTexture* texture, const SkRect& rect);
senorblanco@chromium.org05054f12012-03-02 21:05:45 +0000112
reed@google.com894aa9a2011-09-23 14:49:49 +0000113protected:
senorblanco@chromium.org54e01b22011-11-16 18:20:47 +0000114 SkImageFilter() {}
115 explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
reed@google.com32d25b62011-12-20 16:19:00 +0000116
117 // Default impl returns false
reed@google.com76dd2772012-01-05 21:15:07 +0000118 virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
reed@google.com15356a62011-11-03 19:29:08 +0000119 SkBitmap* result, SkIPoint* offset);
reed@google.com32d25b62011-12-20 16:19:00 +0000120 // Default impl copies src into dst and returns true
121 virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*);
reed@google.com894aa9a2011-09-23 14:49:49 +0000122
123private:
senorblanco@chromium.org54e01b22011-11-16 18:20:47 +0000124 typedef SkFlattenable INHERITED;
reed@google.com894aa9a2011-09-23 14:49:49 +0000125};
126
127#endif