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