GraphicsLayerChromium.cpp [plain text]
#include "config.h"
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayerChromium.h"
#include "Canvas2DLayerChromium.h"
#include "ContentLayerChromium.h"
#include "FloatConversion.h"
#include "FloatRect.h"
#include "Image.h"
#include "ImageLayerChromium.h"
#include "LayerChromium.h"
#include "PlatformString.h"
#include "SystemTime.h"
#include <wtf/CurrentTime.h>
#include <wtf/StringExtras.h>
#include <wtf/text/CString.h>
using namespace std;
namespace {
static int s_nextGroupId = 1;
static int s_nextAnimationId = 1;
}
namespace WebCore {
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return adoptPtr(new GraphicsLayerChromium(client));
}
GraphicsLayerChromium::GraphicsLayerChromium(GraphicsLayerClient* client)
: GraphicsLayer(client)
, m_contentsLayerPurpose(NoContentsLayer)
, m_contentsLayerHasBackgroundColor(false)
, m_inSetChildren(false)
, m_pageScaleChanged(false)
{
m_layer = ContentLayerChromium::create(this);
updateDebugIndicators();
}
GraphicsLayerChromium::~GraphicsLayerChromium()
{
willBeDestroyed();
}
void GraphicsLayerChromium::willBeDestroyed()
{
if (m_layer) {
m_layer->clearDelegate();
m_layer->clearRenderSurface();
m_layer->setLayerAnimationDelegate(0);
}
if (m_contentsLayer)
m_contentsLayer->clearRenderSurface();
if (m_transformLayer) {
m_transformLayer->clearRenderSurface();
m_transformLayer->setLayerAnimationDelegate(0);
}
GraphicsLayer::willBeDestroyed();
}
void GraphicsLayerChromium::setName(const String& inName)
{
m_nameBase = inName;
String name = String::format("GraphicsLayerChromium(%p) GraphicsLayer(%p) ", m_layer.get(), this) + inName;
GraphicsLayer::setName(name);
updateNames();
}
void GraphicsLayerChromium::updateNames()
{
if (m_layer)
m_layer->setDebugName("Layer for " + m_nameBase);
if (m_transformLayer)
m_transformLayer->setDebugName("TransformLayer for " + m_nameBase);
if (m_contentsLayer)
m_contentsLayer->setDebugName("ContentsLayer for " + m_nameBase);
}
bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children)
{
m_inSetChildren = true;
bool childrenChanged = GraphicsLayer::setChildren(children);
if (childrenChanged)
updateChildList();
m_inSetChildren = false;
return childrenChanged;
}
void GraphicsLayerChromium::addChild(GraphicsLayer* childLayer)
{
GraphicsLayer::addChild(childLayer);
if (!m_inSetChildren)
updateChildList();
}
void GraphicsLayerChromium::addChildAtIndex(GraphicsLayer* childLayer, int index)
{
GraphicsLayer::addChildAtIndex(childLayer, index);
updateChildList();
}
void GraphicsLayerChromium::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
{
GraphicsLayer::addChildBelow(childLayer, sibling);
updateChildList();
}
void GraphicsLayerChromium::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer *sibling)
{
GraphicsLayer::addChildAbove(childLayer, sibling);
updateChildList();
}
bool GraphicsLayerChromium::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
{
if (GraphicsLayer::replaceChild(oldChild, newChild)) {
updateChildList();
return true;
}
return false;
}
void GraphicsLayerChromium::removeFromParent()
{
GraphicsLayer::removeFromParent();
layerForParent()->removeFromParent();
}
void GraphicsLayerChromium::setPosition(const FloatPoint& point)
{
GraphicsLayer::setPosition(point);
updateLayerPosition();
}
void GraphicsLayerChromium::setAnchorPoint(const FloatPoint3D& point)
{
GraphicsLayer::setAnchorPoint(point);
updateAnchorPoint();
}
void GraphicsLayerChromium::setSize(const FloatSize& size)
{
FloatSize clampedSize = size;
if (clampedSize.width() < 0 || clampedSize.height() < 0)
clampedSize = FloatSize();
if (clampedSize == m_size)
return;
GraphicsLayer::setSize(clampedSize);
updateLayerSize();
if (m_pageScaleChanged && m_layer)
m_layer->setNeedsDisplay();
m_pageScaleChanged = false;
}
void GraphicsLayerChromium::setTransform(const TransformationMatrix& transform)
{
updateContentsScale();
GraphicsLayer::setTransform(transform);
updateTransform();
}
void GraphicsLayerChromium::setChildrenTransform(const TransformationMatrix& transform)
{
GraphicsLayer::setChildrenTransform(transform);
updateChildrenTransform();
}
void GraphicsLayerChromium::setPreserves3D(bool preserves3D)
{
if (preserves3D == m_preserves3D)
return;
GraphicsLayer::setPreserves3D(preserves3D);
updateLayerPreserves3D();
}
void GraphicsLayerChromium::setMasksToBounds(bool masksToBounds)
{
GraphicsLayer::setMasksToBounds(masksToBounds);
updateMasksToBounds();
}
void GraphicsLayerChromium::setDrawsContent(bool drawsContent)
{
if (drawsContent == m_drawsContent)
return;
GraphicsLayer::setDrawsContent(drawsContent);
updateLayerIsDrawable();
}
void GraphicsLayerChromium::setContentsVisible(bool contentsVisible)
{
if (contentsVisible == m_contentsVisible)
return;
GraphicsLayer::setContentsVisible(contentsVisible);
updateLayerIsDrawable();
}
void GraphicsLayerChromium::setBackgroundColor(const Color& color)
{
GraphicsLayer::setBackgroundColor(color);
m_contentsLayerHasBackgroundColor = true;
updateLayerBackgroundColor();
}
void GraphicsLayerChromium::clearBackgroundColor()
{
GraphicsLayer::clearBackgroundColor();
m_contentsLayer->setBackgroundColor(static_cast<RGBA32>(0));
}
void GraphicsLayerChromium::setContentsOpaque(bool opaque)
{
GraphicsLayer::setContentsOpaque(opaque);
m_layer->setOpaque(m_contentsOpaque);
}
bool GraphicsLayerChromium::setFilters(const FilterOperations& filters)
{
m_layer->setFilters(filters);
return GraphicsLayer::setFilters(filters);
}
void GraphicsLayerChromium::setMaskLayer(GraphicsLayer* maskLayer)
{
if (maskLayer == m_maskLayer)
return;
GraphicsLayer::setMaskLayer(maskLayer);
LayerChromium* maskLayerChromium = m_maskLayer ? m_maskLayer->platformLayer() : 0;
m_layer->setMaskLayer(maskLayerChromium);
}
void GraphicsLayerChromium::setBackfaceVisibility(bool visible)
{
GraphicsLayer::setBackfaceVisibility(visible);
m_layer->setDoubleSided(m_backfaceVisibility);
}
void GraphicsLayerChromium::setOpacity(float opacity)
{
float clampedOpacity = max(min(opacity, 1.0f), 0.0f);
GraphicsLayer::setOpacity(clampedOpacity);
primaryLayer()->setOpacity(opacity);
}
void GraphicsLayerChromium::setReplicatedByLayer(GraphicsLayer* layer)
{
GraphicsLayerChromium* layerChromium = static_cast<GraphicsLayerChromium*>(layer);
GraphicsLayer::setReplicatedByLayer(layer);
LayerChromium* replicaLayer = layerChromium ? layerChromium->primaryLayer() : 0;
primaryLayer()->setReplicaLayer(replicaLayer);
}
void GraphicsLayerChromium::setContentsNeedsDisplay()
{
if (m_contentsLayer)
m_contentsLayer->setNeedsDisplay();
}
void GraphicsLayerChromium::setNeedsDisplay()
{
if (drawsContent())
m_layer->setNeedsDisplay();
}
void GraphicsLayerChromium::setNeedsDisplayInRect(const FloatRect& rect)
{
if (drawsContent())
m_layer->setNeedsDisplayRect(rect);
}
void GraphicsLayerChromium::setContentsRect(const IntRect& rect)
{
if (rect == m_contentsRect)
return;
GraphicsLayer::setContentsRect(rect);
updateContentsRect();
}
void GraphicsLayerChromium::setContentsToImage(Image* image)
{
bool childrenChanged = false;
if (image) {
if (!m_contentsLayer.get() || m_contentsLayerPurpose != ContentsLayerForImage) {
RefPtr<ImageLayerChromium> imageLayer = ImageLayerChromium::create();
setupContentsLayer(imageLayer.get());
m_contentsLayerPurpose = ContentsLayerForImage;
childrenChanged = true;
}
ImageLayerChromium* imageLayer = static_cast<ImageLayerChromium*>(m_contentsLayer.get());
imageLayer->setContents(image);
imageLayer->setOpaque(image->isBitmapImage() && !image->currentFrameHasAlpha());
updateContentsRect();
} else {
if (m_contentsLayer) {
childrenChanged = true;
m_contentsLayer = 0;
}
}
if (childrenChanged)
updateChildList();
}
void GraphicsLayerChromium::setContentsToCanvas(PlatformLayer* platformLayer)
{
bool childrenChanged = false;
if (platformLayer) {
if (m_contentsLayer.get() != platformLayer) {
setupContentsLayer(platformLayer);
m_contentsLayerPurpose = ContentsLayerForCanvas;
childrenChanged = true;
}
updateContentsRect();
} else {
if (m_contentsLayer) {
childrenChanged = true;
m_contentsLayer = 0;
}
}
if (childrenChanged)
updateChildList();
}
bool GraphicsLayerChromium::addAnimation(const KeyframeValueList& values, const IntSize& boxSize, const Animation* animation, const String& animationName, double timeOffset)
{
primaryLayer()->setLayerAnimationDelegate(this);
return primaryLayer()->addAnimation(values, boxSize, animation, mapAnimationNameToId(animationName), s_nextGroupId++, timeOffset);
}
void GraphicsLayerChromium::pauseAnimation(const String& animationName, double timeOffset)
{
primaryLayer()->pauseAnimation(mapAnimationNameToId(animationName), timeOffset);
}
void GraphicsLayerChromium::removeAnimation(const String& animationName)
{
primaryLayer()->removeAnimation(mapAnimationNameToId(animationName));
}
void GraphicsLayerChromium::suspendAnimations(double wallClockTime)
{
double monotonicTime = wallClockTime + monotonicallyIncreasingTime() - currentTime();
primaryLayer()->suspendAnimations(monotonicTime);
}
void GraphicsLayerChromium::resumeAnimations()
{
primaryLayer()->resumeAnimations(monotonicallyIncreasingTime());
}
void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer)
{
bool childrenChanged = false;
if (layer) {
if (!m_contentsLayer.get() || m_contentsLayerPurpose != ContentsLayerForVideo) {
setupContentsLayer(layer);
m_contentsLayerPurpose = ContentsLayerForVideo;
childrenChanged = true;
}
updateContentsRect();
} else {
if (m_contentsLayer) {
childrenChanged = true;
m_contentsLayer = 0;
}
}
if (childrenChanged)
updateChildList();
}
PlatformLayer* GraphicsLayerChromium::hostLayerForChildren() const
{
return m_transformLayer ? m_transformLayer.get() : m_layer.get();
}
PlatformLayer* GraphicsLayerChromium::layerForParent() const
{
return m_transformLayer ? m_transformLayer.get() : m_layer.get();
}
PlatformLayer* GraphicsLayerChromium::platformLayer() const
{
return primaryLayer();
}
void GraphicsLayerChromium::setDebugBackgroundColor(const Color& color)
{
if (color.isValid())
m_layer->setBackgroundColor(color);
else
m_layer->setBackgroundColor(static_cast<RGBA32>(0));
}
void GraphicsLayerChromium::setDebugBorder(const Color& color, float borderWidth)
{
if (color.isValid()) {
m_layer->setDebugBorderColor(color);
m_layer->setDebugBorderWidth(borderWidth);
} else {
m_layer->setDebugBorderColor(static_cast<RGBA32>(0));
m_layer->setDebugBorderWidth(0);
}
}
void GraphicsLayerChromium::updateChildList()
{
Vector<RefPtr<LayerChromium> > newChildren;
if (m_transformLayer) {
newChildren.append(m_layer.get());
} else if (m_contentsLayer) {
newChildren.append(m_contentsLayer.get());
}
const Vector<GraphicsLayer*>& childLayers = children();
size_t numChildren = childLayers.size();
for (size_t i = 0; i < numChildren; ++i) {
GraphicsLayerChromium* curChild = static_cast<GraphicsLayerChromium*>(childLayers[i]);
LayerChromium* childLayer = curChild->layerForParent();
newChildren.append(childLayer);
}
for (size_t i = 0; i < newChildren.size(); ++i)
newChildren[i]->removeFromParent();
if (m_transformLayer) {
m_transformLayer->setChildren(newChildren);
if (m_contentsLayer) {
m_layer->removeAllChildren();
m_layer->addChild(m_contentsLayer);
}
} else
m_layer->setChildren(newChildren);
}
void GraphicsLayerChromium::updateLayerPosition()
{
FloatPoint layerPosition(m_position.x() + m_anchorPoint.x() * m_size.width(),
m_position.y() + m_anchorPoint.y() * m_size.height());
primaryLayer()->setPosition(layerPosition);
}
void GraphicsLayerChromium::updateLayerSize()
{
IntSize layerSize(m_size.width(), m_size.height());
if (m_transformLayer) {
m_transformLayer->setBounds(layerSize);
FloatPoint centerPoint(m_size.width() / 2, m_size.height() / 2);
m_layer->setPosition(centerPoint);
}
m_layer->setBounds(layerSize);
updateLayerPosition();
}
void GraphicsLayerChromium::updateAnchorPoint()
{
primaryLayer()->setAnchorPoint(FloatPoint(m_anchorPoint.x(), m_anchorPoint.y()));
primaryLayer()->setAnchorPointZ(m_anchorPoint.z());
updateLayerPosition();
}
void GraphicsLayerChromium::updateTransform()
{
primaryLayer()->setTransform(m_transform);
}
void GraphicsLayerChromium::updateChildrenTransform()
{
primaryLayer()->setSublayerTransform(m_childrenTransform);
}
void GraphicsLayerChromium::updateMasksToBounds()
{
m_layer->setMasksToBounds(m_masksToBounds);
updateDebugIndicators();
}
void GraphicsLayerChromium::updateLayerPreserves3D()
{
if (m_preserves3D && !m_transformLayer) {
m_transformLayer = LayerChromium::create();
m_transformLayer->setPreserves3D(true);
m_transformLayer->setLayerAnimationDelegate(this);
updateLayerPosition();
updateLayerSize();
updateAnchorPoint();
updateTransform();
updateChildrenTransform();
m_layer->setPosition(FloatPoint(m_size.width() / 2.0f, m_size.height() / 2.0f));
m_layer->setAnchorPoint(FloatPoint(0.5f, 0.5f));
TransformationMatrix identity;
m_layer->setTransform(identity);
m_layer->setOpacity(1);
m_layer->setContentsScale(contentsScale());
if (m_layer->parent())
m_layer->parent()->replaceChild(m_layer.get(), m_transformLayer.get());
m_transformLayer->addChild(m_layer.get());
updateChildList();
} else if (!m_preserves3D && m_transformLayer) {
m_layer->removeFromParent();
if (m_transformLayer->parent())
m_transformLayer->parent()->replaceChild(m_transformLayer.get(), m_layer.get());
m_transformLayer->setLayerAnimationDelegate(0);
m_transformLayer = 0;
updateLayerPosition();
updateLayerSize();
updateAnchorPoint();
updateTransform();
updateChildrenTransform();
updateChildList();
}
m_layer->setPreserves3D(m_preserves3D);
primaryLayer()->setOpacity(m_opacity);
updateNames();
}
void GraphicsLayerChromium::updateLayerIsDrawable()
{
m_layer->setIsDrawable(m_drawsContent && m_contentsVisible);
if (m_contentsLayer)
m_contentsLayer->setIsDrawable(m_contentsVisible);
if (m_drawsContent)
m_layer->setNeedsDisplay();
updateDebugIndicators();
}
void GraphicsLayerChromium::updateLayerBackgroundColor()
{
if (!m_contentsLayer)
return;
if (m_backgroundColorSet)
m_contentsLayer->setBackgroundColor(m_backgroundColor);
else
m_contentsLayer->setBackgroundColor(static_cast<RGBA32>(0));
}
void GraphicsLayerChromium::updateContentsVideo()
{
}
void GraphicsLayerChromium::updateContentsRect()
{
if (!m_contentsLayer)
return;
m_contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y()));
m_contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height()));
}
void GraphicsLayerChromium::updateContentsScale()
{
if (appliesPageScale() || !m_layer)
return;
m_layer->setContentsScale(contentsScale());
}
void GraphicsLayerChromium::setupContentsLayer(LayerChromium* contentsLayer)
{
if (contentsLayer == m_contentsLayer)
return;
if (m_contentsLayer) {
m_contentsLayer->removeFromParent();
m_contentsLayer = 0;
}
if (contentsLayer) {
m_contentsLayer = contentsLayer;
m_contentsLayer->setAnchorPoint(FloatPoint(0, 0));
m_contentsLayer->setIsDrawable(m_contentsVisible);
m_layer->insertChild(m_contentsLayer.get(), 0);
if (showDebugBorders()) {
m_contentsLayer->setDebugBorderColor(Color(0, 0, 128, 180));
m_contentsLayer->setDebugBorderWidth(1);
}
}
updateDebugIndicators();
updateNames();
}
float GraphicsLayerChromium::contentsScale() const
{
if (!appliesPageScale())
return pageScaleFactor() * deviceScaleFactor();
return 1;
}
void GraphicsLayerChromium::deviceOrPageScaleFactorChanged()
{
updateContentsScale();
m_pageScaleChanged = true;
}
void GraphicsLayerChromium::paintContents(GraphicsContext& context, const IntRect& clip)
{
paintGraphicsLayerContents(context, clip);
}
int GraphicsLayerChromium::mapAnimationNameToId(const String& animationName)
{
if (animationName.isEmpty())
return 0;
if (!m_animationIdMap.contains(animationName))
m_animationIdMap.add(animationName, s_nextAnimationId++);
return m_animationIdMap.find(animationName)->second;
}
void GraphicsLayerChromium::notifyAnimationStarted(double startTime)
{
if (m_client)
m_client->notifyAnimationStarted(this, startTime);
}
void GraphicsLayerChromium::notifyAnimationFinished(double)
{
}
}
#endif // USE(ACCELERATED_COMPOSITING)