Some FilterEffect cleanup and logging
[WebKit-https.git] / Source / WebCore / platform / graphics / filters / FilterEffect.h
1 /*
2  * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
3  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
4  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #pragma once
23
24 #include "ColorSpace.h"
25 #include "FloatRect.h"
26 #include "IntRect.h"
27 #include <runtime/Uint8ClampedArray.h>
28 #include <wtf/MathExtras.h>
29 #include <wtf/RefCounted.h>
30 #include <wtf/RefPtr.h>
31 #include <wtf/Vector.h>
32
33 namespace WTF {
34 class TextStream;
35 }
36
37 namespace WebCore {
38
39 class Filter;
40 class FilterEffect;
41 class ImageBuffer;
42
43 typedef Vector<RefPtr<FilterEffect>> FilterEffectVector;
44
45 enum FilterEffectType {
46     FilterEffectTypeUnknown,
47     FilterEffectTypeImage,
48     FilterEffectTypeTile,
49     FilterEffectTypeSourceInput
50 };
51
52 class FilterEffect : public RefCounted<FilterEffect> {
53 public:
54     virtual ~FilterEffect();
55
56     void clearResult();
57     void clearResultsRecursive();
58
59     ImageBuffer* imageBufferResult();
60     RefPtr<Uint8ClampedArray> unmultipliedResult(const IntRect&);
61     RefPtr<Uint8ClampedArray> premultipliedResult(const IntRect&);
62     void copyUnmultipliedResult(Uint8ClampedArray* destination, const IntRect&);
63     void copyPremultipliedResult(Uint8ClampedArray* destination, const IntRect&);
64
65 #if ENABLE(OPENCL)
66     OpenCLHandle openCLImage() { return m_openCLImageResult; }
67     void setOpenCLImage(OpenCLHandle openCLImage) { m_openCLImageResult = openCLImage; }
68     ImageBuffer* openCLImageToImageBuffer();
69 #endif
70
71     FilterEffectVector& inputEffects() { return m_inputEffects; }
72     FilterEffect* inputEffect(unsigned) const;
73     unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
74     unsigned totalNumberOfEffectInputs() const;
75     
76     inline bool hasResult() const
77     {
78         // This function needs platform specific checks, if the memory managment is not done by FilterEffect.
79         return m_imageBufferResult
80 #if ENABLE(OPENCL)
81             || m_openCLImageResult
82 #endif
83             || m_unmultipliedImageResult
84             || m_premultipliedImageResult;
85     }
86
87     FloatRect drawingRegionOfInputImage(const IntRect&) const;
88     IntRect requestedRegionOfInputImageData(const IntRect&) const;
89
90     // Solid black image with different alpha values.
91     bool isAlphaImage() const { return m_alphaImage; }
92     void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
93
94     IntRect absolutePaintRect() const { return m_absolutePaintRect; }
95     void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; }
96
97     FloatRect maxEffectRect() const { return m_maxEffectRect; }
98     void setMaxEffectRect(const FloatRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } 
99
100     void apply();
101 #if ENABLE(OPENCL)
102     void applyAll();
103 #else
104     inline void applyAll() { apply(); }
105 #endif
106
107     // Correct any invalid pixels, if necessary, in the result of a filter operation.
108     // This method is used to ensure valid pixel values on filter inputs and the final result.
109     // Only the arithmetic composite filter ever needs to perform correction.
110     virtual void correctFilterResultIfNeeded() { }
111
112     virtual void determineAbsolutePaintRect();
113
114     virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; }
115
116     virtual WTF::TextStream& externalRepresentation(WTF::TextStream&, int indention = 0) const;
117
118     // The following functions are SVG specific and will move to RenderSVGResourceFilterPrimitive.
119     // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
120     bool hasX() const { return m_hasX; }
121     void setHasX(bool value) { m_hasX = value; }
122
123     bool hasY() const { return m_hasY; }
124     void setHasY(bool value) { m_hasY = value; }
125
126     bool hasWidth() const { return m_hasWidth; }
127     void setHasWidth(bool value) { m_hasWidth = value; }
128
129     bool hasHeight() const { return m_hasHeight; }
130     void setHasHeight(bool value) { m_hasHeight = value; }
131
132     FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
133     void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
134
135     FloatRect effectBoundaries() const { return m_effectBoundaries; }
136     void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
137
138     Filter& filter() { return m_filter; }
139     const Filter& filter() const { return m_filter; }
140
141     bool clipsToBounds() const { return m_clipsToBounds; }
142     void setClipsToBounds(bool value) { m_clipsToBounds = value; }
143
144     ColorSpace operatingColorSpace() const { return m_operatingColorSpace; }
145     virtual void setOperatingColorSpace(ColorSpace colorSpace) { m_operatingColorSpace = colorSpace; }
146     ColorSpace resultColorSpace() const { return m_resultColorSpace; }
147     virtual void setResultColorSpace(ColorSpace colorSpace) { m_resultColorSpace = colorSpace; }
148
149     virtual void transformResultColorSpace(FilterEffect* in, const int) { in->transformResultColorSpace(m_operatingColorSpace); }
150     void transformResultColorSpace(ColorSpace);
151
152 protected:
153     FilterEffect(Filter&);
154     
155     virtual const char* filterName() const = 0;
156
157     ImageBuffer* createImageBufferResult();
158     Uint8ClampedArray* createUnmultipliedImageResult();
159     Uint8ClampedArray* createPremultipliedImageResult();
160 #if ENABLE(OPENCL)
161     OpenCLHandle createOpenCLImageResult(uint8_t* = 0);
162 #endif
163
164     // Return true if the filter will only operate correctly on valid RGBA values, with
165     // alpha in [0,255] and each color component in [0, alpha].
166     virtual bool requiresValidPreMultipliedPixels() { return true; }
167
168     // If a pre-multiplied image, check every pixel for validity and correct if necessary.
169     void forceValidPreMultipliedPixels();
170
171     void clipAbsolutePaintRect();
172     
173     static Vector<float> normalizedFloats(const Vector<float>& values)
174     {
175         Vector<float> normalizedValues(values.size());
176         for (size_t i = 0; i < values.size(); ++i)
177             normalizedValues[i] = normalizedFloat(values[i]);
178         return normalizedValues;
179     }
180
181 private:
182     virtual void platformApplySoftware() = 0;
183
184     void copyImageBytes(Uint8ClampedArray* source, Uint8ClampedArray* destination, const IntRect&) const;
185
186     Filter& m_filter;
187     FilterEffectVector m_inputEffects;
188
189     std::unique_ptr<ImageBuffer> m_imageBufferResult;
190     RefPtr<Uint8ClampedArray> m_unmultipliedImageResult;
191     RefPtr<Uint8ClampedArray> m_premultipliedImageResult;
192 #if ENABLE(OPENCL)
193     OpenCLHandle m_openCLImageResult;
194 #endif
195
196     IntRect m_absolutePaintRect;
197     
198     // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
199     // The absolute paint rect should never be bigger than m_maxEffectRect.
200     FloatRect m_maxEffectRect;
201     
202     // The subregion of a filter primitive according to the SVG Filter specification in local coordinates.
203     // This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive.
204     FloatRect m_filterPrimitiveSubregion;
205
206     // x, y, width and height of the actual SVGFE*Element. Is needed to determine the subregion of the
207     // filter primitive on a later step.
208     FloatRect m_effectBoundaries;
209
210     bool m_alphaImage { false };
211     bool m_hasX { false };
212     bool m_hasY { false };
213     bool m_hasWidth { false };
214     bool m_hasHeight { false };
215
216     // Should the effect clip to its primitive region, or expand to use the combined region of its inputs.
217     bool m_clipsToBounds { true };
218
219     ColorSpace m_operatingColorSpace { ColorSpaceLinearRGB };
220     ColorSpace m_resultColorSpace { ColorSpaceSRGB };
221 };
222
223 } // namespace WebCore
224