Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android 手写延迟优化(一):利用前缓冲快速上屏

Android 手写延迟优化(一):利用前缓冲快速上屏

原创
作者头像
Kkkiro
修改于 2023-01-02 16:06:20
修改于 2023-01-02 16:06:20
2.4K0
举报
文章被收录于专栏:爬坑之路爬坑之路

背景

虽然 Android 的大屏生态和 iPadOS 相比不怎样,但随着移动互联网进入下半场,卷无可卷之下,各厂商纷纷在大屏生态方面各显神通,在 Android Pad、折叠屏等产品领域推陈出新。

这些设备往往打着生产力工具的卖点,和 iPad 一样配备了手写笔。但这些设备的书写体验却往往差强人意,往往是自家应用能做到及格线以上,第三方 APP 却很难实现像 iPadOS 上顺滑跟手的效果。

为了改善这种情况,Android 开发团队决定亲自上场,为开发者打个样,从两个方面辅助开发者解决这个让人头疼的延迟问题:

  1. 优化视觉反馈延迟
  2. 书写轨迹预测

本篇文章主要介绍视觉反馈延迟优化相关技术。

视觉反馈延迟优化原理

Low latency graphic,直译过来就是低延迟图形,这是 Android 团队提供的辅助开发者快速将用户输入的轨迹绘制到屏幕上的工具库,降低从手写输入到渲染上屏幕这个过程的耗时。

常规的手写笔迹绘制流程,从「获取到输入」到「绘制上屏」,在系统层面需要经过多个步骤的处理。我们知道,Android 采用多缓冲的方式进行渲染,同一时间内一般存在两个缓冲:

  1. 显示缓冲(Display Buffer):这块缓冲里面包含了用户在屏幕上看到图像数据
  2. 渲染缓冲(Rendering Buffer):程序的所有绘制操作并不会直接操作显示缓冲,程序的绘制最终修改的都是渲染缓冲,等整个画面都绘制完,再把渲染缓冲和显示缓冲进行交换,整体上屏。
双缓冲渲染机制
双缓冲渲染机制

这种机制能够有效协调每一帧画面的绘制,保证有流畅的用户体验,也能有效避免因渲染直接上屏导致出现画面出现撕裂的问题。关于渲染的双缓冲机制可以参考官方的 Project Butter

但天底下没有免费的午餐,双缓冲机制的引入带来了延迟:从用户输入到最终绘制上屏至少有一帧的延迟,考虑到过程中的其他操作引入的耗时,实际延迟会更加严重。

前缓冲渲染:直接上屏

https://source.android.com/docs/core/graphics

为了优化双缓冲带来的延迟,低延迟视觉库引入了前缓冲技术,这个技术在双缓冲的基础上,增加了一个前缓冲图层(front buffer layer)。这个前缓冲图层盖在双缓冲图层的前面,它是透明的,且只会显示很短的一段时间。

前缓冲图层和双缓冲图层运作机制
前缓冲图层和双缓冲图层运作机制

应用通过将用户的输入直接绘制到前缓冲上,实现快速上屏,在最短的时间内给到用户视觉上的反馈。由于前缓冲只会显示很短的一段时间,所以实际的操作结果还需要通过原来的方式,固化到双缓冲的图层上,替换前缓冲。

可能有人会问:既然前缓冲能快速上屏,直接用前缓冲图层绘制就行,为什么还需要用双缓冲图层?

答案很简单:前缓冲图层之所以能够快速上屏,是因为它抛弃了双缓冲变成了单缓冲,单缓冲的最大问题在于:进行大范围的画面更新时,会有画面撕裂的问题。

也就是说,低延迟视觉库快速实现上屏这种优化方法生效的前提是:只修改屏幕上很小的一块区域,比如很小的一块区域内的笔画变化。

当用户在进行手写输入时,小块的修改通过前缓冲反馈到屏幕上;而当用户抬起手写笔时,这些输入将汇总交给原有的双缓冲渲染机制,实现固化。

应用

低延迟视觉库提供的前缓冲绘制能力,适用于手写、画画、素描这类修改一小块区域的场景,但不适用于平移、缩放这些修改很大块区域的场景。

在接入低延时视觉库前,需要仔细评估下应用中哪些内容可以渲染到前缓冲图层(常见的就是笔画),哪些内容需要维持在双缓冲图层处理(如大面积的内容更新、平移、缩放)。

接入过程也简单,继承 GLFrontBufferedRenderer.Callback 接口,分别实现绘制前缓冲的操作和绘制双缓冲的操作,即可。

代码语言:text
AI代码解释
复制
val callbacks = object : GLFrontBufferedRenderer.Callback<DATA_TYPE> {
    override fun onDrawFrontBufferedLayer(
        eglManager: EGLManager,
        bufferWidth: Int,
        bufferHeight: Int,
        transform: FloatArray,
        param: DATA_TYPE
    ) {
        // 前缓冲绘制代码
    }

    override fun onDrawDoubleBufferedLayer(
        eglManager: EGLManager,
        bufferWidth: Int,
        bufferHeight: Int,
        transform: FloatArray,
        params: Collection<DATA_TYPE>
    ) {
        // 双缓冲绘制代码
    }
}

