mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various Fixes
This commit is contained in:
parent
1dcdde3fbd
commit
851f106afd
12 changed files with 68 additions and 34 deletions
|
|
@ -354,7 +354,7 @@ private final class AnimatedStickerDirectFrameSourceCache {
|
|||
|
||||
let queue = self.queue
|
||||
self.storeQueue.async { [weak self] in
|
||||
let compressedData = compressFrame(width: width, height: height, rgbData: rgbData)
|
||||
let compressedData = compressFrame(width: width, height: height, rgbData: rgbData, unpremultiply: true)
|
||||
|
||||
queue.async {
|
||||
guard let strongSelf = self else {
|
||||
|
|
|
|||
|
|
@ -72,8 +72,9 @@ public final class AnimatedStickerFrame {
|
|||
let index: Int
|
||||
let isLastFrame: Bool
|
||||
let totalFrames: Int
|
||||
let multiplyAlpha: Bool
|
||||
|
||||
init(data: Data, type: AnimationRendererFrameType, width: Int, height: Int, bytesPerRow: Int, index: Int, isLastFrame: Bool, totalFrames: Int) {
|
||||
init(data: Data, type: AnimationRendererFrameType, width: Int, height: Int, bytesPerRow: Int, index: Int, isLastFrame: Bool, totalFrames: Int, multiplyAlpha: Bool = false) {
|
||||
self.data = data
|
||||
self.type = type
|
||||
self.width = width
|
||||
|
|
@ -83,6 +84,7 @@ public final class AnimatedStickerFrame {
|
|||
self.index = index
|
||||
self.isLastFrame = isLastFrame
|
||||
self.totalFrames = totalFrames
|
||||
self.multiplyAlpha = multiplyAlpha
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -422,7 +424,7 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
|||
return
|
||||
}
|
||||
|
||||
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, completion: {
|
||||
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, mulAlpha: frame.multiplyAlpha, completion: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -527,7 +529,7 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
|||
|
||||
assert(frame.bytesPerRow != 0)
|
||||
|
||||
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, completion: {
|
||||
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, mulAlpha: frame.multiplyAlpha, completion: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -679,7 +681,7 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
|||
return
|
||||
}
|
||||
|
||||
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, completion: {
|
||||
strongSelf.renderer?.render(queue: strongSelf.queue, width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type, mulAlpha: frame.multiplyAlpha, completion: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public enum AnimationRendererFrameType {
|
|||
}
|
||||
|
||||
protocol AnimationRenderer {
|
||||
func render(queue: Queue, width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType, completion: @escaping () -> Void)
|
||||
func render(queue: Queue, width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType, mulAlpha: Bool, completion: @escaping () -> Void)
|
||||
|
||||
func setOverlayColor(_ color: UIColor?, replace: Bool, animated: Bool)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import Foundation
|
|||
import Compression
|
||||
import YuvConversion
|
||||
|
||||
func compressFrame(width: Int, height: Int, rgbData: Data) -> Data? {
|
||||
func compressFrame(width: Int, height: Int, rgbData: Data, unpremultiply: Bool) -> Data? {
|
||||
let bytesPerRow = rgbData.count / height
|
||||
|
||||
let yuvaPixelsPerAlphaRow = (Int(width) + 1) & (~1)
|
||||
|
|
@ -26,7 +26,7 @@ func compressFrame(width: Int, height: Int, rgbData: Data) -> Data? {
|
|||
var rgbData = rgbData
|
||||
rgbData.withUnsafeMutableBytes { (buffer: UnsafeMutableRawBufferPointer) -> Void in
|
||||
if let baseAddress = buffer.baseAddress {
|
||||
encodeRGBAToYUVA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), baseAddress.assumingMemoryBound(to: UInt8.self), Int32(width), Int32(height), Int32(bytesPerRow))
|
||||
encodeRGBAToYUVA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), baseAddress.assumingMemoryBound(to: UInt8.self), Int32(width), Int32(height), Int32(bytesPerRow), unpremultiply)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ import AsyncDisplayKit
|
|||
import Display
|
||||
import SwiftSignalKit
|
||||
import YuvConversion
|
||||
import Accelerate
|
||||
|
||||
final class SoftwareAnimationRenderer: ASDisplayNode, AnimationRenderer {
|
||||
private var highlightedContentNode: ASDisplayNode?
|
||||
private var highlightedColor: UIColor?
|
||||
private var highlightReplacesContent = false
|
||||
|
||||
func render(queue: Queue, width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType, completion: @escaping () -> Void) {
|
||||
func render(queue: Queue, width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType, mulAlpha: Bool, completion: @escaping () -> Void) {
|
||||
assert(bytesPerRow > 0)
|
||||
queue.async { [weak self] in
|
||||
switch type {
|
||||
|
|
@ -38,11 +39,22 @@ final class SoftwareAnimationRenderer: ASDisplayNode, AnimationRenderer {
|
|||
decodeYUVAToRGBA(baseAddress.assumingMemoryBound(to: UInt8.self), pixelData, Int32(width), Int32(height), Int32(contextBytesPerRow))
|
||||
}
|
||||
case .argb:
|
||||
data.withUnsafeBytes { bytes -> Void in
|
||||
var data = data
|
||||
data.withUnsafeMutableBytes { bytes -> Void in
|
||||
guard let baseAddress = bytes.baseAddress else {
|
||||
return
|
||||
}
|
||||
memcpy(pixelData, baseAddress.assumingMemoryBound(to: UInt8.self), bytes.count)
|
||||
if mulAlpha {
|
||||
var srcData = vImage_Buffer(data: baseAddress.assumingMemoryBound(to: UInt8.self), height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: bytesPerRow)
|
||||
var destData = vImage_Buffer(data: pixelData, height: vImagePixelCount(height), width: vImagePixelCount(width), rowBytes: bytesPerRow)
|
||||
|
||||
let permuteMap: [UInt8] = [3, 2, 1, 0]
|
||||
vImagePermuteChannels_ARGB8888(&srcData, &destData, permuteMap, vImage_Flags(kvImageDoNotTile))
|
||||
vImagePremultiplyData_ARGB8888(&destData, &destData, vImage_Flags(kvImageDoNotTile))
|
||||
vImagePermuteChannels_ARGB8888(&destData, &destData, permuteMap, vImage_Flags(kvImageDoNotTile))
|
||||
} else {
|
||||
memcpy(pixelData, baseAddress.assumingMemoryBound(to: UInt8.self), bytes.count)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ private final class VideoStickerFrameSourceCache {
|
|||
self.width = width
|
||||
self.height = height
|
||||
|
||||
let version: Int = 2
|
||||
let version: Int = 3
|
||||
self.path = "\(pathPrefix)_\(width)x\(height)-v\(version).vstickerframecache"
|
||||
var file = ManagedFile(queue: queue, path: self.path, mode: .readwrite)
|
||||
if let file = file {
|
||||
|
|
@ -189,7 +189,7 @@ private final class VideoStickerFrameSourceCache {
|
|||
|
||||
let queue = self.queue
|
||||
self.storeQueue.async { [weak self] in
|
||||
let compressedData = compressFrame(width: width, height: height, rgbData: rgbData)
|
||||
let compressedData = compressFrame(width: width, height: height, rgbData: rgbData, unpremultiply: false)
|
||||
|
||||
queue.async {
|
||||
guard let strongSelf = self else {
|
||||
|
|
@ -270,6 +270,8 @@ private final class VideoStickerFrameSourceCache {
|
|||
}
|
||||
}
|
||||
|
||||
private let useCache = true
|
||||
|
||||
final class VideoStickerDirectFrameSource: AnimatedStickerFrameSource {
|
||||
private let queue: Queue
|
||||
private let path: String
|
||||
|
|
@ -299,7 +301,7 @@ final class VideoStickerDirectFrameSource: AnimatedStickerFrameSource {
|
|||
VideoStickerFrameSourceCache(queue: queue, pathPrefix: cachePathPrefix, width: width, height: height)
|
||||
}
|
||||
|
||||
if let cache = self.cache, cache.frameCount > 0 {
|
||||
if useCache, let cache = self.cache, cache.frameCount > 0 {
|
||||
self.source = nil
|
||||
self.frameRate = Int(cache.frameRate)
|
||||
self.frameCount = Int(cache.frameCount)
|
||||
|
|
@ -325,7 +327,7 @@ final class VideoStickerDirectFrameSource: AnimatedStickerFrameSource {
|
|||
|
||||
self.currentFrame += 1
|
||||
if draw {
|
||||
if let cache = self.cache, let yuvData = cache.readUncompressedYuvaFrame(index: frameIndex) {
|
||||
if useCache, let cache = self.cache, let yuvData = cache.readUncompressedYuvaFrame(index: frameIndex) {
|
||||
return AnimatedStickerFrame(data: yuvData, type: .yuva, width: self.width, height: self.height, bytesPerRow: self.width * 2, index: frameIndex, isLastFrame: frameIndex == self.frameCount - 1, totalFrames: self.frameCount)
|
||||
} else if let source = self.source {
|
||||
let frameAndLoop = source.readFrame(maxPts: nil)
|
||||
|
|
@ -376,8 +378,8 @@ final class VideoStickerDirectFrameSource: AnimatedStickerFrameSource {
|
|||
}
|
||||
|
||||
self.cache?.storeUncompressedRgbFrame(index: frameIndex, rgbData: frameData)
|
||||
|
||||
return AnimatedStickerFrame(data: frameData, type: .argb, width: self.width, height: self.height, bytesPerRow: self.bytesPerRow, index: frameIndex, isLastFrame: frameIndex == self.frameCount - 1, totalFrames: self.frameCount)
|
||||
|
||||
return AnimatedStickerFrame(data: frameData, type: .argb, width: self.width, height: self.height, bytesPerRow: self.bytesPerRow, index: frameIndex, isLastFrame: frameIndex == self.frameCount - 1, totalFrames: self.frameCount, multiplyAlpha: true)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue