diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/ca')
7 files changed, 114 insertions, 17 deletions
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp index 37385c0..b72d761 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp @@ -253,6 +253,7 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client) , m_contentsLayerPurpose(NoContentsLayer) , m_contentsLayerHasBackgroundColor(false) , m_uncommittedChanges(NoChange) + , m_contentsScale(1) { m_layer = PlatformCALayer::create(PlatformCALayer::LayerTypeWebLayer, this); @@ -857,6 +858,9 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers() if (m_uncommittedChanges & AcceleratesDrawingChanged) updateAcceleratesDrawing(); + + if (m_uncommittedChanges & ContentsScaleChanged) + updateContentsScale(); } void GraphicsLayerCA::commitLayerChangesAfterSublayers() @@ -1897,6 +1901,44 @@ GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedProperty return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones(); } +void GraphicsLayerCA::setContentsScale(float scale) +{ + float newScale = clampedContentsScaleForScale(scale); + if (newScale == m_contentsScale) + return; + + m_contentsScale = newScale; + noteLayerPropertyChanged(ContentsScaleChanged); +} + +float GraphicsLayerCA::clampedContentsScaleForScale(float scale) const +{ + // Define some limits as a sanity check for the incoming scale value + // those too small to see. + const float maxScale = 5.0f; + const float minScale = 0.01f; + + // Avoid very slight scale changes that would be doing extra work for no benefit + const float maxAllowableDelta = 0.05f; + + // Clamp + float result = max(minScale, min(scale, maxScale)); + + // If it hasn't changed much, don't do any work + return ((fabs(result - m_contentsScale) / m_contentsScale) < maxAllowableDelta) ? m_contentsScale : result; +} + +void GraphicsLayerCA::updateContentsScale() +{ + bool needTiledLayer = requiresTiledLayer(m_size); + if (needTiledLayer != m_usingTiledLayer) + swapFromOrToTiledLayer(needTiledLayer); + + m_layer->setContentsScale(m_contentsScale); + if (drawsContent()) + m_layer->setNeedsDisplay(); +} + void GraphicsLayerCA::setDebugBackgroundColor(const Color& color) { if (color.isValid()) @@ -1950,12 +1992,11 @@ bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer) { - if (useTiledLayer == m_usingTiledLayer) - return; - + ASSERT(useTiledLayer != m_usingTiledLayer); RefPtr<PlatformCALayer> oldLayer = m_layer; m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this); + m_layer->setContentsScale(m_contentsScale); m_usingTiledLayer = useTiledLayer; @@ -2230,6 +2271,7 @@ PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, newLayer->setDoubleSided(layer->isDoubleSided()); newLayer->setOpaque(layer->isOpaque()); newLayer->setBackgroundColor(layer->backgroundColor()); + newLayer->setContentsScale(layer->contentsScale()); if (cloneLevel == IntermediateCloneLevel) { newLayer->setOpacity(layer->opacity()); diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h index 13cbdd1..2c39c0a 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h @@ -56,6 +56,9 @@ public: virtual PlatformLayer* platformLayer() const; virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); } + virtual float contentsScale() const { return m_contentsScale; } + virtual void setContentsScale(float); + virtual bool setChildren(const Vector<GraphicsLayer*>&); virtual void addChild(GraphicsLayer*); virtual void addChildAtIndex(GraphicsLayer*, int index); @@ -278,6 +281,7 @@ private: void updateLayerAnimations(); void updateContentsNeedsDisplay(); void updateAcceleratesDrawing(); + void updateContentsScale(); enum StructuralLayerPurpose { NoStructuralLayer = 0, @@ -320,7 +324,8 @@ private: MaskLayerChanged = 1 << 21, ReplicatedLayerChanged = 1 << 22, ContentsNeedsDisplay = 1 << 23, - AcceleratesDrawingChanged = 1 << 24 + AcceleratesDrawingChanged = 1 << 24, + ContentsScaleChanged = 1 << 25 }; typedef unsigned LayerChangeFlags; void noteLayerPropertyChanged(LayerChangeFlags flags); @@ -391,6 +396,9 @@ private: Vector<FloatRect> m_dirtyRects; LayerChangeFlags m_uncommittedChanges; + + float clampedContentsScaleForScale(float) const; + float m_contentsScale; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h index 46f4bbf..68566b3 100644 --- a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h +++ b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h @@ -182,6 +182,9 @@ public: CFTimeInterval timeOffset() const; void setTimeOffset(CFTimeInterval); + + float contentsScale() const; + void setContentsScale(float); #if PLATFORM(WIN) && !defined(NDEBUG) void printTree() const; diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm index 28460a7..2e20c3f 100644 --- a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm +++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm @@ -723,4 +723,24 @@ void PlatformCALayer::setTimeOffset(CFTimeInterval value) END_BLOCK_OBJC_EXCEPTIONS } +float PlatformCALayer::contentsScale() const +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + return [m_layer.get() contentsScale]; +#else + return 1; +#endif +} + +void PlatformCALayer::setContentsScale(float value) +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + BEGIN_BLOCK_OBJC_EXCEPTIONS + [m_layer.get() setContentsScale:value]; + END_BLOCK_OBJC_EXCEPTIONS +#else + UNUSED_PARAM(value); +#endif +} + #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp index 919c3b3..66d0732 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp @@ -253,15 +253,8 @@ size_t PlatformCALayer::sublayerCount() const void PlatformCALayer::adoptSublayers(PlatformCALayer* source) { - // Make a list of the sublayers from source PlatformCALayerList sublayers; - size_t n = source->sublayerCount(); - CFArrayRef sourceSublayers = CACFLayerGetSublayers(source->platformLayer()); - - for (size_t i = 0; i < n; ++i) { - CACFLayerRef layer = static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sourceSublayers, i))); - sublayers.append(platformCALayer(layer)); - } + intern(source)->getSublayers(sublayers); // Use setSublayers() because it properly nulls out the superlayer pointers. setSublayers(sublayers); @@ -586,6 +579,15 @@ void PlatformCALayer::setTimeOffset(CFTimeInterval value) setNeedsCommit(); } +float PlatformCALayer::contentsScale() const +{ + return 1; +} + +void PlatformCALayer::setContentsScale(float) +{ +} + #ifndef NDEBUG static void printIndent(int indent) { @@ -681,11 +683,11 @@ static void printLayer(const PlatformCALayer* layer, int indent) printIndent(indent + 1); fprintf(stderr, "(sublayers\n"); - CFArrayRef sublayers = CACFLayerGetSublayers(layer->platformLayer()); - for (int i = 0; i < n; ++i) { - PlatformCALayer* sublayer = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, i))); - printLayer(sublayer, indent + 2); - } + PlatformCALayerList sublayers; + intern(layer)->getSublayers(sublayers); + ASSERT(n == sublayers.size()); + for (int i = 0; i < n; ++i) + printLayer(sublayers[i].get(), indent + 2); printIndent(indent + 1); fprintf(stderr, ")\n"); diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp index 0b7eea0..cdf90db 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp @@ -210,6 +210,27 @@ void PlatformCALayerWinInternal::setSublayers(const PlatformCALayerList& list) } } +void PlatformCALayerWinInternal::getSublayers(PlatformCALayerList& list) const +{ + CFArrayRef sublayers = CACFLayerGetSublayers(owner()->platformLayer()); + if (!sublayers) { + list.clear(); + return; + } + + size_t count = CFArrayGetCount(sublayers); + + size_t layersToSkip = 0; + if (owner()->layerType() == PlatformCALayer::LayerTypeWebTiledLayer) { + // Exclude the tile parent layer. + layersToSkip = 1; + } + + list.resize(count - layersToSkip); + for (size_t arrayIndex = layersToSkip; arrayIndex < count; ++arrayIndex) + list[arrayIndex - layersToSkip] = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, arrayIndex))); +} + void PlatformCALayerWinInternal::removeAllSublayers() { CACFLayerSetSublayers(owner()->platformLayer(), 0); diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h index 1be9d26..39ef3b3 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h @@ -52,6 +52,7 @@ public: PlatformCALayer* owner() const { return m_owner; } void setSublayers(const PlatformCALayerList&); + void getSublayers(PlatformCALayerList&) const; void removeAllSublayers(); void insertSublayer(PlatformCALayer*, size_t); size_t sublayerCount() const; |