mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-26 18:13:14 +00:00
Background portal views
This commit is contained in:
parent
48cb7f25ec
commit
11409151df
@ -90,7 +90,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
case experimentalCompatibility(Bool)
|
case experimentalCompatibility(Bool)
|
||||||
case enableDebugDataDisplay(Bool)
|
case enableDebugDataDisplay(Bool)
|
||||||
case acceleratedStickers(Bool)
|
case acceleratedStickers(Bool)
|
||||||
case experimentalBackground(Bool)
|
|
||||||
case inlineForums(Bool)
|
case inlineForums(Bool)
|
||||||
case localTranscription(Bool)
|
case localTranscription(Bool)
|
||||||
case enableReactionOverrides(Bool)
|
case enableReactionOverrides(Bool)
|
||||||
@ -117,7 +116,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
return DebugControllerSection.logging.rawValue
|
return DebugControllerSection.logging.rawValue
|
||||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||||
return DebugControllerSection.experiments.rawValue
|
return DebugControllerSection.experiments.rawValue
|
||||||
case .clearTips, .resetTranslationStates, .resetNotifications, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .enableQuickReactionSwitch, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .experimentalBackground, .inlineForums, .localTranscription, . enableReactionOverrides, .restorePurchases:
|
case .clearTips, .resetTranslationStates, .resetNotifications, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .enableQuickReactionSwitch, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .inlineForums, .localTranscription, . enableReactionOverrides, .restorePurchases:
|
||||||
return DebugControllerSection.experiments.rawValue
|
return DebugControllerSection.experiments.rawValue
|
||||||
case .preferredVideoCodec:
|
case .preferredVideoCodec:
|
||||||
return DebugControllerSection.videoExperiments.rawValue
|
return DebugControllerSection.videoExperiments.rawValue
|
||||||
@ -202,8 +201,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
return 34
|
return 34
|
||||||
case .acceleratedStickers:
|
case .acceleratedStickers:
|
||||||
return 35
|
return 35
|
||||||
case .experimentalBackground:
|
|
||||||
return 36
|
|
||||||
case .inlineForums:
|
case .inlineForums:
|
||||||
return 37
|
return 37
|
||||||
case .localTranscription:
|
case .localTranscription:
|
||||||
@ -1181,16 +1178,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
})
|
})
|
||||||
}).start()
|
}).start()
|
||||||
})
|
})
|
||||||
case let .experimentalBackground(value):
|
|
||||||
return ItemListSwitchItem(presentationData: presentationData, title: "Background Experiment", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
|
||||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
|
||||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
|
||||||
var settings = settings?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
|
|
||||||
settings.experimentalBackground = value
|
|
||||||
return PreferencesEntry(settings)
|
|
||||||
})
|
|
||||||
}).start()
|
|
||||||
})
|
|
||||||
case let .inlineForums(value):
|
case let .inlineForums(value):
|
||||||
return ItemListSwitchItem(presentationData: presentationData, title: "Inline Forums", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
return ItemListSwitchItem(presentationData: presentationData, title: "Inline Forums", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||||
@ -1371,7 +1358,6 @@ private func debugControllerEntries(sharedContext: SharedAccountContext, present
|
|||||||
entries.append(.experimentalCompatibility(experimentalSettings.experimentalCompatibility))
|
entries.append(.experimentalCompatibility(experimentalSettings.experimentalCompatibility))
|
||||||
entries.append(.enableDebugDataDisplay(experimentalSettings.enableDebugDataDisplay))
|
entries.append(.enableDebugDataDisplay(experimentalSettings.enableDebugDataDisplay))
|
||||||
entries.append(.acceleratedStickers(experimentalSettings.acceleratedStickers))
|
entries.append(.acceleratedStickers(experimentalSettings.acceleratedStickers))
|
||||||
entries.append(.experimentalBackground(experimentalSettings.experimentalBackground))
|
|
||||||
entries.append(.inlineForums(experimentalSettings.inlineForums))
|
entries.append(.inlineForums(experimentalSettings.inlineForums))
|
||||||
entries.append(.localTranscription(experimentalSettings.localTranscription))
|
entries.append(.localTranscription(experimentalSettings.localTranscription))
|
||||||
if case .internal = sharedContext.applicationBindings.appBuildType {
|
if case .internal = sharedContext.applicationBindings.appBuildType {
|
||||||
|
|||||||
@ -523,7 +523,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI
|
|||||||
self.context = context
|
self.context = context
|
||||||
self.persistentItems = persistentItems
|
self.persistentItems = persistentItems
|
||||||
|
|
||||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false, useExperimentalImplementation: context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false)
|
||||||
self.wallpaperBackgroundNode.backgroundColor = .black
|
self.wallpaperBackgroundNode.backgroundColor = .black
|
||||||
self.scrollNode = ASScrollNode()
|
self.scrollNode = ASScrollNode()
|
||||||
|
|
||||||
|
|||||||
@ -572,7 +572,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: useSharedAnimationPhase, useExperimentalImplementation: self.context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: useSharedAnimationPhase)
|
||||||
self.wallpaperReady.set(self.chatBackgroundNode.isReady)
|
self.wallpaperReady.set(self.chatBackgroundNode.isReady)
|
||||||
|
|
||||||
var locationBroadcastPanelSource: LocationBroadcastPanelSource
|
var locationBroadcastPanelSource: LocationBroadcastPanelSource
|
||||||
|
|||||||
@ -1531,7 +1531,7 @@ private class QrContentNode: ASDisplayNode, ContentNode {
|
|||||||
|
|
||||||
self.containerNode = ASDisplayNode()
|
self.containerNode = ASDisplayNode()
|
||||||
|
|
||||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false, useExperimentalImplementation: context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false)
|
||||||
|
|
||||||
self.codeBackgroundNode = ASDisplayNode()
|
self.codeBackgroundNode = ASDisplayNode()
|
||||||
self.codeBackgroundNode.backgroundColor = .white
|
self.codeBackgroundNode.backgroundColor = .white
|
||||||
@ -2022,7 +2022,7 @@ private class MessageContentNode: ASDisplayNode, ContentNode {
|
|||||||
|
|
||||||
self.containerNode = ASDisplayNode()
|
self.containerNode = ASDisplayNode()
|
||||||
|
|
||||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false, useExperimentalImplementation: context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false)
|
||||||
|
|
||||||
self.backgroundNode = ASDisplayNode()
|
self.backgroundNode = ASDisplayNode()
|
||||||
self.backgroundImageNode = ASImageNode()
|
self.backgroundImageNode = ASImageNode()
|
||||||
|
|||||||
@ -40,7 +40,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||||||
public var experimentalCompatibility: Bool
|
public var experimentalCompatibility: Bool
|
||||||
public var enableDebugDataDisplay: Bool
|
public var enableDebugDataDisplay: Bool
|
||||||
public var acceleratedStickers: Bool
|
public var acceleratedStickers: Bool
|
||||||
public var experimentalBackground: Bool
|
|
||||||
public var inlineStickers: Bool
|
public var inlineStickers: Bool
|
||||||
public var localTranscription: Bool
|
public var localTranscription: Bool
|
||||||
public var enableReactionOverrides: Bool
|
public var enableReactionOverrides: Bool
|
||||||
@ -68,7 +67,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||||||
experimentalCompatibility: false,
|
experimentalCompatibility: false,
|
||||||
enableDebugDataDisplay: false,
|
enableDebugDataDisplay: false,
|
||||||
acceleratedStickers: false,
|
acceleratedStickers: false,
|
||||||
experimentalBackground: false,
|
|
||||||
inlineStickers: false,
|
inlineStickers: false,
|
||||||
localTranscription: false,
|
localTranscription: false,
|
||||||
enableReactionOverrides: false,
|
enableReactionOverrides: false,
|
||||||
@ -97,7 +95,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||||||
experimentalCompatibility: Bool,
|
experimentalCompatibility: Bool,
|
||||||
enableDebugDataDisplay: Bool,
|
enableDebugDataDisplay: Bool,
|
||||||
acceleratedStickers: Bool,
|
acceleratedStickers: Bool,
|
||||||
experimentalBackground: Bool,
|
|
||||||
inlineStickers: Bool,
|
inlineStickers: Bool,
|
||||||
localTranscription: Bool,
|
localTranscription: Bool,
|
||||||
enableReactionOverrides: Bool,
|
enableReactionOverrides: Bool,
|
||||||
@ -123,7 +120,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||||||
self.experimentalCompatibility = experimentalCompatibility
|
self.experimentalCompatibility = experimentalCompatibility
|
||||||
self.enableDebugDataDisplay = enableDebugDataDisplay
|
self.enableDebugDataDisplay = enableDebugDataDisplay
|
||||||
self.acceleratedStickers = acceleratedStickers
|
self.acceleratedStickers = acceleratedStickers
|
||||||
self.experimentalBackground = experimentalBackground
|
|
||||||
self.inlineStickers = inlineStickers
|
self.inlineStickers = inlineStickers
|
||||||
self.localTranscription = localTranscription
|
self.localTranscription = localTranscription
|
||||||
self.enableReactionOverrides = enableReactionOverrides
|
self.enableReactionOverrides = enableReactionOverrides
|
||||||
@ -153,7 +149,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||||||
self.experimentalCompatibility = (try container.decodeIfPresent(Int32.self, forKey: "experimentalCompatibility") ?? 0) != 0
|
self.experimentalCompatibility = (try container.decodeIfPresent(Int32.self, forKey: "experimentalCompatibility") ?? 0) != 0
|
||||||
self.enableDebugDataDisplay = (try container.decodeIfPresent(Int32.self, forKey: "enableDebugDataDisplay") ?? 0) != 0
|
self.enableDebugDataDisplay = (try container.decodeIfPresent(Int32.self, forKey: "enableDebugDataDisplay") ?? 0) != 0
|
||||||
self.acceleratedStickers = (try container.decodeIfPresent(Int32.self, forKey: "acceleratedStickers") ?? 0) != 0
|
self.acceleratedStickers = (try container.decodeIfPresent(Int32.self, forKey: "acceleratedStickers") ?? 0) != 0
|
||||||
self.experimentalBackground = (try container.decodeIfPresent(Int32.self, forKey: "experimentalBackground") ?? 0) != 0
|
|
||||||
self.inlineStickers = (try container.decodeIfPresent(Int32.self, forKey: "inlineStickers") ?? 0) != 0
|
self.inlineStickers = (try container.decodeIfPresent(Int32.self, forKey: "inlineStickers") ?? 0) != 0
|
||||||
self.localTranscription = (try container.decodeIfPresent(Int32.self, forKey: "localTranscription") ?? 0) != 0
|
self.localTranscription = (try container.decodeIfPresent(Int32.self, forKey: "localTranscription") ?? 0) != 0
|
||||||
self.enableReactionOverrides = try container.decodeIfPresent(Bool.self, forKey: "enableReactionOverrides") ?? false
|
self.enableReactionOverrides = try container.decodeIfPresent(Bool.self, forKey: "enableReactionOverrides") ?? false
|
||||||
@ -183,7 +178,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
|||||||
try container.encode((self.experimentalCompatibility ? 1 : 0) as Int32, forKey: "experimentalCompatibility")
|
try container.encode((self.experimentalCompatibility ? 1 : 0) as Int32, forKey: "experimentalCompatibility")
|
||||||
try container.encode((self.enableDebugDataDisplay ? 1 : 0) as Int32, forKey: "enableDebugDataDisplay")
|
try container.encode((self.enableDebugDataDisplay ? 1 : 0) as Int32, forKey: "enableDebugDataDisplay")
|
||||||
try container.encode((self.acceleratedStickers ? 1 : 0) as Int32, forKey: "acceleratedStickers")
|
try container.encode((self.acceleratedStickers ? 1 : 0) as Int32, forKey: "acceleratedStickers")
|
||||||
try container.encode((self.experimentalBackground ? 1 : 0) as Int32, forKey: "experimentalBackground")
|
|
||||||
try container.encode((self.inlineStickers ? 1 : 0) as Int32, forKey: "inlineStickers")
|
try container.encode((self.inlineStickers ? 1 : 0) as Int32, forKey: "inlineStickers")
|
||||||
try container.encode((self.localTranscription ? 1 : 0) as Int32, forKey: "localTranscription")
|
try container.encode((self.localTranscription ? 1 : 0) as Int32, forKey: "localTranscription")
|
||||||
try container.encode(self.enableReactionOverrides, forKey: "enableReactionOverrides")
|
try container.encode(self.enableReactionOverrides, forKey: "enableReactionOverrides")
|
||||||
|
|||||||
@ -1,313 +1 @@
|
|||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
import AsyncDisplayKit
|
|
||||||
import Display
|
|
||||||
import GradientBackground
|
|
||||||
import TelegramPresentationData
|
|
||||||
import TelegramCore
|
|
||||||
import AccountContext
|
|
||||||
import SwiftSignalKit
|
|
||||||
import WallpaperResources
|
|
||||||
import FastBlur
|
|
||||||
import Svg
|
|
||||||
import GZip
|
|
||||||
import AppBundle
|
|
||||||
import AnimatedStickerNode
|
|
||||||
import TelegramAnimatedStickerNode
|
|
||||||
import HierarchyTrackingLayer
|
|
||||||
import MetalKit
|
|
||||||
import HierarchyTrackingLayer
|
|
||||||
import simd
|
|
||||||
|
|
||||||
private final class NullActionClass: NSObject, CAAction {
|
|
||||||
static let shared = NullActionClass()
|
|
||||||
|
|
||||||
@objc public func run(forKey event: String, object anObject: Any, arguments dict: [AnyHashable : Any]?) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
open class SimpleMetalLayer: CAMetalLayer {
|
|
||||||
override open func action(forKey event: String) -> CAAction? {
|
|
||||||
return nullAction
|
|
||||||
}
|
|
||||||
|
|
||||||
override public init() {
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
override public init(layer: Any) {
|
|
||||||
super.init(layer: layer)
|
|
||||||
}
|
|
||||||
|
|
||||||
required public init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func makePipelineState(device: MTLDevice, library: MTLLibrary, vertexProgram: String, fragmentProgram: String) -> MTLRenderPipelineState? {
|
|
||||||
guard let loadedVertexProgram = library.makeFunction(name: vertexProgram) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
guard let loadedFragmentProgram = library.makeFunction(name: fragmentProgram) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
|
|
||||||
pipelineStateDescriptor.vertexFunction = loadedVertexProgram
|
|
||||||
pipelineStateDescriptor.fragmentFunction = loadedFragmentProgram
|
|
||||||
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
|
|
||||||
guard let pipelineState = try? device.makeRenderPipelineState(descriptor: pipelineStateDescriptor) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return pipelineState
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
final class MetalWallpaperBackgroundNode: ASDisplayNode, WallpaperBackgroundNode {
|
|
||||||
private let device: MTLDevice
|
|
||||||
private let metalLayer: SimpleMetalLayer
|
|
||||||
private let commandQueue: MTLCommandQueue
|
|
||||||
private let renderPipelineState: MTLRenderPipelineState
|
|
||||||
|
|
||||||
private let hierarchyTrackingLayer = HierarchyTrackingLayer()
|
|
||||||
|
|
||||||
var isReady: Signal<Bool, NoError> {
|
|
||||||
return .single(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
var rotation: CGFloat = 0.0
|
|
||||||
|
|
||||||
private var animationPhase: Int = 0
|
|
||||||
|
|
||||||
private var animationThread: Thread?
|
|
||||||
private var displayLink: CADisplayLink?
|
|
||||||
|
|
||||||
override init() {
|
|
||||||
self.device = MTLCreateSystemDefaultDevice()!
|
|
||||||
self.metalLayer = SimpleMetalLayer()
|
|
||||||
self.metalLayer.maximumDrawableCount = 3
|
|
||||||
self.metalLayer.presentsWithTransaction = true
|
|
||||||
self.metalLayer.contentsScale = UIScreenScale
|
|
||||||
self.commandQueue = self.device.makeCommandQueue()!
|
|
||||||
|
|
||||||
let mainBundle = Bundle(for: MetalWallpaperBackgroundNode.self)
|
|
||||||
|
|
||||||
guard let path = mainBundle.path(forResource: "WallpaperBackgroundNodeBundle", ofType: "bundle") else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
guard let bundle = Bundle(path: path) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
guard let defaultLibrary = try? self.device.makeDefaultLibrary(bundle: bundle) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let renderPipelineState = makePipelineState(device: self.device, library: defaultLibrary, vertexProgram: "wallpaperVertex", fragmentProgram: "wallpaperFragment") else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
self.renderPipelineState = renderPipelineState
|
|
||||||
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
self.metalLayer.device = self.device
|
|
||||||
self.metalLayer.pixelFormat = .bgra8Unorm
|
|
||||||
self.metalLayer.framebufferOnly = true
|
|
||||||
self.metalLayer.allowsNextDrawableTimeout = true
|
|
||||||
self.metalLayer.isOpaque = true
|
|
||||||
|
|
||||||
self.layer.addSublayer(self.metalLayer)
|
|
||||||
self.layer.addSublayer(self.hierarchyTrackingLayer)
|
|
||||||
|
|
||||||
self.hierarchyTrackingLayer.opacity = 0.0
|
|
||||||
self.hierarchyTrackingLayer.didEnterHierarchy = { [weak self] in
|
|
||||||
self?.updateIsVisible(true)
|
|
||||||
}
|
|
||||||
self.hierarchyTrackingLayer.didExitHierarchy = { [weak self] in
|
|
||||||
self?.updateIsVisible(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(wallpaper: TelegramWallpaper) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func _internalUpdateIsSettingUpWallpaper() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateLayout(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) {
|
|
||||||
if self.metalLayer.drawableSize != size {
|
|
||||||
self.metalLayer.drawableSize = size
|
|
||||||
|
|
||||||
transition.updateFrame(layer: self.metalLayer, frame: CGRect(origin: CGPoint(), size: size))
|
|
||||||
|
|
||||||
self.redraw()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateIsVisible(_ isVisible: Bool) {
|
|
||||||
if isVisible {
|
|
||||||
if self.displayLink == nil {
|
|
||||||
let displayLink = CADisplayLink(target: DisplayLinkTarget { [weak self] in
|
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
strongSelf.redraw()
|
|
||||||
}, selector: #selector(DisplayLinkTarget.event))
|
|
||||||
self.displayLink = displayLink
|
|
||||||
if #available(iOS 15.0, iOSApplicationExtension 15.0, *) {
|
|
||||||
if "".isEmpty {
|
|
||||||
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: 60.0, maximum: 60.0, preferred: 60.0)
|
|
||||||
} else {
|
|
||||||
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: Float(UIScreen.main.maximumFramesPerSecond), maximum: Float(UIScreen.main.maximumFramesPerSecond), preferred: Float(UIScreen.main.maximumFramesPerSecond))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
displayLink.isPaused = false
|
|
||||||
|
|
||||||
if !"".isEmpty {
|
|
||||||
self.animationThread = Thread(block: {
|
|
||||||
displayLink.add(to: .current, forMode: .common)
|
|
||||||
|
|
||||||
while true {
|
|
||||||
if Thread.current.isCancelled {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
RunLoop.current.run(until: .init(timeIntervalSinceNow: 1.0))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
self.animationThread?.name = "MetalWallpaperBackgroundNode"
|
|
||||||
self.animationThread?.qualityOfService = .userInteractive
|
|
||||||
self.animationThread?.start()
|
|
||||||
} else {
|
|
||||||
displayLink.add(to: .current, forMode: .common)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let displayLink = self.displayLink {
|
|
||||||
self.displayLink = nil
|
|
||||||
|
|
||||||
displayLink.invalidate()
|
|
||||||
}
|
|
||||||
if let animationThread = self.animationThread {
|
|
||||||
self.animationThread = nil
|
|
||||||
animationThread.cancel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var previousDrawTime: Double?
|
|
||||||
|
|
||||||
private func redraw() {
|
|
||||||
let timestamp = CACurrentMediaTime()
|
|
||||||
if let previousDrawTime = self.previousDrawTime {
|
|
||||||
let _ = previousDrawTime
|
|
||||||
//print("frame time \((timestamp - previousDrawTime) * 1000.0)")
|
|
||||||
}
|
|
||||||
self.previousDrawTime = timestamp
|
|
||||||
|
|
||||||
self.animationPhase += 1
|
|
||||||
let animationOffset = Float(self.animationPhase % 200) / 200.0
|
|
||||||
let _ = animationOffset
|
|
||||||
|
|
||||||
guard let commandBuffer = self.commandQueue.makeCommandBuffer() else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let drawable = self.metalLayer.nextDrawable() else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let drawTime = CACurrentMediaTime() - timestamp
|
|
||||||
if drawTime > 9.0 / 1000.0 {
|
|
||||||
print("get time \(drawTime * 1000.0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
let renderPassDescriptor = MTLRenderPassDescriptor()
|
|
||||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
|
|
||||||
renderPassDescriptor.colorAttachments[0].loadAction = .clear
|
|
||||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(
|
|
||||||
red: 0.0,
|
|
||||||
green: 0.0,
|
|
||||||
blue: 0.0,
|
|
||||||
alpha: 1.0
|
|
||||||
)
|
|
||||||
|
|
||||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var vertices: [Float] = [
|
|
||||||
-1.0, -1.0,
|
|
||||||
1.0, -1.0,
|
|
||||||
-1.0, 1.0,
|
|
||||||
1.0, 1.0
|
|
||||||
]
|
|
||||||
|
|
||||||
renderEncoder.setRenderPipelineState(self.renderPipelineState)
|
|
||||||
|
|
||||||
renderEncoder.setVertexBytes(&vertices, length: 4 * vertices.count, index: 0)
|
|
||||||
|
|
||||||
var resolution = simd_uint2(UInt32(drawable.texture.width), UInt32(drawable.texture.height))
|
|
||||||
renderEncoder.setFragmentBytes(&resolution, length: MemoryLayout<simd_uint2>.size * 2, index: 0)
|
|
||||||
|
|
||||||
var time = Float(timestamp) * 0.25
|
|
||||||
renderEncoder.setFragmentBytes(&time, length: 4, index: 1)
|
|
||||||
|
|
||||||
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1)
|
|
||||||
|
|
||||||
renderEncoder.endEncoding()
|
|
||||||
|
|
||||||
if self.metalLayer.presentsWithTransaction {
|
|
||||||
if Thread.isMainThread {
|
|
||||||
commandBuffer.commit()
|
|
||||||
commandBuffer.waitUntilScheduled()
|
|
||||||
drawable.present()
|
|
||||||
} else {
|
|
||||||
CATransaction.begin()
|
|
||||||
commandBuffer.commit()
|
|
||||||
commandBuffer.waitUntilScheduled()
|
|
||||||
drawable.present()
|
|
||||||
CATransaction.commit()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
commandBuffer.addScheduledHandler { _ in
|
|
||||||
drawable.present()
|
|
||||||
}
|
|
||||||
commandBuffer.commit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateIsLooping(_ isLooping: Bool) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasExtraBubbleBackground() -> Bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeFreeBackground() -> PortalView? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeDimmedNode() -> ASDisplayNode? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user