This commit is contained in:
Ali 2022-05-07 21:22:58 +04:00
parent 6fabcaf7df
commit 574583381f
9 changed files with 379 additions and 3 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -191,7 +191,9 @@ public class ItemListCheckboxItemNode: ItemListRevealOptionsItemNode {
case .left:
leftInset += 62.0
case .right:
leftInset += 0.0
if item.icon == nil {
leftInset += 16.0
}
}
let iconInset: CGFloat = 62.0

View File

@ -784,7 +784,7 @@ public final class OngoingCallContext {
var allowP2P = allowP2P
if debugUseLegacyVersionForReflectors {
useModernImplementation = true
version = "4.1.2"
version = "10.0.0"
allowP2P = false
} else {
useModernImplementation = version != OngoingCallThreadLocalContext.version()

View File

@ -831,7 +831,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
+ (tgcalls::ProtocolVersion)protocolVersionFromLibraryVersion:(NSString *)version {
if ([version isEqualToString:@"2.7.7"]) {
return tgcalls::ProtocolVersion::V0;
} else if ([version isEqualToString:@"3.0.0"]) {
} else if ([version isEqualToString:@"5.0.0"]) {
return tgcalls::ProtocolVersion::V1;
} else {
return tgcalls::ProtocolVersion::V0;

View File

@ -1,4 +1,44 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
load(
"@build_bazel_rules_apple//apple:resources.bzl",
"apple_resource_bundle",
"apple_resource_group",
)
load("//build-system/bazel-utils:plist_fragment.bzl",
"plist_fragment",
)
filegroup(
name = "WallpaperBackgroundNodeMetalResources",
srcs = glob([
"Resources/**/*.metal",
]),
visibility = ["//visibility:public"],
)
plist_fragment(
name = "WallpaperBackgroundNodeBundleInfoPlist",
extension = "plist",
template =
"""
<key>CFBundleIdentifier</key>
<string>org.telegram.WallpaperBackgroundNode</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleName</key>
<string>WallpaperBackgroundNode</string>
"""
)
apple_resource_bundle(
name = "WallpaperBackgroundNodeBundle",
infoplists = [
":WallpaperBackgroundNodeBundleInfoPlist",
],
resources = [
":WallpaperBackgroundNodeMetalResources",
],
)
swift_library(
name = "WallpaperBackgroundNode",
@ -9,6 +49,9 @@ swift_library(
copts = [
"-warnings-as-errors",
],
data = [
":WallpaperBackgroundNodeBundle",
],
deps = [
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
"//submodules/Display:Display",

View File

@ -0,0 +1,24 @@
#include <metal_stdlib>
using namespace metal;
typedef struct {
packed_float2 position;
} Vertex;
typedef struct {
float4 position[[position]];
} Varyings;
vertex Varyings wallpaperVertex(constant Vertex *verticies[[buffer(0)]], unsigned int vid[[vertex_id]]) {
Varyings out;
constant Vertex &v = verticies[vid];
out.position = float4(float2(v.position), 0.0, 1.0);
return out;
}
fragment half4 wallpaperFragment(Varyings in[[stage_in]]) {
float4 out = float4(0.0, 1.0, 0.0, 1.0);
return half4(out);
}

View File

@ -0,0 +1,301 @@
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
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, 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 {
final class DisplayLinkTarget: NSObject {
private let f: () -> Void
init(_ f: @escaping () -> Void) {
self.f = f
}
@objc func event() {
self.f()
}
}
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, *) {
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, animationOffset * 1.0,
1.0, animationOffset * 1.0
]
renderEncoder.setRenderPipelineState(self.renderPipelineState)
renderEncoder.setVertexBytes(&vertices, length: 4 * vertices.count, index: 0)
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 updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
}
func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool {
return false
}
func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode? {
return nil
}
func makeDimmedNode() -> ASDisplayNode? {
return nil
}
}

View File

@ -1775,7 +1775,13 @@ private let sharedStorage = WallpaperBackgroundNodeMergedImpl.SharedStorage()
public func createWallpaperBackgroundNode(context: AccountContext, forChatDisplay: Bool, useSharedAnimationPhase: Bool = false, useExperimentalImplementation: Bool = false) -> WallpaperBackgroundNode {
if forChatDisplay && useExperimentalImplementation {
#if DEBUG
if #available(iOS 13.0, iOSApplicationExtension 13.0, *) {
return MetalWallpaperBackgroundNode()
}
#else
return WallpaperBackgroundNodeMergedImpl(context: context, storage: useSharedAnimationPhase ? sharedStorage : nil)
#endif
}
return WallpaperBackgroundNodeImpl(context: context, useSharedAnimationPhase: useSharedAnimationPhase)