📄 graphicslayerca.mm
字号:
BEGIN_BLOCK_OBJC_EXCEPTIONS // add an entry for this animation addAnimationEntry(property, index, isTransition, transition); String keyPath = propertyIdToString(property); String animName = keyPath + "_" + String::number(index); CABasicAnimation* basicAnim = [CABasicAnimation animationWithKeyPath:keyPath]; double duration = transition->duration(); if (duration <= 0) duration = cAnimationAlmostZeroDuration; float repeatCount = transition->iterationCount(); if (repeatCount == Animation::IterationCountInfinite) repeatCount = FLT_MAX; else if (transition->direction() == Animation::AnimationDirectionAlternate) repeatCount /= 2; [basicAnim setDuration:duration]; [basicAnim setRepeatCount:repeatCount]; [basicAnim setAutoreverses:transition->direction()]; [basicAnim setRemovedOnCompletion:NO]; // Note that currently transform is the only property which has animations // with an index > 0. [basicAnim setAdditive:property == AnimatedPropertyWebkitTransform]; [basicAnim setFillMode:@"extended"];#if HAVE_MODERN_QUARTZCORE if (NSString* valueFunctionName = getValueFunctionNameForTransformOperation(operationType)) [basicAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];#else UNUSED_PARAM(operationType);#endif // Set the delegate (and property value). int prop = isTransition ? property : AnimatedPropertyInvalid; [basicAnim setValue:[NSNumber numberWithInt:prop] forKey:WebAnimationCSSPropertyKey]; [basicAnim setDelegate:m_animationDelegate.get()]; NSTimeInterval bt = beginTime ? [layer convertTime:currentTimeToMediaTime(beginTime) fromLayer:nil] : 0; [basicAnim setBeginTime:bt]; if (fromVal) [basicAnim setFromValue:reinterpret_cast<id>(fromVal)]; if (toVal) [basicAnim setToValue:reinterpret_cast<id>(toVal)]; const TimingFunction* tf = 0; if (transition->isTimingFunctionSet()) tf = &transition->timingFunction(); CAMediaTimingFunction* timingFunction = getCAMediaTimingFunction(tf ? *tf : TimingFunction()); [basicAnim setTimingFunction:timingFunction]; // Send over the animation. [layer removeAnimationForKey:animName]; [layer addAnimation:basicAnim forKey:animName]; END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setKeyframeAnimation(AnimatedPropertyID property, TransformOperation::OperationType operationType, short index, void* keys, void* values, void* timingFunctions, bool isTransition, const Animation* anim, double beginTime){ PlatformLayer* layer = animatedLayer(property); // Add an entry for this animation (which may change beginTime). addAnimationEntry(property, index, isTransition, anim); String keyPath = propertyIdToString(property); String animName = keyPath + "_" + String::number(index); BEGIN_BLOCK_OBJC_EXCEPTIONS CAKeyframeAnimation* keyframeAnim = [CAKeyframeAnimation animationWithKeyPath:keyPath]; double duration = anim->duration(); if (duration <= 0) duration = cAnimationAlmostZeroDuration; float repeatCount = anim->iterationCount(); if (repeatCount == Animation::IterationCountInfinite) repeatCount = FLT_MAX; else if (anim->direction() == Animation::AnimationDirectionAlternate) repeatCount /= 2; [keyframeAnim setDuration:duration]; [keyframeAnim setRepeatCount:repeatCount]; [keyframeAnim setAutoreverses:anim->direction()]; [keyframeAnim setRemovedOnCompletion:NO]; // The first animation is non-additive, all the rest are additive. // Note that currently transform is the only property which has animations // with an index > 0. [keyframeAnim setAdditive:(property == AnimatedPropertyWebkitTransform) ? YES : NO]; [keyframeAnim setFillMode:@"extended"];#if HAVE_MODERN_QUARTZCORE if (NSString* valueFunctionName = getValueFunctionNameForTransformOperation(operationType)) [keyframeAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];#else UNUSED_PARAM(operationType);#endif [keyframeAnim setKeyTimes:reinterpret_cast<id>(keys)]; [keyframeAnim setValues:reinterpret_cast<id>(values)]; // Set the delegate (and property value). int prop = isTransition ? property : AnimatedPropertyInvalid; [keyframeAnim setValue:[NSNumber numberWithInt: prop] forKey:WebAnimationCSSPropertyKey]; [keyframeAnim setDelegate:m_animationDelegate.get()]; NSTimeInterval bt = beginTime ? [layer convertTime:currentTimeToMediaTime(beginTime) fromLayer:nil] : 0; [keyframeAnim setBeginTime:bt]; // Set the timing functions, if any. if (timingFunctions != nil) [keyframeAnim setTimingFunctions:(id)timingFunctions]; // Send over the animation. [layer removeAnimationForKey:animName]; [layer addAnimation:keyframeAnim forKey:animName]; END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::suspendAnimations(){ double t = currentTimeToMediaTime(currentTime()); [primaryLayer() setSpeed:0]; [primaryLayer() setTimeOffset:t];}void GraphicsLayerCA::resumeAnimations(){ [primaryLayer() setSpeed:1]; [primaryLayer() setTimeOffset:0];}void GraphicsLayerCA::removeAnimation(int index, bool reset){ ASSERT(index >= 0); AnimatedPropertyID property = m_animations[index].property(); // Set the value of the property and remove the animation. String keyPath = propertyIdToString(property); String animName = keyPath + "_" + String::number(m_animations[index].index()); CALayer* layer = animatedLayer(property); BEGIN_BLOCK_OBJC_EXCEPTIONS // If we are not resetting, it means we are pausing. So we need to get the current presentation // value into the property before we remove the animation. if (!reset) { // Put the current value into the property. CALayer* presLayer = [layer presentationLayer]; if (presLayer) [layer setValue:[presLayer valueForKeyPath:keyPath] forKeyPath:keyPath]; // Make sure the saved values accurately reflect the value in the layer. id val = [layer valueForKeyPath:keyPath]; switch (property) { case AnimatedPropertyWebkitTransform: // FIXME: needs comment explaining why the m_transform is not obtained from the layer break; case AnimatedPropertyBackgroundColor: m_backgroundColor = Color(reinterpret_cast<CGColorRef>(val)); break; case AnimatedPropertyOpacity: m_opacity = [val floatValue]; break; case AnimatedPropertyInvalid: ASSERT_NOT_REACHED(); break; } } // If we have reached the end of an animation, we don't want to actually remove the // animation from the CALayer. At some point we will be setting the property to its // unanimated value and at that point we will remove the animation. That will avoid // any flashing between the time the animation is removed and the property is set. if (!reset || m_animations[index].isTransition()) [layer removeAnimationForKey:animName]; END_BLOCK_OBJC_EXCEPTIONS // Remove the animation entry. m_animations.remove(index);}PlatformLayer* GraphicsLayerCA::hostLayerForSublayers() const{ return m_transformLayer ? m_transformLayer.get() : m_layer.get();}PlatformLayer* GraphicsLayerCA::layerForSuperlayer() const{ if (m_transformLayer) return m_transformLayer.get(); return m_layer.get();}PlatformLayer* GraphicsLayerCA::platformLayer() const{ return primaryLayer();}#ifndef NDEBUGvoid GraphicsLayerCA::setDebugBackgroundColor(const Color& color){ BEGIN_BLOCK_OBJC_EXCEPTIONS if (color.isValid()) setLayerBackgroundColor(m_layer.get(), color); else clearLayerBackgroundColor(m_layer.get()); END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth){ BEGIN_BLOCK_OBJC_EXCEPTIONS if (color.isValid()) { setLayerBorderColor(m_layer.get(), color); [m_layer.get() setBorderWidth:borderWidth]; } else { clearBorderColor(m_layer.get()); [m_layer.get() setBorderWidth:0]; } END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setZPosition(float position){ GraphicsLayer::setZPosition(position); BEGIN_BLOCK_OBJC_EXCEPTIONS [primaryLayer() setZPosition:position]; END_BLOCK_OBJC_EXCEPTIONS}#endifbool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const{ if (!m_drawsContent) return false; // FIXME: catch zero-size height or width here (or earlier)? return size.width() > cMaxPixelDimension || size.height() > cMaxPixelDimension;}void GraphicsLayerCA::swapFromOrToTiledLayer(bool userTiledLayer){ if (userTiledLayer == m_usingTiledLayer) return; CGSize tileSize = CGSizeMake(cTiledLayerTileSize, cTiledLayerTileSize); BEGIN_BLOCK_OBJC_EXCEPTIONS RetainPtr<CALayer> oldLayer = m_layer.get(); Class layerClass = userTiledLayer ? [WebTiledLayer self] : [WebLayer self]; m_layer.adoptNS([[layerClass alloc] init]); if (userTiledLayer) { WebTiledLayer* tiledLayer = (WebTiledLayer*)m_layer.get(); [tiledLayer setTileSize:tileSize]; [tiledLayer setLevelsOfDetail:1]; [tiledLayer setLevelsOfDetailBias:0]; if (GraphicsLayer::graphicsContextsFlipped()) [tiledLayer setContentsGravity:@"bottomLeft"]; else [tiledLayer setContentsGravity:@"topLeft"]; } [m_layer.get() setLayerOwner:this]; [m_layer.get() setSublayers:[oldLayer.get() sublayers]]; [[oldLayer.get() superlayer] replaceSublayer:oldLayer.get() with:m_layer.get()]; [m_layer.get() setBounds:[oldLayer.get() bounds]]; [m_layer.get() setPosition:[oldLayer.get() position]]; [m_layer.get() setAnchorPoint:[oldLayer.get() anchorPoint]]; [m_layer.get() setOpaque:[oldLayer.get() isOpaque]]; [m_layer.get() setOpacity:[oldLayer.get() opacity]]; [m_layer.get() setTransform:[oldLayer.get() transform]]; [m_layer.get() setSublayerTransform:[oldLayer.get() sublayerTransform]]; [m_layer.get() setDoubleSided:[oldLayer.get() isDoubleSided]];#ifndef NDEBUG [m_layer.get() setZPosition:[oldLayer.get() zPosition]];#endif #ifndef NDEBUG String name = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + m_name; [m_layer.get() setName:name];#endif // move over animations moveAnimation(AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get()); moveAnimation(AnimatedPropertyOpacity, oldLayer.get(), m_layer.get()); moveAnimation(AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get()); // need to tell new layer to draw itself setNeedsDisplay(); END_BLOCK_OBJC_EXCEPTIONS m_usingTiledLayer = userTiledLayer; #ifndef NDEBUG updateDebugIndicators();#endif}void GraphicsLayerCA::setHasContentsLayer(bool hasLayer){ BEGIN_BLOCK_OBJC_EXCEPTIONS if (hasLayer && !m_contentsLayer) { // create the inner layer WebLayer* contentsLayer = [WebLayer layer];#ifndef NDEBUG [contentsLayer setName:@"Contents Layer"];#endif setContentsLayer(contentsLayer); } else if (!hasLayer && m_contentsLayer) setContentsLayer(0); END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setContentsLayer(WebLayer* contentsLayer){ if (contentsLayer == m_contentsLayer) return; BEGIN_BLOCK_OBJC_EXCEPTIONS if (m_contentsLayer) { [m_contentsLayer.get() removeFromSuperlayer]; m_contentsLayer = 0; } if (contentsLayer) { // Turn off implicit animations on the inner layer. [contentsLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]]; m_contentsLayer.adoptNS([contentsLayer retain]); [m_contentsLayer.get() setAnchorPoint:CGPointZero]; [m_layer.get() addSublayer:m_contentsLayer.get()]; updateContentsRect(); // Set contents to nil if the layer does not draw its own content. if (m_client && !drawsContent()) [m_layer.get() setContents:nil];#ifndef NDEBUG if (showDebugBorders()) { setLayerBorderColor(m_contentsLayer.get(), Color(0, 0, 128, 180)); [m_contentsLayer.get() setBorderWidth:1.0f]; }#endif }#ifndef NDEBUG updateDebugIndicators();#endif END_BLOCK_OBJC_EXCEPTIONS}} // namespace WebCore#endif // USE(ACCELERATED_COMPOSITING)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -