1/*
2 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#ifndef LayerFilterRenderer_h
20#define LayerFilterRenderer_h
21
22#if USE(ACCELERATED_COMPOSITING) && ENABLE(CSS_FILTERS)
23
24#include "IntRect.h"
25#include "LayerData.h"
26#include "LayerTexture.h"
27#include "TransformationMatrix.h"
28
29#include <BlackBerryPlatformGLES2Context.h>
30#include <BlackBerryPlatformIntRectRegion.h>
31#include <wtf/HashSet.h>
32#include <wtf/Noncopyable.h>
33#include <wtf/OwnPtr.h>
34#include <wtf/PassOwnPtr.h>
35#include <wtf/Vector.h>
36
37namespace WebCore {
38
39class LayerCompositingThread;
40class LayerFilterRenderer;
41class LayerFilterRendererAction;
42class LayerRendererSurface;
43
44class Parameter : public RefCounted<Parameter> {
45    WTF_MAKE_NONCOPYABLE(Parameter);
46public:
47    virtual void apply() = 0;
48    virtual void restoreState() { }
49    virtual ~Parameter() { }
50protected:
51    explicit Parameter() { }
52};
53
54class Uniform : public Parameter {
55    WTF_MAKE_NONCOPYABLE(Uniform);
56public:
57    virtual void apply() = 0;
58    virtual ~Uniform() { }
59
60protected:
61    Uniform(int location);
62    const int& location() const { return m_location; }
63
64private:
65    int m_location;
66};
67
68class Uniform1f : public Uniform {
69public:
70    static PassRefPtr<Uniform> create(int location, float val);
71
72    template<typename Functor>
73    static PassRefPtr<Uniform> createWithFunctor(int location, Functor);
74
75protected:
76    Uniform1f(int location, float val);
77
78    virtual void apply();
79
80    float m_val;
81};
82
83template<typename Functor>
84class Uniform1fWithFunctor : public Uniform1f {
85public:
86    static PassRefPtr<Uniform> create(int location, Functor functor)
87    {
88        return adoptRef(new Uniform1fWithFunctor(location, functor));
89    }
90
91protected:
92    Uniform1fWithFunctor(int location, Functor functor)
93        : Uniform1f(location, 0)
94        , m_functor(functor)
95    {
96    }
97
98    virtual void apply()
99    {
100        m_val = m_functor();
101        Uniform1f::apply();
102    }
103
104    Functor m_functor;
105};
106
107template<typename Functor>
108inline PassRefPtr<Uniform> Uniform1f::createWithFunctor(int location, Functor functor)
109{
110    return Uniform1fWithFunctor<Functor>::create(location, functor);
111}
112
113class Uniform1i : public Uniform {
114public:
115    static PassRefPtr<Uniform> create(int location, int val);
116
117protected:
118    Uniform1i(int location, int val);
119
120private:
121    virtual void apply();
122    int m_val;
123};
124
125class Uniform2f : public Uniform {
126public:
127    static PassRefPtr<Uniform> create(int location, float val0, float val1);
128
129protected:
130    Uniform2f(int location, float val0, float val1);
131
132private:
133    virtual void apply();
134    float m_val[2];
135};
136
137class Uniform3f : public Uniform {
138public:
139    static PassRefPtr<Uniform> create(int location, float val0, float val1, float val2);
140
141protected:
142    Uniform3f(int location, float val0, float val1, float val2);
143
144private:
145    virtual void apply();
146    float m_val[3];
147};
148
149class Uniform4f : public Uniform {
150public:
151    static PassRefPtr<Uniform> create(int location, float val0, float val1, float val2, float val3);
152
153protected:
154    Uniform4f(int location, float val0, float val1, float val2, float val3);
155
156private:
157    virtual void apply();
158    float m_val[4];
159};
160
161class Matrix4fv : public Uniform {
162public:
163    static PassRefPtr<Parameter> create(GLint location, GLsizei, GLboolean transpose, GLfloat* array);
164
165protected:
166    Matrix4fv(GLint location, GLsizei length, GLboolean transpose, GLfloat* array);
167    ~Matrix4fv();
168
169private:
170    virtual void apply();
171    GLint m_location;
172    GLsizei m_size;
173    GLboolean m_transpose;
174    GLfloat* m_array;
175};
176
177class Buffer : public Parameter {
178public:
179    static PassRefPtr<Parameter> create(GLenum buffer, GLuint index);
180
181protected:
182    Buffer(GLenum buffer, GLuint index);
183
184private:
185    virtual void apply();
186    virtual void restoreState();
187    GLenum m_buffer;
188    GLuint m_object;
189};
190
191class VertexAttribf : public Parameter {
192public:
193    static PassRefPtr<Parameter> create(int location, int size, int bytesPerVertex, int offset);
194
195protected:
196    VertexAttribf(int location, int size, int bytesPerVertex, int offset);
197
198private:
199    virtual void apply();
200    virtual void restoreState();
201    int m_location;
202    int m_size;
203    int m_bytesPerVertex;
204    int m_offset;
205};
206
207class LayerFilterRendererAction : public RefCounted<LayerFilterRendererAction> {
208public:
209    static PassRefPtr<LayerFilterRendererAction> create(int programId);
210        // A vector of actions must have an even count, so if you have an odd count, add a passthrough event at the end.
211        // See the ping-pong note in LayerFilterRenderer::applyActions.
212
213    bool shouldPushSnapshot() const { return m_pushSnapshot; }
214    void setPushSnapshot() { m_pushSnapshot = true; }
215
216    bool shouldPopSnapshot() const { return m_popSnapshot; }
217    void setPopSnapshot() { m_popSnapshot = true; }
218
219    void appendParameter(const RefPtr<Parameter>& uniform) { m_parameters.append(uniform); }
220    void useActionOn(LayerFilterRenderer*);
221    void restoreState();
222
223    enum DrawingMode {
224        DrawTriangleFanArrays = 0,
225        DrawTriangleElementsUShort0,
226        NumberOfDrawingModes
227    };
228
229    DrawingMode drawingMode() const { return m_drawingMode; }
230    void setDrawingMode(const DrawingMode& mode) { m_drawingMode = mode; }
231
232    int drawingModeParameter() const { return m_drawingModeParameter; }
233    void setDrawingModeParameter(int p) { m_drawingModeParameter = p; }
234
235
236protected:
237    int m_programId;
238    bool m_pushSnapshot;
239    bool m_popSnapshot;
240
241    Vector<RefPtr<Parameter> > m_parameters;
242
243    DrawingMode m_drawingMode;
244    int m_drawingModeParameter;
245
246private:
247    LayerFilterRendererAction(int programId);
248};
249
250class LayerFilterRenderer {
251    WTF_MAKE_NONCOPYABLE(LayerFilterRenderer);
252
253public:
254    static PassOwnPtr<LayerFilterRenderer> create(const int& positionLocation, const int& texCoordLocation);
255    void applyActions(unsigned& fbo, LayerCompositingThread*, Vector<RefPtr<LayerFilterRendererAction> >);
256    Vector<RefPtr<LayerFilterRendererAction> > actionsForOperations(LayerRendererSurface*, const Vector<RefPtr<FilterOperation> >&);
257
258    // If initialization fails, or disable() is called, this is false.
259    bool isEnabled() const { return m_enabled; }
260    void disable() { m_enabled = false; }
261
262private:
263    LayerFilterRenderer(const int& positionLocation, const int& texCoordLocation);
264    void bindCommonAttribLocation(int location, const char* attribName);
265    bool initializeSharedGLObjects();
266
267    // See note about ping-ponging in applyActions()
268    void ping(LayerRendererSurface*);
269    void pong(LayerRendererSurface*);
270
271    // This is for shadows, where we need to create a shadow, and then repaint the original image
272    // on top of the shadow.
273    void pushSnapshot(LayerRendererSurface*, int sourceId);
274    void popSnapshot();
275
276    bool m_enabled;
277
278    // ESSL attributes shared with LayerRenderer - see constructor:
279    const int m_positionLocation;
280    const int m_texCoordLocation;
281
282    // ESSL program object IDs:
283    unsigned m_cssFilterProgramObject[LayerData::NumberOfCSSFilterShaders];
284
285    // ESSL uniform locations:
286    int m_amountLocation[LayerData::NumberOfCSSFilterShaders];
287    int m_blurAmountLocation[2]; // 0 = Y, 1 = X
288    int m_shadowColorLocation;
289    int m_offsetLocation;
290
291    // Textures for playing ping-pong - see note in applyActions()
292    RefPtr<LayerTexture> m_texture;
293    RefPtr<LayerTexture> m_snapshotTexture;
294
295    friend class LayerFilterRendererAction;
296};
297
298}
299
300#endif // USE(ACCELERATED_COMPOSITING) && ENABLE(CSS_FILTERS)
301
302#endif // LayerFilterRenderer_h
303