val frontBufferRenderer = GLFrontBufferedRenderer(mySurfaceView, callbacks)

// 添加触摸监听,获取动作输入,并将输入转为动作数据交给 frontBufferRenderer
mySurfaceView.setOnTouchListener { v, event ->
            // 需要自行处理 MotionEvent 转换成图形数据的逻辑
            val dataPoint = event.toDATA_TYPE()
                
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    // 直接绘制新的数据到前缓冲层
                    frontBufferRenderer.renderFrontBufferedLayer(dataPoint)
                }

                MotionEvent.ACTION_MOVE -> {
                    // 直接绘制新的数据到前缓冲层
                    frontBufferRenderer.renderFrontBufferedLayer(dataPoint)
                }

                MotionEvent.ACTION_UP -> {
                    // 用户操作完毕,笔画绘制完成,这个时候把过程中所有的数据提交给双缓冲层处理
                    frontBufferRenderer.commit()
                }
                else -> Unit
            }
            true
        }

完整的实例代码可以参考官方仓库中的测试工程,入口界面 FrontBufferedRendererTestActivity

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
“终于懂了” 系列:Android屏幕刷新机制—VSync、Choreographer 全面理解!
在Android中,当我们谈到 布局优化、卡顿优化 时,通常都知道 需要减少布局层级、减少主线程耗时操作,这样可以减少丢帧。如果丢帧比较严重,那么界面可能会有明显的卡顿感。我们知道 通常手机刷新是每秒60次,即每隔16.6ms刷新一次。 问题来了:
胡飞洋
2020/08/25
10.5K1
“终于懂了” 系列:Android屏幕刷新机制—VSync、Choreographer 全面理解!
Android VSYNC与图形系统中的撕裂、双缓冲、三缓冲浅析
先接触两个图形概念: 帧率(Frame Rate,单位FPS)--GPU显卡生成帧的速率,也可以认为是数据处理的速度), 屏幕刷新频率 (Refresh Rate单位赫兹/HZ):是指硬件设备刷新屏幕的频率。屏幕刷新率一般是固定的,比如60Hz的每16ms就刷一次屏幕,可以类比一下黑白电视的电子扫描枪,每16ms电子枪从上到下从左到右一行一行逐渐把图片绘制出来,如果GPU显卡性能非常强悍,帧率可以非常高,甚至会高于屏幕刷新频率。
看书的小蜗牛
2020/02/19
2.6K0
SurfaceView 与 TextureView 详解
Surface 就是“表面”的意思,可以简单理解为内存中的一段绘图缓冲区。在SDK的文档中,对Surface的描述是这样的:“Handle onto a raw buffer that is being managed by the screen compositor”,翻译成中文就是“由屏幕显示内容合成器(screen compositor)所管理的原生缓冲器的句柄”, 这句话包括下面两个意思:
字节流动
2021/01/12
14.2K0
Android 显示刷新机制、VSYNC和三重缓存机制
为了理解 APP 是如何进行渲染的,我们就必须了解手机硬件是如何工作的,也必须理解什么是 VSYNC。
全栈程序员站长
2022/08/31
2.9K0
Android 显示刷新机制、VSYNC和三重缓存机制
Android平台下VR头显如何低延迟播放4K以上超高分辨率RTSP|RTMP流
VR头显需要更高的分辨率以提供更清晰的视觉体验、满足沉浸感的要求、适应透镜放大效应以及适应更广泛的可视角度,超高分辨率的优势如下:
音视频牛哥
2024/06/18
1550
Android平台下VR头显如何低延迟播放4K以上超高分辨率RTSP|RTMP流
揭秘字节码到像素的一生!Chromium 渲染流水线
点个关注👆跟腾讯工程师学技术 导语| 本文将深入介绍 Chromium 内核组成结构,并以渲染流水线为主线,从接收字节码开始,按渲染流程来一步一步分析这个字节码究竟是如何转变成屏幕上的像素点的。 现代浏览器架构 在开始介绍渲染流水线之前,我们需要先介绍一下 Chromium 的浏览器架构与 Chromium 的进程模型作为前置知识。 一、两个公式 公式 1:浏览器 = 浏览器内核 + 服务 Safari = WebKit + 其他组件、库、服务 Chrome = Chromium + Google
腾讯云开发者
2022/12/06
1.4K0
揭秘字节码到像素的一生!Chromium 渲染流水线
一看就懂的 OpenGL 基础概念(2):EGL,OpenGL 与设备的桥梁丨音视频基础
这个公众号会路线图式的遍历分享音视频技术:音视频基础 → 音视频工具 → 音视频工程示例 → 音视频工业实战。关注一下成本不高,错过干货损失不小 ↓↓↓
关键帧
2022/11/29
3.2K0
一看就懂的 OpenGL 基础概念(2):EGL,OpenGL 与设备的桥梁丨音视频基础
Android帧率监测与优化技巧
Android 应用的性能优化是开发过程中至关重要的一环,而帧率(Frame Rate)是评估应用性能的一个关键指标。在本文中,我们将深入探讨如何监测 Android 应用的帧率,以及如何通过代码示例来优化应用的性能。
Rouse
2023/10/27
6170
Android帧率监测与优化技巧
小米:VR产业中Android的现状与挑战
内容来源:2017年11月16日,小米高级研发经理李政在“droidcon 北京2017安卓技术大会”进行《移动VR的现状和展望》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。 阅读字数:2575 | 7分钟阅读 摘要 我们将探讨虚拟现实产业中Android的现状,以及当前VR设备所面临的瓶颈,如何通过技术层去一一解决,未来的发展中又面临着那些挑战。 嘉宾演讲视频及PPT回顾:http://suo.im/2LJpfn 概念区分 为了便于大家区分VR
IT大咖说
2018/06/04
6340
Android 布局优化真的难,从入门到放弃
Android的绘制优化其实可以分为两个部分,即布局(UI)优化和卡顿优化,而布局优化的核心问题就是要解决因布局渲染性能不佳而导致应用卡顿的问题,所以它可以认为是卡顿优化的一个子集。
用户9239674
2022/01/08
9920
像素是怎样练成的
本来呢,最近在规划一篇关于浏览器的文章,但是在做文章架构梳理和相关资料查询的时候,发现「浏览器在渲染页面」的过程中,也别有洞天。索性,就单独将其作为一篇文章来写。
前端柒八九
2023/08/01
6350
像素是怎样练成的
让你的应用完美适配平板
其实标题有点吹牛逼了,谁也不敢说能完美适配平板,只能说尽力去做,包括显示和使用的各个方面尽力去做,才有可能在更多的平板设备上更加完美的运行起来,因为安卓的设备实在是太多了,之前手机在卷,现在平板也一样在卷。。。
ZhuJiang
2022/08/02
2.3K0
让你的应用完美适配平板
Android中的绘图
界面是软件与用户交互的最直接的层,界面的好坏决定用户对软件的第一印象。Android系统能够在诸多的移动平台中脱颖而出,漂亮的界面带来的良好的用户体验无疑是其中一个很重要的因素。在我们平时的软件开发中,仅靠系统提供的那些组件来实现界面是远远不够的,在很多情况下我们都需要自己来绘制软件界面。在本章中我们就将学习Android中和绘制图形及位图显示和效果有关的知识。
张哥编程
2024/12/17
2400
Android中的绘图
延迟是AR/VR体验的基础
译者注: 原文发表于2012年, 虽然当时的一些硬件条件限制现在已经没有了, 但我们可以从中学习到AR/VR的延迟解决思路. 另外, 译文略过了显示器的发展史
逍遥剑客
2022/01/11
1.2K0
页面是如何生成的(宏观角度)
当你启动一个应用程序,对应的进程就被创建。进程可能会创建一些线程用于帮助它完成部分工作,新建线程是一个可选操作。在启动某个进程的同时,操作系统(OS)也会分配内存以用于进程进行私有数据的存储。该内存空间是和其他进程是互不干扰的。
前端柒八九
2022/08/25
8810
页面是如何生成的(宏观角度)
浏览器_知识点精讲
今天,我们继续「前端面试」的知识点。我们来谈谈关于「浏览器」的相关知识点和具体的算法。
前端柒八九
2022/12/19
8710
浏览器_知识点精讲
移动端点击事件延迟的诞生消亡史
快速反馈对于任何 UI 的实现都是至关重要的。研究表明,100ms 是界面让用户感到即时的最大延迟。尽管如此,移动网络仍然受到一个巨大的反馈问题的困扰:触摸任何元素后,延迟 300 毫秒。这种延迟是许多用户认为基于 HTML 的 Web 应用程序“卡顿”的最重要原因之一。在本文中,本文将带你了解移动端点击事件延迟的从诞生到消亡的过程。
用户6167509
2020/07/25
3.2K0
Android界面性能优化必读
Android系统要求每一帧都要在 16ms 内绘制完成,平滑的完成一帧意味着任何特殊的帧需要执行所有的渲染代码(包括 framework 发送给 GPU 和 CPU 绘制到缓冲区的命令)都要在 16ms 内完成,保持流畅的体验。这个速度允许系统在动画和输入事件的过程中以约 60 帧每秒( 1秒 / 0.016帧每秒 = 62.5帧/秒 )的平滑帧率来渲染。
做个快乐的码农
2022/01/10
5K0
Android界面性能优化必读
iOS 页面渲染 - 流程
作为一名专业的 iOS 页面仔,画 UI 是我们的家常便饭,那不知道你在开发过程中有没有思考过这样一些问题:
CoderStar
2022/09/23
2.1K1
iOS 页面渲染 - 流程
【笔记】《游戏编程算法与技巧》1-6
本篇是看完《游戏编程算法与技巧》后做的笔记的上半部分. 这本书可以看作是《游戏引擎架构》的入门版, 主要介绍了游戏相关的常见算法和一些基础知识, 很多知识点都在面试中会遇到, 值得一读.
ZifengHuang
2022/08/30
4.5K0
相关推荐
“终于懂了” 系列:Android屏幕刷新机制—VSync、Choreographer 全面理解!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档