blob: 85385ed2c5e668a0178650d8b16bcbb844b01885 [file] [log] [blame]
/*
* Copyright (C) 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LayerCompositingThread_h
#define LayerCompositingThread_h
#if USE(ACCELERATED_COMPOSITING)
#include "FilterOperations.h"
#include "FloatQuad.h"
#include "LayerAnimation.h"
#include "LayerData.h"
#include "LayerFilterRenderer.h"
#include "LayerRendererSurface.h"
#include "LayerTiler.h"
#include <BlackBerryPlatformGuardedPointer.h>
#include <GuardedPointerDeleter.h>
namespace BlackBerry {
namespace Platform {
namespace Graphics {
class Buffer;
}
}
}
namespace WebCore {
class LayerCompositingThreadClient;
class LayerRenderer;
class LayerOverride {
public:
static PassOwnPtr<LayerOverride> create() { return adoptPtr(new LayerOverride()); }
bool isPositionSet() const { return m_positionSet; }
FloatPoint position() const { return m_position; }
void setPosition(const FloatPoint& position) { m_position = position; m_positionSet = true; }
bool isAnchorPointSet() const { return m_anchorPointSet; }
FloatPoint anchorPoint() const { return m_anchorPoint; }
void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; m_anchorPointSet = true; }
bool isBoundsSet() const { return m_boundsSet; }
IntSize bounds() const { return m_bounds; }
void setBounds(const IntSize& bounds) { m_bounds = bounds; m_boundsSet = true; }
bool isTransformSet() const { return m_transformSet; }
const TransformationMatrix& transform() const { return m_transform; }
void setTransform(const TransformationMatrix& transform) { m_transform = transform; m_transformSet = true; }
bool isOpacitySet() const { return m_opacitySet; }
float opacity() const { return m_opacity; }
void setOpacity(float opacity) { m_opacity = opacity; m_opacitySet = true; }
const Vector<RefPtr<LayerAnimation> >& animations() const { return m_animations; }
void addAnimation(PassRefPtr<LayerAnimation> animation) { m_animations.append(animation); }
void removeAnimation(const String& name);
private:
LayerOverride()
: m_opacity(1.0)
, m_positionSet(false)
, m_anchorPointSet(false)
, m_boundsSet(false)
, m_transformSet(false)
, m_opacitySet(false)
{
}
FloatPoint m_position;
FloatPoint m_anchorPoint;
IntSize m_bounds;
TransformationMatrix m_transform;
float m_opacity;
Vector<RefPtr<LayerAnimation> > m_animations;
unsigned m_positionSet : 1;
unsigned m_anchorPointSet : 1;
unsigned m_boundsSet : 1;
unsigned m_transformSet : 1;
unsigned m_opacitySet : 1;
};
class LayerFilterRendererAction;
class LayerCompositingThread : public ThreadSafeRefCounted<LayerCompositingThread>, public LayerData, public BlackBerry::Platform::GuardedPointerBase {
public:
static PassRefPtr<LayerCompositingThread> create(LayerType, LayerCompositingThreadClient*);
void setClient(LayerCompositingThreadClient* client) { m_client = client; }
// Thread safe
void setPluginView(PluginView*);
#if ENABLE(VIDEO)
void setMediaPlayer(MediaPlayer*);
#endif
// Not thread safe
// These will be overwritten on the next commit if this layer has a LayerWebKitThread counterpart.
// Useful for stand-alone layers that are created and managed on the compositing thread.
// These functions can also be used to update animated properties in LayerAnimation.
void setPosition(const FloatPoint& position) { m_position = position; }
void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; }
void setBounds(const IntSize& bounds) { m_bounds = bounds; }
void setSizeIsScaleInvariant(bool invariant) { m_sizeIsScaleInvariant = invariant; }
void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
void setOpacity(float opacity) { m_opacity = opacity; }
void addSublayer(LayerCompositingThread*);
void removeFromSuperlayer();
void setNeedsTexture(bool needsTexture) { m_needsTexture = needsTexture; }
// Returns true if we have an animation
bool updateAnimations(double currentTime);
void updateTextureContentsIfNeeded();
void bindContentsTexture();
const LayerCompositingThread* rootLayer() const;
void setSublayers(const Vector<RefPtr<LayerCompositingThread> >&);
const Vector<RefPtr<LayerCompositingThread> >& getSublayers() const { return m_sublayers; }
void setSuperlayer(LayerCompositingThread* superlayer) { m_superlayer = superlayer; }
LayerCompositingThread* superlayer() const { return m_superlayer; }
// The layer renderer must be set if the layer has been rendered
void setLayerRenderer(LayerRenderer*);
void setDrawTransform(double scale, const TransformationMatrix&);
const TransformationMatrix& drawTransform() const { return m_drawTransform; }
void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
float drawOpacity() const { return m_drawOpacity; }
void createLayerRendererSurface();
LayerRendererSurface* layerRendererSurface() const { return m_layerRendererSurface.get(); }
void clearLayerRendererSurface() { m_layerRendererSurface.clear(); }
void setMaskLayer(LayerCompositingThread* maskLayer) { m_maskLayer = maskLayer; }
LayerCompositingThread* maskLayer() const { return m_maskLayer.get(); }
void setReplicaLayer(LayerCompositingThread* layer) { m_replicaLayer = layer; }
LayerCompositingThread* replicaLayer() const { return m_replicaLayer.get(); }
FloatRect getDrawRect() const { return m_drawRect; }
const FloatQuad& getTransformedBounds() const { return m_transformedBounds; }
FloatQuad getTransformedHolePunchRect() const;
void deleteTextures();
void drawTextures(double scale, int positionLocation, int texCoordLocation, const FloatRect& visibleRect);
bool hasMissingTextures() const;
void drawMissingTextures(double scale, int positionLocation, int texCoordLocation, const FloatRect& visibleRect);
void drawSurface(const TransformationMatrix&, LayerCompositingThread* mask, int positionLocation, int texCoordLocation);
void releaseTextureResources();
// Layer visibility is determined by the LayerRenderer when drawing.
// So we don't have an accurate value for visibility until it's too late,
// but the attribute still is useful.
bool isVisible() const { return m_visible; }
void setVisible(bool);
// This will cause a commit of the whole layer tree on the WebKit thread,
// sometime after rendering is finished. Used when rendering results in a
// need for commit, for example when a dirty layer becomes visible.
void setNeedsCommit();
// Normally you would schedule a commit from the webkit thread, but
// this allows you to do it from the compositing thread.
void scheduleCommit();
bool hasRunningAnimations() const { return !m_runningAnimations.isEmpty(); }
bool hasVisibleHolePunchRect() const;
void addAnimation(LayerAnimation* animation) { m_runningAnimations.append(animation); }
void removeAnimation(const String& name);
void setRunningAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_runningAnimations = animations; }
void setSuspendedAnimations(const Vector<RefPtr<LayerAnimation> >& animations) { m_suspendedAnimations = animations; }
LayerOverride* override();
void clearOverride();
#if ENABLE(CSS_FILTERS)
bool filterOperationsChanged() const { return m_filterOperationsChanged; }
void setFilterOperationsChanged(bool changed) { m_filterOperationsChanged = changed; }
Vector<RefPtr<LayerFilterRendererAction> > filterActions() const { return m_filterActions; }
void setFilterActions(const Vector<RefPtr<LayerFilterRendererAction> >& actions) { m_filterActions = actions; }
#endif
protected:
virtual ~LayerCompositingThread();
private:
LayerCompositingThread(LayerType, LayerCompositingThreadClient*);
void updateTileContents(const IntRect& tile);
// Returns the index of the sublayer or -1 if not found.
int indexOfSublayer(const LayerCompositingThread*);
// This should only be called from removeFromSuperlayer.
void removeSublayer(LayerCompositingThread*);
LayerRenderer* m_layerRenderer;
typedef Vector<RefPtr<LayerCompositingThread> > LayerList;
LayerList m_sublayers;
LayerCompositingThread* m_superlayer;
// Vertex data for the bounds of this layer
FloatQuad m_transformedBounds;
// The bounding rectangle of the transformed layer
FloatRect m_drawRect;
OwnPtr<LayerRendererSurface> m_layerRendererSurface;
RefPtr<LayerCompositingThread> m_maskLayer;
RefPtr<LayerCompositingThread> m_replicaLayer;
BlackBerry::Platform::Graphics::Buffer* m_pluginBuffer;
// The global property values, after concatenation with parent values
TransformationMatrix m_drawTransform;
float m_drawOpacity;
bool m_visible;
bool m_commitScheduled;
Vector<RefPtr<LayerAnimation> > m_runningAnimations;
Vector<RefPtr<LayerAnimation> > m_suspendedAnimations;
OwnPtr<LayerOverride> m_override;
LayerCompositingThreadClient* m_client;
#if ENABLE(CSS_FILTERS)
bool m_filterOperationsChanged;
Vector<RefPtr<LayerFilterRendererAction> > m_filterActions;
#endif
};
} // namespace WebCore
namespace WTF {
// LayerCompositingThread objects must be destroyed on the compositing thread.
// But it's possible for the last reference to be held by the WebKit thread.
// So we create a custom specialization of ThreadSafeRefCounted which calls a
// function that ensures the destructor is called on the correct thread, rather
// than calling delete directly.
template<>
inline void ThreadSafeRefCounted<WebCore::LayerCompositingThread>::deref()
{
if (derefBase()) {
// Delete on the compositing thread.
BlackBerry::Platform::GuardedPointerDeleter::deleteOnThread(
BlackBerry::Platform::userInterfaceThreadMessageClient(),
static_cast<WebCore::LayerCompositingThread*>(this));
}
}
} // namespace WTF
#endif // USE(ACCELERATED_COMPOSITING)
#endif