From 87297a0722a3bd2d3c830dc9eec3c0812a1edcd8 Mon Sep 17 00:00:00 2001 From: jiasong <593908937@qq.com> Date: Wed, 28 Jan 2026 11:03:46 +0800 Subject: [PATCH 1/6] =?UTF-8?q?set=20dar=E3=80=81scale=E3=80=81rotate=20pr?= =?UTF-8?q?eference=EF=BC=8C=E7=94=B1=E5=A4=96=E9=83=A8=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=8A=A8=E7=94=BB=EF=BC=8ConRecord=E5=8F=AF=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FSMoviePlayerViewController.m | 11 ++++- ijkmedia/ijksdl/metal/FSMetalView.m | 44 +++---------------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/examples/ios/FSPlayerDemo/ViewController/FSMoviePlayerViewController.m b/examples/ios/FSPlayerDemo/ViewController/FSMoviePlayerViewController.m index 85dd1657..aa2cfe0b 100644 --- a/examples/ios/FSPlayerDemo/ViewController/FSMoviePlayerViewController.m +++ b/examples/ios/FSPlayerDemo/ViewController/FSMoviePlayerViewController.m @@ -316,7 +316,7 @@ - (void)saveToPhotosAlbum - (IBAction)onRecord:(UIButton *)sender { -// test dar + // test dar // int dar_num = 0; // int dar_den = 1; // @@ -327,6 +327,15 @@ - (IBAction)onRecord:(UIButton *)sender // } else { // self.player.view.darPreference = (FSDARPreference){0.0}; // } +// [UIView animateWithDuration:0.75 delay:0 usingSpringWithDamping:0.45 initialSpringVelocity:1.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{ +// [self.view setNeedsLayout]; +// [self.view layoutIfNeeded]; +// // 或者 +// // [self.player.view setNeedsLayout]; +// // [self.player.view layoutIfNeeded]; +// } completion:^(BOOL finished) { +// +// }]; // return; if (sender.isSelected) { diff --git a/ijkmedia/ijksdl/metal/FSMetalView.m b/ijkmedia/ijksdl/metal/FSMetalView.m index c9c935f0..4ea84de2 100644 --- a/ijkmedia/ijksdl/metal/FSMetalView.m +++ b/ijkmedia/ijksdl/metal/FSMetalView.m @@ -39,7 +39,6 @@ @interface FSMetalView () @property (atomic, assign) int attachSarNum; @property (atomic, assign) int attachSarDen; @property (atomic, assign) int attachAutoZRotate; -@property (atomic, assign) BOOL animating; @end @@ -74,9 +73,7 @@ - (void)prepare { #if TARGET_OS_OSX - (void)layout { [super layout]; - if (!self.animating) { - [self updateRenderedViewFrameWithAnimate:NO]; - } + [self updateRenderedViewFrame]; } #else @@ -89,14 +86,11 @@ - (void)layout { //frame #6: 0x000000018436f9a8 QuartzCore`CA::Transaction::flush_as_runloop_observer(bool) + 84 - (void)layoutSubviews { [super layoutSubviews]; - //ignore animate caused layoutSubviews - if (!self.animating) { - [self updateRenderedViewFrameWithAnimate:NO]; - } + [self updateRenderedViewFrame]; } #endif -- (void)updateRenderedViewFrameWithAnimate:(BOOL)animate { +- (void)updateRenderedViewFrame { if (self.scalingMode == FSScalingModeFill) { self.renderedView.frame = self.bounds; } else { @@ -155,31 +149,7 @@ - (void)updateRenderedViewFrameWithAnimate:(BOOL)animate { attachSize.height * ratio); CGPoint origin = CGPointMake(CGRectGetMidX(self.bounds) - size.width / 2, CGRectGetMidY(self.bounds) - size.height / 2); - - if (animate) { - self.animating = YES; - [self setNeedsRefreshCurrentPic]; -#if TARGET_OS_OSX - [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { - context.duration = 0.3; - context.allowsImplicitAnimation = YES; - context.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; - self.renderedView.animator.frame = CGRectMake(origin.x, origin.y, size.width, size.height); - } completionHandler:^{ - self.animating = NO; - [self setNeedsRefreshCurrentPic]; - }]; -#else - [UIView animateWithDuration:0.3 animations:^{ - self.renderedView.frame = CGRectMake(origin.x, origin.y, size.width, size.height); - } completion:^(BOOL finished) { - self.animating = NO; - [self setNeedsRefreshCurrentPic]; - }]; -#endif - } else { - self.renderedView.frame = CGRectMake(origin.x, origin.y, size.width, size.height); - } + self.renderedView.frame = CGRectMake(origin.x, origin.y, size.width, size.height); } else { self.renderedView.frame = CGRectZero; } @@ -214,7 +184,7 @@ - (void)setDisplayDelegate:(id)displayDelegate { - (void)setScalingMode:(FSScalingMode)scalingMode { if (self.renderedView.scalingMode != scalingMode) { self.renderedView.scalingMode = scalingMode; - [self updateRenderedViewFrameWithAnimate:YES]; + [self makeNeedsLayout]; } } @@ -235,7 +205,7 @@ - (CGFloat)scaleFactor { - (void)setRotatePreference:(FSRotatePreference)rotatePreference { if (self.renderedView.rotatePreference.type != rotatePreference.type || self.renderedView.rotatePreference.degrees != rotatePreference.degrees) { self.renderedView.rotatePreference = rotatePreference; - [self updateRenderedViewFrameWithAnimate:YES]; + [self makeNeedsLayout]; } } @@ -257,7 +227,7 @@ - (FSColorConvertPreference)colorPreference { - (void)setDarPreference:(FSDARPreference)darPreference { if (self.renderedView.darPreference.ratio != darPreference.ratio) { self.renderedView.darPreference = darPreference; - [self updateRenderedViewFrameWithAnimate:YES]; + [self makeNeedsLayout]; } } From f45ebc5c42967931a64f13f67a246f783c19164b Mon Sep 17 00:00:00 2001 From: jiasong <593908937@qq.com> Date: Wed, 28 Jan 2026 11:28:11 +0800 Subject: [PATCH 2/6] fix --- ijkmedia/ijksdl/metal/FSMetalView.m | 1 + 1 file changed, 1 insertion(+) diff --git a/ijkmedia/ijksdl/metal/FSMetalView.m b/ijkmedia/ijksdl/metal/FSMetalView.m index 4ea84de2..6e2dcc7c 100644 --- a/ijkmedia/ijksdl/metal/FSMetalView.m +++ b/ijkmedia/ijksdl/metal/FSMetalView.m @@ -228,6 +228,7 @@ - (void)setDarPreference:(FSDARPreference)darPreference { if (self.renderedView.darPreference.ratio != darPreference.ratio) { self.renderedView.darPreference = darPreference; [self makeNeedsLayout]; + [self setNeedsRefreshCurrentPic]; } } From 64dde7bb223c41c7a68bb01d317ad3daca22b235 Mon Sep 17 00:00:00 2001 From: jiasong <593908937@qq.com> Date: Wed, 28 Jan 2026 14:46:34 +0800 Subject: [PATCH 3/6] [self setNeedsRefreshCurrentPic]; --- .../FSPlayerDemo.xcodeproj/project.pbxproj | 4 +-- .../FSPlayerMacDemo.xcodeproj/project.pbxproj | 26 +++++++++++++++++-- ijkmedia/ijksdl/metal/FSMetalView.m | 2 ++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj b/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj index 2d329f9c..d557ffeb 100644 --- a/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj +++ b/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj @@ -484,7 +484,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 96C96H28CU; + DEVELOPMENT_TEAM = KJ6AEY5JEH; ENABLE_BITCODE = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -520,7 +520,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 96C96H28CU; + DEVELOPMENT_TEAM = KJ6AEY5JEH; ENABLE_BITCODE = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; diff --git a/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj b/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj index 2d718b15..e62d3042 100644 --- a/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj +++ b/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj @@ -694,8 +694,19 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 96C96H28CU; + DEVELOPMENT_TEAM = KJ6AEY5JEH; + ENABLE_APP_SANDBOX = YES; ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = FSPlayerMacDemo/PrefixHeader.pch; INFOPLIST_FILE = FSPlayerMacDemo/Info.plist; @@ -722,8 +733,19 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 96C96H28CU; + DEVELOPMENT_TEAM = KJ6AEY5JEH; + ENABLE_APP_SANDBOX = YES; ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = FSPlayerMacDemo/PrefixHeader.pch; INFOPLIST_FILE = FSPlayerMacDemo/Info.plist; diff --git a/ijkmedia/ijksdl/metal/FSMetalView.m b/ijkmedia/ijksdl/metal/FSMetalView.m index 6e2dcc7c..c787c25f 100644 --- a/ijkmedia/ijksdl/metal/FSMetalView.m +++ b/ijkmedia/ijksdl/metal/FSMetalView.m @@ -185,6 +185,7 @@ - (void)setScalingMode:(FSScalingMode)scalingMode { if (self.renderedView.scalingMode != scalingMode) { self.renderedView.scalingMode = scalingMode; [self makeNeedsLayout]; + [self setNeedsRefreshCurrentPic]; } } @@ -206,6 +207,7 @@ - (void)setRotatePreference:(FSRotatePreference)rotatePreference { if (self.renderedView.rotatePreference.type != rotatePreference.type || self.renderedView.rotatePreference.degrees != rotatePreference.degrees) { self.renderedView.rotatePreference = rotatePreference; [self makeNeedsLayout]; + [self setNeedsRefreshCurrentPic]; } } From b446cc5d6c437af8ce2a9693c53635720f281866 Mon Sep 17 00:00:00 2001 From: jiasong <593908937@qq.com> Date: Wed, 28 Jan 2026 15:31:58 +0800 Subject: [PATCH 4/6] Revert "[self setNeedsRefreshCurrentPic];" This reverts commit 64dde7bb223c41c7a68bb01d317ad3daca22b235. --- .../FSPlayerDemo.xcodeproj/project.pbxproj | 4 +-- .../FSPlayerMacDemo.xcodeproj/project.pbxproj | 26 ++----------------- ijkmedia/ijksdl/metal/FSMetalView.m | 2 -- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj b/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj index d557ffeb..2d329f9c 100644 --- a/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj +++ b/examples/ios/FSPlayerDemo.xcodeproj/project.pbxproj @@ -484,7 +484,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = KJ6AEY5JEH; + DEVELOPMENT_TEAM = 96C96H28CU; ENABLE_BITCODE = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -520,7 +520,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = KJ6AEY5JEH; + DEVELOPMENT_TEAM = 96C96H28CU; ENABLE_BITCODE = NO; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; diff --git a/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj b/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj index e62d3042..2d718b15 100644 --- a/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj +++ b/examples/macos/FSPlayerMacDemo.xcodeproj/project.pbxproj @@ -694,19 +694,8 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = KJ6AEY5JEH; - ENABLE_APP_SANDBOX = YES; + DEVELOPMENT_TEAM = 96C96H28CU; ENABLE_HARDENED_RUNTIME = YES; - ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; - ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO; - ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; - ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; - ENABLE_RESOURCE_ACCESS_CALENDARS = NO; - ENABLE_RESOURCE_ACCESS_CAMERA = NO; - ENABLE_RESOURCE_ACCESS_CONTACTS = NO; - ENABLE_RESOURCE_ACCESS_LOCATION = NO; - ENABLE_RESOURCE_ACCESS_PRINTING = NO; - ENABLE_RESOURCE_ACCESS_USB = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = FSPlayerMacDemo/PrefixHeader.pch; INFOPLIST_FILE = FSPlayerMacDemo/Info.plist; @@ -733,19 +722,8 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = KJ6AEY5JEH; - ENABLE_APP_SANDBOX = YES; + DEVELOPMENT_TEAM = 96C96H28CU; ENABLE_HARDENED_RUNTIME = YES; - ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; - ENABLE_OUTGOING_NETWORK_CONNECTIONS = NO; - ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; - ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; - ENABLE_RESOURCE_ACCESS_CALENDARS = NO; - ENABLE_RESOURCE_ACCESS_CAMERA = NO; - ENABLE_RESOURCE_ACCESS_CONTACTS = NO; - ENABLE_RESOURCE_ACCESS_LOCATION = NO; - ENABLE_RESOURCE_ACCESS_PRINTING = NO; - ENABLE_RESOURCE_ACCESS_USB = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = FSPlayerMacDemo/PrefixHeader.pch; INFOPLIST_FILE = FSPlayerMacDemo/Info.plist; diff --git a/ijkmedia/ijksdl/metal/FSMetalView.m b/ijkmedia/ijksdl/metal/FSMetalView.m index c787c25f..6e2dcc7c 100644 --- a/ijkmedia/ijksdl/metal/FSMetalView.m +++ b/ijkmedia/ijksdl/metal/FSMetalView.m @@ -185,7 +185,6 @@ - (void)setScalingMode:(FSScalingMode)scalingMode { if (self.renderedView.scalingMode != scalingMode) { self.renderedView.scalingMode = scalingMode; [self makeNeedsLayout]; - [self setNeedsRefreshCurrentPic]; } } @@ -207,7 +206,6 @@ - (void)setRotatePreference:(FSRotatePreference)rotatePreference { if (self.renderedView.rotatePreference.type != rotatePreference.type || self.renderedView.rotatePreference.degrees != rotatePreference.degrees) { self.renderedView.rotatePreference = rotatePreference; [self makeNeedsLayout]; - [self setNeedsRefreshCurrentPic]; } } From 915bb47fdb9b457cba42aa7dde1c82f56f8e9fb6 Mon Sep 17 00:00:00 2001 From: jiasong <593908937@qq.com> Date: Wed, 28 Jan 2026 15:33:13 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E8=AE=BE=E7=BD=AEscalingMode/rotatePrefere?= =?UTF-8?q?nce=E4=B9=9F=E6=A0=87=E8=AE=B0=E4=B8=8BsetNeedsRefreshCurrentPi?= =?UTF-8?q?c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ijkmedia/ijksdl/metal/FSMetalView.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ijkmedia/ijksdl/metal/FSMetalView.m b/ijkmedia/ijksdl/metal/FSMetalView.m index 6e2dcc7c..c787c25f 100644 --- a/ijkmedia/ijksdl/metal/FSMetalView.m +++ b/ijkmedia/ijksdl/metal/FSMetalView.m @@ -185,6 +185,7 @@ - (void)setScalingMode:(FSScalingMode)scalingMode { if (self.renderedView.scalingMode != scalingMode) { self.renderedView.scalingMode = scalingMode; [self makeNeedsLayout]; + [self setNeedsRefreshCurrentPic]; } } @@ -206,6 +207,7 @@ - (void)setRotatePreference:(FSRotatePreference)rotatePreference { if (self.renderedView.rotatePreference.type != rotatePreference.type || self.renderedView.rotatePreference.degrees != rotatePreference.degrees) { self.renderedView.rotatePreference = rotatePreference; [self makeNeedsLayout]; + [self setNeedsRefreshCurrentPic]; } } From 63fe0c09042572420489fff26e850ffc6ac4da1e Mon Sep 17 00:00:00 2001 From: jiasong <593908937@qq.com> Date: Wed, 28 Jan 2026 17:45:35 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8DmacOS=E4=B8=8ArunAnimatio?= =?UTF-8?q?nGroup=E5=8F=AF=E8=83=BD=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewController/MRRootViewController.m | 22 ++++++++ ijkmedia/ijksdl/metal/FSMetalView.m | 52 +++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/examples/macos/FSPlayerMacDemo/ViewController/MRRootViewController.m b/examples/macos/FSPlayerMacDemo/ViewController/MRRootViewController.m index 7b21326e..2b27023e 100644 --- a/examples/macos/FSPlayerMacDemo/ViewController/MRRootViewController.m +++ b/examples/macos/FSPlayerMacDemo/ViewController/MRRootViewController.m @@ -1752,6 +1752,17 @@ - (void)observerCocoaBingsChange __strongSelf__ int value = [v intValue]; [self.player setScalingMode:value]; + + [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { + __strongSelf__ + context.duration = 0.3; + context.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + context.allowsImplicitAnimation = YES; + [self.view setNeedsLayout:YES]; + [self.view layoutSubtreeIfNeeded]; + } completionHandler:^{ + + }]; } forKey:@"picture_fill_mode"]; [[MRCocoaBindingUserDefault sharedDefault] onChange:^(id _Nonnull v, BOOL * _Nonnull r) { @@ -1762,6 +1773,17 @@ - (void)observerCocoaBingsChange [[MRCocoaBindingUserDefault sharedDefault] onChange:^(id _Nonnull v, BOOL * _Nonnull r) { __strongSelf__ [self applyRotate]; + + [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { + __strongSelf__ + context.duration = 0.3; + context.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + context.allowsImplicitAnimation = YES; + [self.view setNeedsLayout:YES]; + [self.view layoutSubtreeIfNeeded]; + } completionHandler:^{ + + }]; } forKey:@"picture_ratate_mode"]; [[MRCocoaBindingUserDefault sharedDefault] onChange:^(id _Nonnull v, BOOL * _Nonnull r) { diff --git a/ijkmedia/ijksdl/metal/FSMetalView.m b/ijkmedia/ijksdl/metal/FSMetalView.m index c787c25f..06e4e3e8 100644 --- a/ijkmedia/ijksdl/metal/FSMetalView.m +++ b/ijkmedia/ijksdl/metal/FSMetalView.m @@ -26,6 +26,49 @@ typedef CGRect NSRect; #endif +typedef NS_ENUM(NSInteger, FSMetalDecimalRoundingRule) { + FSMetalDecimalRoundingRuleRound, + FSMetalDecimalRoundingRuleCeil, + FSMetalDecimalRoundingRuleFloor, +}; + +CG_INLINE CGFloat +__FSMetalCGFloatMakePixelValue(CGFloat value, FSMetalDecimalRoundingRule rule) { + /// 以下算法是由「yoga -> YGPixelGrid.h -> YGRoundValueToPixelGrid」中翻译 + + BOOL(^inexactEquals)(CGFloat, CGFloat) = ^BOOL(CGFloat a, CGFloat b) { + if (!isnan(a) && !isnan(b)) { + return ABS(a - b) < 0.0001; + } + return isnan(a) && isnan(b); + }; + +#if TARGET_OS_IPHONE + CGFloat pointScaleFactor = MAX(UIScreen.mainScreen.traitCollection.displayScale, 1); +#else + CGFloat pointScaleFactor = MAX(NSScreen.mainScreen.backingScaleFactor, 1); +#endif + CGFloat scaledValue = value * pointScaleFactor; + CGFloat fractial = fmod(scaledValue, 1.0); + if (fractial < 0) { + ++fractial; + } + if (inexactEquals(fractial, 0)) { + scaledValue = scaledValue - fractial; + } else if (inexactEquals(fractial, 1.0)) { + scaledValue = scaledValue - fractial + 1.0; + } else if (rule == FSMetalDecimalRoundingRuleCeil) { + scaledValue = scaledValue - fractial + 1.0; + } else if (rule == FSMetalDecimalRoundingRuleFloor) { + scaledValue = scaledValue - fractial; + } else if (rule == FSMetalDecimalRoundingRuleRound) { + scaledValue = scaledValue - fractial + (!isnan(fractial) && (fractial > 0.5 || inexactEquals(fractial, 0.5)) ? 1.0 : 0.0); + } else { + NSCAssert(NO, @""); + } + return isnan(scaledValue) ? 0 : (scaledValue / pointScaleFactor); +} + NS_CLASS_AVAILABLE(10_13, 11_0) @interface FSMetalRenderedView: MTKView @@ -149,6 +192,11 @@ - (void)updateRenderedViewFrame { attachSize.height * ratio); CGPoint origin = CGPointMake(CGRectGetMidX(self.bounds) - size.width / 2, CGRectGetMidY(self.bounds) - size.height / 2); +#if TARGET_OS_OSX + // 需进行像素对齐,解决外部使用runAnimationGroup可能不会生效的问题 + origin.x = __FSMetalCGFloatMakePixelValue(origin.x, FSMetalDecimalRoundingRuleRound); + origin.y = __FSMetalCGFloatMakePixelValue(origin.y, FSMetalDecimalRoundingRuleRound); +#endif self.renderedView.frame = CGRectMake(origin.x, origin.y, size.width, size.height); } else { self.renderedView.frame = CGRectZero; @@ -159,7 +207,7 @@ - (void)updateRenderedViewFrame { - (void)makeNeedsLayout { void(^setNeedsLayout)(void) = ^{ #if TARGET_OS_OSX - self.needsLayout = YES; + [self setNeedsLayout:YES]; #else [self setNeedsLayout]; #endif @@ -185,7 +233,6 @@ - (void)setScalingMode:(FSScalingMode)scalingMode { if (self.renderedView.scalingMode != scalingMode) { self.renderedView.scalingMode = scalingMode; [self makeNeedsLayout]; - [self setNeedsRefreshCurrentPic]; } } @@ -230,7 +277,6 @@ - (void)setDarPreference:(FSDARPreference)darPreference { if (self.renderedView.darPreference.ratio != darPreference.ratio) { self.renderedView.darPreference = darPreference; [self makeNeedsLayout]; - [self setNeedsRefreshCurrentPic]; } }