1/*
2 Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library 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 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB.  If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20#ifndef TextureMapperGL_h
21#define TextureMapperGL_h
22
23#if USE(TEXTURE_MAPPER)
24
25#include "FilterOperation.h"
26#include "FloatQuad.h"
27#include "GraphicsContext3D.h"
28#include "IntSize.h"
29#include "TextureMapper.h"
30#include "TransformationMatrix.h"
31
32namespace WebCore {
33
34class TextureMapperGLData;
35class TextureMapperShaderProgram;
36class FilterOperation;
37
38// An OpenGL-ES2 implementation of TextureMapper.
39class TextureMapperGL : public TextureMapper {
40public:
41    TextureMapperGL();
42    virtual ~TextureMapperGL();
43
44    enum Flag {
45        ShouldBlend = 0x01,
46        ShouldFlipTexture = 0x02,
47        ShouldUseARBTextureRect = 0x04,
48        ShouldAntialias = 0x08
49    };
50
51    typedef int Flags;
52
53    // TextureMapper implementation
54    virtual void drawBorder(const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) override;
55    virtual void drawNumber(int number, const Color&, const FloatPoint&, const TransformationMatrix&) override;
56    virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, unsigned exposedEdges) override;
57    virtual void drawTexture(Platform3DObject texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
58    virtual void drawSolidColor(const FloatRect&, const TransformationMatrix&, const Color&) override;
59
60    virtual void bindSurface(BitmapTexture* surface) override;
61    virtual void beginClip(const TransformationMatrix&, const FloatRect&) override;
62    virtual void beginPainting(PaintFlags = 0) override;
63    virtual void endPainting() override;
64    virtual void endClip() override;
65    virtual IntRect clipBounds() override;
66    virtual IntSize maxTextureSize() const override { return IntSize(2000, 2000); }
67    virtual PassRefPtr<BitmapTexture> createTexture() override;
68    inline GraphicsContext3D* graphicsContext3D() const { return m_context3D.get(); }
69
70#if ENABLE(CSS_FILTERS)
71    void drawFiltered(const BitmapTexture& sourceTexture, const BitmapTexture* contentTexture, const FilterOperation&, int pass);
72#endif
73
74    void setEnableEdgeDistanceAntialiasing(bool enabled) { m_enableEdgeDistanceAntialiasing = enabled; }
75
76private:
77    struct ClipState {
78        IntRect scissorBox;
79        int stencilIndex;
80        ClipState(const IntRect& scissors = IntRect(), int stencil = 1)
81            : scissorBox(scissors)
82            , stencilIndex(stencil)
83        { }
84    };
85
86    class ClipStack {
87    public:
88        ClipStack()
89            : clipStateDirty(false)
90        { }
91
92        // Y-axis should be inverted only when painting into the window.
93        enum YAxisMode {
94            DefaultYAxis,
95            InvertedYAxis
96        };
97
98        void push();
99        void pop();
100        void apply(GraphicsContext3D*);
101        void applyIfNeeded(GraphicsContext3D*);
102        inline ClipState& current() { return clipState; }
103        void reset(const IntRect&, YAxisMode);
104        void intersect(const IntRect&);
105        void setStencilIndex(int);
106        inline int getStencilIndex() const
107        {
108            return clipState.stencilIndex;
109        }
110        inline bool isCurrentScissorBoxEmpty() const
111        {
112            return clipState.scissorBox.isEmpty();
113        }
114
115    private:
116        ClipState clipState;
117        Vector<ClipState> clipStack;
118        bool clipStateDirty;
119        IntSize size;
120        YAxisMode yAxisMode;
121    };
122
123    void drawTexturedQuadWithProgram(TextureMapperShaderProgram*, uint32_t texture, Flags, const IntSize&, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);
124    void draw(const FloatRect&, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram*, GC3Denum drawingMode, Flags);
125
126    void drawUnitRect(TextureMapperShaderProgram*, GC3Denum drawingMode);
127    void drawEdgeTriangles(TextureMapperShaderProgram*);
128
129    bool beginScissorClip(const TransformationMatrix&, const FloatRect&);
130    void bindDefaultSurface();
131    ClipStack& clipStack();
132    inline TextureMapperGLData& data() { return *m_data; }
133    RefPtr<GraphicsContext3D> m_context3D;
134    TextureMapperGLData* m_data;
135    ClipStack m_clipStack;
136    bool m_enableEdgeDistanceAntialiasing;
137
138    friend class BitmapTextureGL;
139};
140
141class BitmapTextureGL : public BitmapTexture {
142public:
143    virtual IntSize size() const;
144    virtual bool isValid() const;
145    virtual bool canReuseWith(const IntSize& contentsSize, Flags = 0);
146    virtual void didReset();
147    void bind(TextureMapperGL*);
148    void initializeStencil();
149    void initializeDepthBuffer();
150    ~BitmapTextureGL();
151    virtual uint32_t id() const { return m_id; }
152    uint32_t textureTarget() const { return GraphicsContext3D::TEXTURE_2D; }
153    IntSize textureSize() const { return m_textureSize; }
154    void updateContents(Image*, const IntRect&, const IntPoint&, UpdateContentsFlag);
155    virtual void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag);
156    virtual bool isBackedByOpenGL() const { return true; }
157
158#if ENABLE(CSS_FILTERS)
159    virtual PassRefPtr<BitmapTexture> applyFilters(TextureMapper*, const FilterOperations&) override;
160    struct FilterInfo {
161        RefPtr<FilterOperation> filter;
162        unsigned pass;
163        RefPtr<BitmapTexture> contentTexture;
164
165        FilterInfo(PassRefPtr<FilterOperation> f = 0, unsigned p = 0, PassRefPtr<BitmapTexture> t = 0)
166            : filter(f)
167            , pass(p)
168            , contentTexture(t)
169            { }
170    };
171    const FilterInfo* filterInfo() const { return &m_filterInfo; }
172#endif
173
174private:
175    void updateContentsNoSwizzle(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine, unsigned bytesPerPixel = 4, Platform3DObject glFormat = GraphicsContext3D::RGBA);
176
177    Platform3DObject m_id;
178    IntSize m_textureSize;
179    IntRect m_dirtyRect;
180    Platform3DObject m_fbo;
181    Platform3DObject m_rbo;
182    Platform3DObject m_depthBufferObject;
183    bool m_shouldClear;
184    TextureMapperGL::ClipStack m_clipStack;
185    RefPtr<GraphicsContext3D> m_context3D;
186
187    explicit BitmapTextureGL(TextureMapperGL*);
188    BitmapTextureGL();
189
190    void clearIfNeeded();
191    void createFboIfNeeded();
192
193#if ENABLE(CSS_FILTERS)
194    FilterInfo m_filterInfo;
195#endif
196
197    friend class TextureMapperGL;
198};
199
200BitmapTextureGL* toBitmapTextureGL(BitmapTexture*);
201
202}
203#endif
204
205#endif
206