-
Notifications
You must be signed in to change notification settings - Fork 43
Open
Description
查找图像压缩算法的实现细节:
[3 tools called]
查看客户端如何处理图像压缩:
[3 tools called]
查看 DXT1 压缩的具体实现:
[3 tools called]
Tracy 使用两阶段压缩来处理图像数据:
图像压缩算法详解
一、第一阶段:DXT1 纹理压缩(客户端)
1. 压缩位置
在客户端,由专门的压缩线程处理:
const auto csz = size_t( w * h / 2 );
auto etc1buf = (char*)tracy_malloc( csz );
CompressImageDxt1( (const char*)fi->image, etc1buf, w, h );2. DXT1 压缩特性
- 算法:S3 纹理压缩(DXT1/BC1)
- 压缩比:8:1(每像素从 32 位压缩到 4 位)
- 格式:从 RGBA8888(4 字节/像素)→ DXT1(0.5 字节/像素)
- 类型:有损压缩,质量损失较小
- 块大小:4×4 像素块 = 8 字节
3. 性能优化
支持 SIMD 加速,性能数据(320×180 图像):
| 实现 | 所需定义 | 压缩时间 |
|---|---|---|
| x86 参考实现 | --- | 198.2 μs |
| x86 SSE4.1 | __SSE4_1__ |
25.4 μs |
| x86 AVX2 | __AVX2__ |
17.4 μs |
| ARM 参考实现 | --- | 1.04 ms |
| ARM32 NEON | __ARM_NEON |
529 μs |
| ARM64 NEON | __ARM_NEON |
438 μs |
4. 处理流程
- 用户调用
FrameImage()传入 RGBA 数据 - 数据存入
m_fiQueue队列 - 压缩线程从队列取出图像
- 调用
CompressImageDxt1()进行 DXT1 压缩 - 压缩后的数据通过网络发送到服务器
二、第二阶段:ZSTD 压缩(服务器端)
1. 压缩位置
在服务器端接收数据后进行进一步压缩:
m_texcomp.FixOrder( (char*)dst, sz/8 );
m_texcomp.Rdo( (char*)dst, sz/8 );
m_pendingFrameImageData.image = m_texcomp.Pack( m_frameImageBuffer, sz, m_pendingFrameImageData.csz, m_slab );2. ZSTD 压缩参数
uint32_t TextureCompression::Pack( struct ZSTD_CCtx_s* ctx, char*& buf, size_t& bufsz, const char* image, uint32_t inBytes )
{
const auto maxout = ZSTD_COMPRESSBOUND( inBytes );
if( bufsz < maxout )
{
bufsz = maxout;
delete[] buf;
buf = new char[maxout];
}
assert( ctx );
auto ret = (uint32_t)ZSTD_compressCCtx( ctx, buf, maxout, image, inBytes, 3 );- 算法:ZSTD(Zstandard)
- 压缩级别:3(平衡压缩比与速度)
- 类型:无损压缩
- 对象:对 DXT1 压缩后的数据再次压缩
3. 服务器端优化处理
在 ZSTD 压缩前,还进行了两项优化:
FixOrder():调整 DXT1 块的数据顺序,提高压缩效率Rdo():基于视觉的 RDO(Rate Distortion Optimization),在保持视觉质量的前提下进一步优化压缩
三、完整压缩流程
用户提供RGBA图像
↓
[客户端] FrameImage() - 存储到队列
↓
[客户端] 压缩线程 - DXT1压缩 (8:1)
├─ 32位/像素 → 4位/像素
├─ 支持SIMD加速
└─ 质量轻微下降
↓
[网络传输] DXT1压缩数据
↓
[服务器] 接收数据
↓
[服务器] FixOrder() - 优化数据排列
↓
[服务器] Rdo() - 视觉优化压缩
↓
[服务器] ZSTD压缩 (级别3) - 进一步压缩
└─ 无损压缩
↓
[服务器] 存储压缩后的数据
四、压缩效果
1. 理论压缩比
- DXT1:8:1(32 位 → 4 位)
- ZSTD:通常 2-4:1(取决于图像内容)
综合压缩比通常为 16-32:1
2. 实际示例
对于 320×180 的图像:
- 原始 RGBA:320 × 180 × 4 = 230,400 字节(约 225 KB)
- DXT1 压缩后:320 × 180 / 2 = 28,800 字节(约 28 KB)
- ZSTD 进一步压缩后:通常 < 10 KB
3. 限制
- 单帧图像压缩后不能超过 256 KB(网络缓冲限制)
- 960×540 的图像可以满足此限制
五、关键代码位置
-
客户端 DXT1 压缩:
public/client/TracyDxt1.cpp- DXT1 压缩实现public/client/TracyProfiler.cpp:2288- 调用压缩函数
-
服务器端 ZSTD 压缩:
server/TracyTextureCompression.cpp- ZSTD 压缩实现server/TracyWorker.cpp:3887- 调用压缩函数
-
服务器端解压:
server/TracyTextureCompression.cpp:62-80- 解压函数
六、总结
Tracy 使用两阶段压缩:
-
DXT1 纹理压缩(客户端,有损)
- 8:1 压缩比
- 支持 SIMD 加速
- 质量损失小
-
ZSTD 压缩(服务器端,无损)
- 对 DXT1 数据再次压缩
- 压缩级别 3
- 进一步减小存储空间
该方案在保持视觉质量的同时,显著减少内存和网络传输开销。
Metadata
Metadata
Assignees
Labels
No labels