📄 graphicslayerca.mm
字号:
/* * 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE COMPUTER, INC. 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. */#import "config.h"#if USE(ACCELERATED_COMPOSITING)#import "GraphicsLayerCA.h"#import "Animation.h"#import "BlockExceptions.h"#import "CString.h"#import "FloatConversion.h"#import "FloatRect.h"#import "Image.h"#import "PlatformString.h"#import <QuartzCore/QuartzCore.h>#import "RotateTransformOperation.h"#import "ScaleTransformOperation.h"#import "SystemTime.h"#import "TranslateTransformOperation.h"#import "WebLayer.h"#import "WebTiledLayer.h"#import <wtf/CurrentTime.h>#import <wtf/UnusedParam.h>using namespace std;#define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))namespace WebCore {// The threshold width or height above which a tiled layer will be used. This should be// large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL// texture size limit on all supported hardware.static const int cMaxPixelDimension = 2000;// The width and height of a single tile in a tiled layer. Should be large enough to// avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough// to keep the overall tile cost low.static const int cTiledLayerTileSize = 512;// If we send a duration of 0 to CA, then it will use the default duration// of 250ms. So send a very small value instead.static const float cAnimationAlmostZeroDuration = 1e-3f;// CACurrentMediaTime() is a time since boot. These methods convert between that and// WebCore time, which is system time (UTC).static CFTimeInterval currentTimeToMediaTime(double t){ return CACurrentMediaTime() + t - WTF::currentTime();}static double mediaTimeToCurrentTime(CFTimeInterval t){ return WTF::currentTime() + t - CACurrentMediaTime();}} // namespace WebCorestatic NSString* const WebAnimationCSSPropertyKey = @"GraphicsLayerCA_property";@interface WebAnimationDelegate : NSObject { WebCore::GraphicsLayerCA* m_graphicsLayer;}- (void)animationDidStart:(CAAnimation *)anim;- (WebCore::GraphicsLayerCA*)graphicsLayer;- (void)setLayer:(WebCore::GraphicsLayerCA*)graphicsLayer;@end@implementation WebAnimationDelegate- (void)animationDidStart:(CAAnimation *)animation{ if (!m_graphicsLayer) return; double startTime = WebCore::mediaTimeToCurrentTime([animation beginTime]); m_graphicsLayer->client()->notifyAnimationStarted(m_graphicsLayer, startTime);}- (WebCore::GraphicsLayerCA*)graphicsLayer{ return m_graphicsLayer;}- (void)setLayer:(WebCore::GraphicsLayerCA*)graphicsLayer{ m_graphicsLayer = graphicsLayer;}@endnamespace WebCore {static inline void copyTransform(CATransform3D& toT3D, const TransformationMatrix& t){ toT3D.m11 = narrowPrecisionToFloat(t.m11()); toT3D.m12 = narrowPrecisionToFloat(t.m12()); toT3D.m13 = narrowPrecisionToFloat(t.m13()); toT3D.m14 = narrowPrecisionToFloat(t.m14()); toT3D.m21 = narrowPrecisionToFloat(t.m21()); toT3D.m22 = narrowPrecisionToFloat(t.m22()); toT3D.m23 = narrowPrecisionToFloat(t.m23()); toT3D.m24 = narrowPrecisionToFloat(t.m24()); toT3D.m31 = narrowPrecisionToFloat(t.m31()); toT3D.m32 = narrowPrecisionToFloat(t.m32()); toT3D.m33 = narrowPrecisionToFloat(t.m33()); toT3D.m34 = narrowPrecisionToFloat(t.m34()); toT3D.m41 = narrowPrecisionToFloat(t.m41()); toT3D.m42 = narrowPrecisionToFloat(t.m42()); toT3D.m43 = narrowPrecisionToFloat(t.m43()); toT3D.m44 = narrowPrecisionToFloat(t.m44());}static NSValue* getTransformFunctionValue(const GraphicsLayer::TransformValue& transformValue, size_t index, const IntSize& size, TransformOperation::OperationType transformType){ TransformOperation* op = (index >= transformValue.value()->operations().size()) ? 0 : transformValue.value()->operations()[index].get(); switch (transformType) { case TransformOperation::ROTATE: case TransformOperation::ROTATE_X: case TransformOperation::ROTATE_Y: return [NSNumber numberWithDouble:op ? deg2rad(static_cast<RotateTransformOperation*>(op)->angle()) : 0]; case TransformOperation::SCALE_X: return [NSNumber numberWithDouble:op ? static_cast<ScaleTransformOperation*>(op)->x() : 0]; case TransformOperation::SCALE_Y: return [NSNumber numberWithDouble:op ? static_cast<ScaleTransformOperation*>(op)->y() : 0]; case TransformOperation::SCALE_Z: return [NSNumber numberWithDouble:op ? static_cast<ScaleTransformOperation*>(op)->z() : 0]; case TransformOperation::TRANSLATE_X: return [NSNumber numberWithDouble:op ? static_cast<TranslateTransformOperation*>(op)->x(size) : 0]; case TransformOperation::TRANSLATE_Y: return [NSNumber numberWithDouble:op ? static_cast<TranslateTransformOperation*>(op)->y(size) : 0]; case TransformOperation::TRANSLATE_Z: return [NSNumber numberWithDouble:op ? static_cast<TranslateTransformOperation*>(op)->z(size) : 0]; case TransformOperation::SCALE: case TransformOperation::TRANSLATE: case TransformOperation::SKEW_X: case TransformOperation::SKEW_Y: case TransformOperation::SKEW: case TransformOperation::MATRIX: case TransformOperation::SCALE_3D: case TransformOperation::TRANSLATE_3D: case TransformOperation::ROTATE_3D: case TransformOperation::MATRIX_3D: case TransformOperation::PERSPECTIVE: case TransformOperation::IDENTITY: case TransformOperation::NONE: { TransformationMatrix t; if (op) op->apply(t, size); CATransform3D cat; copyTransform(cat, t); return [NSValue valueWithCATransform3D:cat]; } } return 0;}#if HAVE_MODERN_QUARTZCOREstatic NSString* getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType){ // Use literal strings to avoid link-time dependency on those symbols. switch (transformType) { case TransformOperation::ROTATE_X: return @"rotateX"; // kCAValueFunctionRotateX; case TransformOperation::ROTATE_Y: return @"rotateY"; // kCAValueFunctionRotateY; case TransformOperation::ROTATE: return @"rotateZ"; // kCAValueFunctionRotateZ; case TransformOperation::SCALE_X: return @"scaleX"; // kCAValueFunctionScaleX; case TransformOperation::SCALE_Y: return @"scaleY"; // kCAValueFunctionScaleY; case TransformOperation::SCALE_Z: return @"scaleZ"; // kCAValueFunctionScaleZ; case TransformOperation::TRANSLATE_X: return @"translateX"; // kCAValueFunctionTranslateX; case TransformOperation::TRANSLATE_Y: return @"translateY"; // kCAValueFunctionTranslateY; case TransformOperation::TRANSLATE_Z: return @"translateZ"; // kCAValueFunctionTranslateZ; default: return nil; }}#endifstatic CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction& timingFunction){ switch (timingFunction.type()) { case LinearTimingFunction: return [CAMediaTimingFunction functionWithName:@"linear"]; case CubicBezierTimingFunction: return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(timingFunction.x1()) :static_cast<float>(timingFunction.y1()) :static_cast<float>(timingFunction.x2()) :static_cast<float>(timingFunction.y2())]; } return 0;}#ifndef NDEBUGstatic void setLayerBorderColor(PlatformLayer* layer, const Color& color){ CGColorRef borderColor = createCGColor(color); [layer setBorderColor:borderColor]; CGColorRelease(borderColor);}static void clearBorderColor(PlatformLayer* layer){ [layer setBorderColor:nil];}#endifstatic void setLayerBackgroundColor(PlatformLayer* layer, const Color& color){ CGColorRef bgColor = createCGColor(color); [layer setBackgroundColor:bgColor]; CGColorRelease(bgColor);}static void clearLayerBackgroundColor(PlatformLayer* layer){ [layer setBackgroundColor:0];}static CALayer* getPresentationLayer(CALayer* layer){ CALayer* presLayer = [layer presentationLayer]; if (!presLayer) presLayer = layer; return presLayer;}static bool caValueFunctionSupported(){ static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)]; return sHaveValueFunction;}static bool forceSoftwareAnimation(){ static bool forceSoftwareAnimation = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreForceSoftwareAnimation"]; return forceSoftwareAnimation;}bool GraphicsLayer::graphicsContextsFlipped(){ return true;}#ifndef NDEBUGbool GraphicsLayer::showDebugBorders(){ static bool showDebugBorders = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreLayerBorders"]; return showDebugBorders;}bool GraphicsLayer::showRepaintCounter(){ static bool showRepaintCounter = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreLayerRepaintCounter"]; return showRepaintCounter;}#endifstatic NSDictionary* nullActionsDictionary(){ NSNull* nullValue = [NSNull null]; NSDictionary* actions = [NSDictionary dictionaryWithObjectsAndKeys: nullValue, @"anchorPoint", nullValue, @"bounds", nullValue, @"contents", nullValue, @"contentsRect", nullValue, @"opacity", nullValue, @"position", nullValue, @"shadowColor", nullValue, @"sublayerTransform", nullValue, @"sublayers", nullValue, @"transform",#ifndef NDEBUG nullValue, @"zPosition",#endif nil]; return actions;}GraphicsLayer* GraphicsLayer::createGraphicsLayer(GraphicsLayerClient* client){ return new GraphicsLayerCA(client);}GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client): GraphicsLayer(client), m_contentLayerForImageOrVideo(false){ BEGIN_BLOCK_OBJC_EXCEPTIONS m_layer.adoptNS([[WebLayer alloc] init]); [m_layer.get() setLayerOwner:this];#ifndef NDEBUG updateDebugIndicators();#endif m_animationDelegate.adoptNS([[WebAnimationDelegate alloc] init]); [m_animationDelegate.get() setLayer:this]; END_BLOCK_OBJC_EXCEPTIONS}GraphicsLayerCA::~GraphicsLayerCA(){ // Remove a inner layer if there is one. clearContents(); BEGIN_BLOCK_OBJC_EXCEPTIONS // Clean up the WK layer. if (m_layer) { WebLayer* layer = m_layer.get(); [layer setLayerOwner:nil]; [layer removeFromSuperlayer]; } if (m_transformLayer) [m_transformLayer.get() removeFromSuperlayer]; // animationDidStart: can fire after this, so we need to clear out the layer on the delegate. [m_animationDelegate.get() setLayer:0]; END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::setName(const String& name){ String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name; GraphicsLayer::setName(longName); BEGIN_BLOCK_OBJC_EXCEPTIONS [m_layer.get() setName:name]; END_BLOCK_OBJC_EXCEPTIONS}NativeLayer GraphicsLayerCA::nativeLayer() const{ return m_layer.get();}void GraphicsLayerCA::addChild(GraphicsLayer* childLayer){ GraphicsLayer::addChild(childLayer); GraphicsLayerCA* childLayerCA = static_cast<GraphicsLayerCA*>(childLayer); BEGIN_BLOCK_OBJC_EXCEPTIONS [hostLayerForSublayers() addSublayer:childLayerCA->layerForSuperlayer()]; END_BLOCK_OBJC_EXCEPTIONS}void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index){ GraphicsLayer::addChildAtIndex(childLayer, index);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -