1/*
2 * Copyright (C) 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
33#ifndef LayerCompositingThread_h
34#define LayerCompositingThread_h
35
36#if USE(ACCELERATED_COMPOSITING)
37
38#include "FilterOperations.h"
39#include "FloatQuad.h"
40#include "LayerAnimation.h"
41#include "LayerData.h"
42#include "LayerFilterRenderer.h"
43#include "LayerRendererSurface.h"
44#include "LayerTiler.h"
45
46#include <BlackBerryPlatformGuardedPointer.h>
47#include <GuardedPointerDeleter.h>
48
49namespace BlackBerry {
50namespace Platform {
51namespace Graphics {
52class Buffer;
53class GLES2Program;
54}
55}
56}
57
58namespace WebCore {
59
60class LayerCompositingThreadClient;
61class LayerRenderer;
62
63class LayerOverride {
64public:
65    static PassOwnPtr<LayerOverride> create() { return adoptPtr(new LayerOverride()); }
66
67    bool isPositionSet() const { return m_positionSet; }
68    FloatPoint position() const { return m_position; }
69    void setPosition(const FloatPoint& position) { m_position = position; m_positionSet = true; }
70
71    bool isAnchorPointSet() const { return m_anchorPointSet; }
72    FloatPoint anchorPoint() const { return m_anchorPoint; }
73    void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; m_anchorPointSet = true; }
74
75    bool isBoundsSet() const { return m_boundsSet; }
76    IntSize bounds() const { return m_bounds; }
77    void setBounds(const IntSize& bounds) { m_bounds = bounds; m_boundsSet = true; }
78
79    bool isTransformSet() const { return m_transformSet; }
80    const TransformationMatrix& transform() const { return m_transform; }
81    void setTransform(const TransformationMatrix& transform) { m_transform = transform; m_transformSet = true; }
82
83    bool isOpacitySet() const { return m_opacitySet; }
84    float opacity() const { return m_opacity; }
85    void setOpacity(float opacity) { m_opacity = opacity; m_opacitySet = true; }
86
87    const Vector<RefPtr<LayerAnimation> >& animations() const { return m_animations; }
88    void addAnimation(PassRefPtr<LayerAnimation> animation) { m_animations.append(animation); }
89    void removeAnimation(const String& name);
90
91private:
92    LayerOverride()
93        : m_opacity(1.0)
94        , m_positionSet(false)
95        , m_anchorPointSet(false)
96        , m_boundsSet(false)
97        , m_transformSet(false)
98        , m_opacitySet(false)
99    {
100    }
101
102    FloatPoint m_position;
103    FloatPoint m_anchorPoint;
104    IntSize m_bounds;
105    TransformationMatrix m_transform;
106    float m_opacity;
107
108    Vector<RefPtr<LayerAnimation> > m_animations;
109
110    unsigned m_positionSet : 1;
111    unsigned m_anchorPointSet : 1;
112    unsigned m_boundsSet : 1;
113    unsigned m_transformSet : 1;
114    unsigned m_opacitySet : 1;
115};
116
117class LayerFilterRendererAction;
118
119class LayerCompositingThread : public ThreadSafeRefCounted<LayerCompositingThread>, public LayerData, public BlackBerry::Platform::GuardedPointerBase {
120public:
121    static PassRefPtr<LayerCompositingThread> create(LayerType, LayerCompositingThreadClient*);
122
123    LayerCompositingThreadClient* client() const { return m_client; }
124    void setClient(LayerCompositingThreadClient* client) { m_client = client; }
125
126    // Thread safe
127    void setPluginView(PluginView*);
128#if ENABLE(VIDEO)
129    void setMediaPlayer(MediaPlayer*);
130#endif
131
132    // Not thread safe
133
134    // These will be overwritten on the next commit if this layer has a LayerWebKitThread counterpart.
135    // Useful for stand-alone layers that are created and managed on the compositing thread.
136    // These functions can also be used to update animated properties in LayerAnimation.
137    void setPosition(const FloatPoint& position) { m_position = position; }
138    void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; }
139    void setBounds(const IntSize& bounds) { m_bounds = bounds; }
140    void setSizeIsScaleInvariant(bool invariant) { m_sizeIsScaleInvariant = invariant; }
141    void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
142    void setOpacity(float opacity) { m_opacity = opacity; }
143    void addSublayer(LayerCompositingThread*);
144    void removeFromSuperlayer();
145    void setNeedsTexture(bool needsTexture) { m_needsTexture = needsTexture; }
146
147    void commitPendingTextureUploads();
148
149    // Returns true if we have an animation
150    bool updateAnimations(double currentTime);
151    void updateTextureContentsIfNeeded();
152    LayerTexture* contentsTexture();
153
154    const LayerCompositingThread* rootLayer() const;
155    void setSublayers(const Vector<RefPtr<LayerCompositingThread> >&);
156    const Vector<RefPtr<LayerCompositingThread> >& sublayers() const { return m_sublayers; }
157    void setSuperlayer(LayerCompositingThread* superlayer) { m_superlayer = superlayer; }
158    LayerCompositingThread* superlayer() const { return m_superlayer; }
159
160    // The layer renderer must be set if the layer has been rendered
161    LayerRenderer* layerRenderer() const { return m_layerRenderer; }
162    void setLayerRenderer(LayerRenderer*);
163
164    // The draw transform expects the origin to be located at the center of the layer.
165    FloatPoint origin() const { return FloatPoint(m_bounds.width() / 2.0f, m_bounds.height() / 2.0f); }
166
167    void setDrawTransform(double scale, const TransformationMatrix& modelViewMatrix, const TransformationMatrix& projectionMatrix);
168    const TransformationMatrix& drawTransform() const { return m_drawTransform; }
169
170    void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
171    float drawOpacity() const { return m_drawOpacity; }
172
173    void createLayerRendererSurface();
174    LayerRendererSurface* layerRendererSurface() const { return m_layerRendererSurface.get(); }
175    void clearLayerRendererSurface() { m_layerRendererSurface.clear(); }
176
177    void setMaskLayer(LayerCompositingThread* maskLayer) { m_maskLayer = maskLayer; }
178    LayerCompositingThread* maskLayer() const { return m_maskLayer.get(); }
179
180    void setReplicaLayer(LayerCompositingThread* layer) { m_replicaLayer = layer; }
181    LayerCompositingThread* replicaLayer() const { return m_replicaLayer.get(); }
182
183    // These use normalized device coordinates
184    FloatRect boundingBox() const { return m_boundingBox; }
185    // The bounds are processed according to http://www.w3.org/TR/css3-transforms paragraph 6.2, which can result in a polygon with more than 4 sides.
186    const Vector<FloatPoint, 4>& transformedBounds() const { return m_transformedBounds; }
187    const Vector<float, 4>& ws() const { return m_ws; }
188
189    enum TextureCoordinateOrientation {
190        RightSideUp = 0,
191        UpsideDown
192    };
193
194    const Vector<FloatPoint>& textureCoordinates(TextureCoordinateOrientation = RightSideUp) const;
195    FloatQuad transformedHolePunchRect() const;
196    float centerW() const { return m_centerW; }
197
198    void deleteTextures();
199
200    void drawTextures(const BlackBerry::Platform::Graphics::GLES2Program&, double scale, const FloatRect& visibleRect, const FloatRect& clipRect);
201    void drawSurface(const BlackBerry::Platform::Graphics::GLES2Program&, const TransformationMatrix&, LayerCompositingThread* mask);
202
203    void releaseTextureResources();
204
205    // Layer visibility is determined by the LayerRenderer when drawing.
206    // So we don't have an accurate value for visibility until it's too late,
207    // but the attribute still is useful.
208    bool isVisible() const { return m_visible; }
209    void setVisible(bool);
210
211    // This will cause a commit of the whole layer tree on the WebKit thread,
212    // sometime after rendering is finished. Used when rendering results in a
213    // need for commit, for example when a dirty layer becomes visible.
214    void setNeedsCommit();
215
216    // Normally you would schedule a commit from the webkit thread, but
217    // this allows you to do it from the compositing thread.
218    void scheduleCommit();
219
220    bool hasRunningAnimations() const { return !m_runningAnimations.isEmpty(); }
221
222    bool hasVisibleHolePunchRect() const;
223
224    void addAnimation(LayerAnimation* animation) { m_runningAnimations.append(animation); }
225    void removeAnimation(const String& name);
226
227    void setRunningAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_runningAnimations = animations; }
228    void setSuspendedAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_suspendedAnimations = animations; }
229
230    LayerOverride* override();
231    void clearOverride();
232
233#if ENABLE(CSS_FILTERS)
234    bool filterOperationsChanged() const { return m_filterOperationsChanged; }
235    void setFilterOperationsChanged(bool changed) { m_filterOperationsChanged = changed; }
236
237    Vector<RefPtr<LayerFilterRendererAction> > filterActions() const { return m_filterActions; }
238    void setFilterActions(const Vector<RefPtr<LayerFilterRendererAction> >& actions) { m_filterActions = actions; }
239#endif
240
241protected:
242    virtual ~LayerCompositingThread();
243
244private:
245    LayerCompositingThread(LayerType, LayerCompositingThreadClient*);
246
247    void updateTileContents(const IntRect& tile);
248
249    // Returns the index of the sublayer or -1 if not found.
250    int indexOfSublayer(const LayerCompositingThread*);
251
252    // This should only be called from removeFromSuperlayer.
253    void removeSublayer(LayerCompositingThread*);
254
255    LayerRenderer* m_layerRenderer;
256
257    typedef Vector<RefPtr<LayerCompositingThread> > LayerList;
258    LayerList m_sublayers;
259    LayerCompositingThread* m_superlayer;
260
261    // Vertex data for the bounds of this layer
262    Vector<FloatPoint, 4> m_transformedBounds;
263    Vector<float, 4> m_ws;
264    Vector<FloatPoint> m_textureCoordinates; // Only used when a 3D layer is clipped against z = 0
265    float m_centerW;
266    FloatRect m_boundingBox;
267
268    OwnPtr<LayerRendererSurface> m_layerRendererSurface;
269
270    RefPtr<LayerCompositingThread> m_maskLayer;
271    RefPtr<LayerCompositingThread> m_replicaLayer;
272
273    BlackBerry::Platform::Graphics::Buffer* m_pluginBuffer;
274
275    // The global property values, after concatenation with parent values
276    TransformationMatrix m_drawTransform;
277    float m_drawOpacity;
278
279    bool m_visible;
280    bool m_commitScheduled;
281
282    Vector<RefPtr<LayerAnimation> > m_runningAnimations;
283    Vector<RefPtr<LayerAnimation> > m_suspendedAnimations;
284
285    OwnPtr<LayerOverride> m_override;
286    LayerCompositingThreadClient* m_client;
287
288#if ENABLE(CSS_FILTERS)
289    bool m_filterOperationsChanged;
290    Vector<RefPtr<LayerFilterRendererAction> > m_filterActions;
291#endif
292};
293
294} // namespace WebCore
295
296namespace WTF {
297
298// LayerCompositingThread objects must be destroyed on the compositing thread.
299// But it's possible for the last reference to be held by the WebKit thread.
300// So we create a custom specialization of ThreadSafeRefCounted which calls a
301// function that ensures the destructor is called on the correct thread, rather
302// than calling delete directly.
303template<>
304inline void ThreadSafeRefCounted<WebCore::LayerCompositingThread>::deref()
305{
306    if (derefBase()) {
307        // Delete on the compositing thread.
308        BlackBerry::Platform::GuardedPointerDeleter::deleteOnThread(
309            BlackBerry::Platform::userInterfaceThreadMessageClient(),
310            static_cast<WebCore::LayerCompositingThread*>(this));
311    }
312}
313
314} // namespace WTF
315
316
317#endif // USE(ACCELERATED_COMPOSITING)
318
319#endif
320