| Index: WebCore/platform/graphics/skia/GraphicsLayerSkia.cpp
|
| ===================================================================
|
| --- WebCore/platform/graphics/skia/GraphicsLayerSkia.cpp (revision 0)
|
| +++ WebCore/platform/graphics/skia/GraphicsLayerSkia.cpp (revision 0)
|
| @@ -0,0 +1,586 @@
|
| +/*
|
| + * Copyright (c) 2010, Google Inc. All rights reserved.
|
| + * Copyright (C) 2009 Apple 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.
|
| + */
|
| +
|
| +
|
| +/** TODO(Vangelis)
|
| + * This file borrows code heavily from platform/graphics/win/GraphicsLayerCACF.cpp
|
| + * (and hence it includes both copyrights)
|
| + * Ideally the common code (e.g. the code that keeps track of the layer hierarchy
|
| + * should be kept separate and shared between platforms.
|
| + */
|
| +
|
| +#include "config.h"
|
| +
|
| +#if USE(ACCELERATED_COMPOSITING)
|
| +
|
| +#include "GraphicsLayerSkia.h"
|
| +
|
| +#include "CString.h"
|
| +#include "FloatConversion.h"
|
| +#include "FloatRect.h"
|
| +#include "Image.h"
|
| +#include "PlatformString.h"
|
| +#include "SystemTime.h"
|
| +#include "LayerSkia.h"
|
| +#include <wtf/CurrentTime.h>
|
| +#include <wtf/StringExtras.h>
|
| +
|
| +using namespace std;
|
| +
|
| +namespace WebCore {
|
| +
|
| +
|
| +static void setLayerBorderColor(LayerSkia* layer, const Color& color)
|
| +{
|
| + layer->setBorderColor(color);
|
| +}
|
| +
|
| +static void clearBorderColor(LayerSkia* layer)
|
| +{
|
| + layer->setBorderColor(Color(0, 0, 0, 0));
|
| +}
|
| +
|
| +static void setLayerBackgroundColor(LayerSkia* layer, const Color& color)
|
| +{
|
| + layer->setBackgroundColor(color);
|
| +}
|
| +
|
| +static void clearLayerBackgroundColor(LayerSkia* layer)
|
| +{
|
| + layer->setBackgroundColor(0);
|
| +}
|
| +
|
| +GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoordinatesOrientation()
|
| +{
|
| + return CompositingCoordinatesBottomUp;
|
| +}
|
| +
|
| +PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
|
| +{
|
| + return new GraphicsLayerSkia(client);
|
| +}
|
| +
|
| +GraphicsLayerSkia::GraphicsLayerSkia(GraphicsLayerClient* client)
|
| + : GraphicsLayer(client)
|
| + , m_contentsLayerPurpose(NoContentsLayer)
|
| + , m_contentsLayerHasBackgroundColor(false)
|
| +{
|
| + m_layer = LayerSkia::create(LayerSkia::Layer, this);
|
| +
|
| + updateDebugIndicators();
|
| +}
|
| +
|
| +GraphicsLayerSkia::~GraphicsLayerSkia()
|
| +{
|
| + // clean up the Skia layer
|
| + if (m_layer)
|
| + m_layer->removeFromSuperlayer();
|
| +
|
| + if (m_transformLayer)
|
| + m_transformLayer->removeFromSuperlayer();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setName(const String& inName)
|
| +{
|
| + String name = String::format("GraphicsLayerSkia(%p) GraphicsLayer(%p) ", m_layer.get(), this) + inName;
|
| + GraphicsLayer::setName(name);
|
| +}
|
| +
|
| +NativeLayer GraphicsLayerSkia::nativeLayer() const
|
| +{
|
| + return m_layer.get();
|
| +}
|
| +
|
| +bool GraphicsLayerSkia::setChildren(const Vector<GraphicsLayer*>& children)
|
| +{
|
| + bool childrenChanged = GraphicsLayer::setChildren(children);
|
| + // FIXME: GraphicsLayer::setChildren calls addChild() for each sublayer, which
|
| + // will end up calling updateSublayerList() N times.
|
| + if (childrenChanged)
|
| + updateSublayerList();
|
| +
|
| + return childrenChanged;
|
| +}
|
| +
|
| +void GraphicsLayerSkia::addChild(GraphicsLayer* childLayer)
|
| +{
|
| + GraphicsLayer::addChild(childLayer);
|
| + updateSublayerList();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::addChildAtIndex(GraphicsLayer* childLayer, int index)
|
| +{
|
| + GraphicsLayer::addChildAtIndex(childLayer, index);
|
| + updateSublayerList();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
|
| +{
|
| + GraphicsLayer::addChildBelow(childLayer, sibling);
|
| + updateSublayerList();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer *sibling)
|
| +{
|
| + GraphicsLayer::addChildAbove(childLayer, sibling);
|
| + updateSublayerList();
|
| +}
|
| +
|
| +bool GraphicsLayerSkia::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
|
| +{
|
| + if (GraphicsLayer::replaceChild(oldChild, newChild)) {
|
| + updateSublayerList();
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void GraphicsLayerSkia::removeFromParent()
|
| +{
|
| + GraphicsLayer::removeFromParent();
|
| + layerForSuperlayer()->removeFromSuperlayer();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setPosition(const FloatPoint& point)
|
| +{
|
| + GraphicsLayer::setPosition(point);
|
| + updateLayerPosition();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setAnchorPoint(const FloatPoint3D& point)
|
| +{
|
| + if (point == m_anchorPoint)
|
| + return;
|
| +
|
| + GraphicsLayer::setAnchorPoint(point);
|
| + updateAnchorPoint();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setSize(const FloatSize& size)
|
| +{
|
| + if (size == m_size)
|
| + return;
|
| +
|
| + GraphicsLayer::setSize(size);
|
| + updateLayerSize();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setTransform(const TransformationMatrix& t)
|
| +{
|
| + if (t == m_transform)
|
| + return;
|
| +
|
| + GraphicsLayer::setTransform(t);
|
| + updateTransform();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setChildrenTransform(const TransformationMatrix& t)
|
| +{
|
| + if (t == m_childrenTransform)
|
| + return;
|
| +
|
| + GraphicsLayer::setChildrenTransform(t);
|
| + updateChildrenTransform();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setPreserves3D(bool preserves3D)
|
| +{
|
| + if (preserves3D == m_preserves3D)
|
| + return;
|
| +
|
| + GraphicsLayer::setPreserves3D(preserves3D);
|
| + updateLayerPreserves3D();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setMasksToBounds(bool masksToBounds)
|
| +{
|
| + if (masksToBounds == m_masksToBounds)
|
| + return;
|
| +
|
| + GraphicsLayer::setMasksToBounds(masksToBounds);
|
| + updateMasksToBounds();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setDrawsContent(bool drawsContent)
|
| +{
|
| + if (drawsContent == m_drawsContent)
|
| + return;
|
| +
|
| + GraphicsLayer::setDrawsContent(drawsContent);
|
| + updateLayerDrawsContent();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setBackgroundColor(const Color& color)
|
| +{
|
| + if (m_backgroundColorSet && m_backgroundColor == color)
|
| + return;
|
| +
|
| + GraphicsLayer::setBackgroundColor(color);
|
| +
|
| + m_contentsLayerHasBackgroundColor = true;
|
| + updateLayerBackgroundColor();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::clearBackgroundColor()
|
| +{
|
| + if (!m_backgroundColorSet)
|
| + return;
|
| +
|
| + GraphicsLayer::clearBackgroundColor();
|
| + clearLayerBackgroundColor(m_contentsLayer.get());
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setContentsOpaque(bool opaque)
|
| +{
|
| + if (m_contentsOpaque == opaque)
|
| + return;
|
| +
|
| + GraphicsLayer::setContentsOpaque(opaque);
|
| + updateContentsOpaque();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setBackfaceVisibility(bool visible)
|
| +{
|
| + if (m_backfaceVisibility == visible)
|
| + return;
|
| +
|
| + GraphicsLayer::setBackfaceVisibility(visible);
|
| + updateBackfaceVisibility();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setOpacity(float opacity)
|
| +{
|
| + float clampedOpacity = max(min(opacity, 1.0f), 0.0f);
|
| +
|
| + if (m_opacity == clampedOpacity)
|
| + return;
|
| +
|
| + GraphicsLayer::setOpacity(clampedOpacity);
|
| + primaryLayer()->setOpacity(opacity);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setNeedsDisplay()
|
| +{
|
| + if (drawsContent())
|
| + m_layer->setNeedsDisplay();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setNeedsDisplayInRect(const FloatRect& rect)
|
| +{
|
| + if (drawsContent())
|
| + m_layer->setNeedsDisplay(rect);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setContentsRect(const IntRect& rect)
|
| +{
|
| + if (rect == m_contentsRect)
|
| + return;
|
| +
|
| + GraphicsLayer::setContentsRect(rect);
|
| + updateContentsRect();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setContentsToImage(Image* image)
|
| +{
|
| + // TODO(vangelis): Implement
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setContentsToVideo(PlatformLayer* videoLayer)
|
| +{
|
| + // TODO(vangelis): Implement
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setGeometryOrientation(CompositingCoordinatesOrientation orientation)
|
| +{
|
| + if (orientation == m_geometryOrientation)
|
| + return;
|
| +
|
| + GraphicsLayer::setGeometryOrientation(orientation);
|
| + updateGeometryOrientation();
|
| +}
|
| +
|
| +PlatformLayer* GraphicsLayerSkia::hostLayerForSublayers() const
|
| +{
|
| + return m_transformLayer ? m_transformLayer.get() : m_layer.get();
|
| +}
|
| +
|
| +PlatformLayer* GraphicsLayerSkia::layerForSuperlayer() const
|
| +{
|
| + return m_transformLayer ? m_transformLayer.get() : m_layer.get();
|
| +}
|
| +
|
| +PlatformLayer* GraphicsLayerSkia::platformLayer() const
|
| +{
|
| + return primaryLayer();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setDebugBackgroundColor(const Color& color)
|
| +{
|
| + if (color.isValid())
|
| + setLayerBackgroundColor(m_layer.get(), color);
|
| + else
|
| + clearLayerBackgroundColor(m_layer.get());
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setDebugBorder(const Color& color, float borderWidth)
|
| +{
|
| + if (color.isValid()) {
|
| + setLayerBorderColor(m_layer.get(), color);
|
| + m_layer->setBorderWidth(borderWidth);
|
| + } else {
|
| + clearBorderColor(m_layer.get());
|
| + m_layer->setBorderWidth(0);
|
| + }
|
| +}
|
| +
|
| +GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerSkia::defaultContentsOrientation() const
|
| +{
|
| + return CompositingCoordinatesTopDown;
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateSublayerList()
|
| +{
|
| + Vector<RefPtr<LayerSkia> > newSublayers;
|
| +
|
| + if (m_transformLayer) {
|
| + // Add the primary layer first. Even if we have negative z-order children, the primary layer always comes behind.
|
| + newSublayers.append(m_layer.get());
|
| + } else if (m_contentsLayer) {
|
| + // FIXME: add the contents layer in the correct order with negative z-order children.
|
| + // This does not cause visible rendering issues because currently contents layers are only used
|
| + // for replaced elements that don't have children.
|
| + newSublayers.append(m_contentsLayer.get());
|
| + }
|
| +
|
| + const Vector<GraphicsLayer*>& childLayers = children();
|
| + size_t numChildren = childLayers.size();
|
| + for (size_t i = 0; i < numChildren; ++i) {
|
| + GraphicsLayerSkia* curChild = static_cast<GraphicsLayerSkia*>(childLayers[i]);
|
| +
|
| + LayerSkia* childLayer = curChild->layerForSuperlayer();
|
| + newSublayers.append(childLayer);
|
| + }
|
| +
|
| + for (size_t i = 0; i < newSublayers.size(); ++i)
|
| + newSublayers[i]->removeFromSuperlayer();
|
| +
|
| + if (m_transformLayer) {
|
| + m_transformLayer->setSublayers(newSublayers);
|
| +
|
| + if (m_contentsLayer) {
|
| + // If we have a transform layer, then the contents layer is parented in the
|
| + // primary layer (which is itself a child of the transform layer).
|
| + m_layer->removeAllSublayers();
|
| + m_layer->addSublayer(m_contentsLayer);
|
| + }
|
| + } else
|
| + m_layer->setSublayers(newSublayers);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateLayerPosition()
|
| +{
|
| + // Position is offset on the layer by the layer anchor point.
|
| + SkPoint posPoint;
|
| + posPoint.set(m_position.x() + m_anchorPoint.x() * m_size.width(),
|
| + posPoint.fY = m_position.y() + m_anchorPoint.y() * m_size.height());
|
| +
|
| + primaryLayer()->setPosition(posPoint);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateLayerSize()
|
| +{
|
| + SkIRect rect;
|
| + rect.set(0, 0, m_size.width(), m_size.height());
|
| + if (m_transformLayer) {
|
| + m_transformLayer->setBounds(rect);
|
| + // The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative.
|
| + SkPoint centerPoint;
|
| + centerPoint.set(m_size.width() / 2.0f, m_size.height() / 2.0f);
|
| + m_layer->setPosition(centerPoint);
|
| + }
|
| +
|
| + m_layer->setBounds(rect);
|
| +
|
| + // Note that we don't resize m_contentsLayer. It's up the caller to do that.
|
| +
|
| + // if we've changed the bounds, we need to recalculate the position
|
| + // of the layer, taking anchor point into account.
|
| + updateLayerPosition();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateAnchorPoint()
|
| +{
|
| + SkPoint anchorPoint;
|
| + anchorPoint.set(m_anchorPoint.x(), m_anchorPoint.y());
|
| + primaryLayer()->setAnchorPoint(anchorPoint);
|
| + primaryLayer()->setAnchorPointZ(m_anchorPoint.z());
|
| + updateLayerPosition();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateTransform()
|
| +{
|
| + primaryLayer()->setTransform(m_transform.toAffineTransform());
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateChildrenTransform()
|
| +{
|
| + primaryLayer()->setSublayerTransform(m_childrenTransform);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateMasksToBounds()
|
| +{
|
| + m_layer->setMasksToBounds(m_masksToBounds);
|
| + updateDebugIndicators();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateContentsOpaque()
|
| +{
|
| + m_layer->setOpaque(m_contentsOpaque);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateBackfaceVisibility()
|
| +{
|
| + m_layer->setDoubleSided(m_backfaceVisibility);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateLayerPreserves3D()
|
| +{
|
| + // TODO(vangelis): implement
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateLayerDrawsContent()
|
| +{
|
| + if (m_drawsContent)
|
| + m_layer->setNeedsDisplay();
|
| +
|
| + updateDebugIndicators();
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateLayerBackgroundColor()
|
| +{
|
| + if (!m_contentsLayer)
|
| + return;
|
| +
|
| + // We never create the contents layer just for background color yet.
|
| + if (m_backgroundColorSet)
|
| + setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor);
|
| + else
|
| + clearLayerBackgroundColor(m_contentsLayer.get());
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateContentsImage()
|
| +{
|
| + // TODO(vangelis): Implement
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateContentsVideo()
|
| +{
|
| + // TODO(vangelis): Implement
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateContentsRect()
|
| +{
|
| + if (!m_contentsLayer)
|
| + return;
|
| +
|
| + SkPoint point;
|
| + point.set(m_contentsRect.x(), m_contentsRect.y());
|
| + SkIRect rect;
|
| + rect.set(0,
|
| + 0,
|
| + m_contentsRect.width(),
|
| + m_contentsRect.height());
|
| +
|
| + m_contentsLayer->setPosition(point);
|
| + m_contentsLayer->setBounds(rect);
|
| +}
|
| +
|
| +void GraphicsLayerSkia::updateGeometryOrientation()
|
| +{
|
| + switch (geometryOrientation()) {
|
| + case CompositingCoordinatesTopDown:
|
| + m_layer->setGeometryFlipped(false);
|
| + break;
|
| +
|
| + case CompositingCoordinatesBottomUp:
|
| + m_layer->setGeometryFlipped(true);
|
| + break;
|
| + }
|
| + // Geometry orientation is mapped onto children transform in older QuartzCores,
|
| + // so is handled via setGeometryOrientation().
|
| +}
|
| +
|
| +void GraphicsLayerSkia::setupContentsLayer(LayerSkia* contentsLayer)
|
| +{
|
| + if (contentsLayer == m_contentsLayer)
|
| + return;
|
| +
|
| + if (m_contentsLayer) {
|
| + m_contentsLayer->removeFromSuperlayer();
|
| + m_contentsLayer = 0;
|
| + }
|
| +
|
| + if (contentsLayer) {
|
| + m_contentsLayer = contentsLayer;
|
| +
|
| + if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) {
|
| + SkPoint anchorPoint;
|
| + anchorPoint.set(0.0f, 1.0f);
|
| + m_contentsLayer->setAnchorPoint(anchorPoint);
|
| + } else {
|
| + SkPoint anchorPoint;
|
| + anchorPoint.set(0.0f, 0.0f);
|
| + m_contentsLayer->setAnchorPoint(anchorPoint);
|
| + }
|
| +
|
| + // Insert the content layer first. Video elements require this, because they have
|
| + // shadow content that must display in front of the video.
|
| + m_layer->insertSublayer(m_contentsLayer.get(), 0);
|
| +
|
| + updateContentsRect();
|
| +
|
| + if (showDebugBorders()) {
|
| + setLayerBorderColor(m_contentsLayer.get(), Color(0, 0, 128, 180));
|
| + m_contentsLayer->setBorderWidth(1.0f);
|
| + }
|
| + }
|
| + updateDebugIndicators();
|
| +}
|
| +
|
| +// This function simply mimics the operation of GraphicsLayerCA
|
| +void GraphicsLayerSkia::updateOpacityOnLayer()
|
| +{
|
| + primaryLayer()->setOpacity(m_opacity);
|
| +}
|
| +
|
| +} // namespace WebCore
|
| +
|
| +#endif // USE(ACCELERATED_COMPOSITING)
|
|
|