【V】Surface的size分析

Surface有两种size,render size和 screen size。render size就是buffer的大小,screen size就是surface显示到屏幕的大小。render size < screen size,画面会拉伸,反之则会缩小。在SurfaceFlinger里面体现就是Source Crop和Disp Frame。

render size的取值逻辑如下:

先取mReqWidth/mReqHeight的值,如果mReqWidth/mReqHeight未设置再取mUserWidth/mUserHeight的值,如果mUserWidth/mUserHeight为设置最后取mDefaultWidth/mDefaultHeight,如图:

Surface的mReqWidth/mReqHeight缺省值为0,通过native_window_set_buffers_dimensions设置:

Surface的mUserWidth/mUserHeight缺省值为0,可以通过native_window_set_buffers_user_dimensions设置:

可以通过query NATIVE_WINDOW_DEFAULT_WIDTH/NATIVE_WINDOW_DEFAULT_HEIGHT的方式读取该值:

我们通过eglQuerySurface查询surface的宽高时,就是通过上面的方式查询的。

Surface的mDefaultWidth/mDefaultHeight缺省值为0,在执行Surface::connect和Surface::queueBuffer时会同步BufferQueueProducer的mDefaultWidth/mDefaultHeight的值。

BufferQueueProducer的mDefaultWidth/mDefaultHeight的值,在执行BlastBufferQueue::updates时会调用BufferQueueConsumer::setDefaultBufferSize接口进行设置:

可以通过query NATIVE_WINDOW_WIDTH/NATIVE_WINDOW_HEIGHT的方式读取该值:

下面的图更加清晰的展示了Surface的mReqWidth/mReqHeight等值的设置:

screen size的值要根据SurfaceView来分析。SurfaceView执行updateSurface流程时,会设置两个transaction:

第一个transaction是设置mBlastSurfaceControl的desintationframe;mSurfaceWidth/mSurfaceHeight缺省情况下等于View大小,可以通过setFixedSize改变;该值最终会设置到Surface的mDefaultWidth/mDefaultHeight。

第二个transaction是设置mSurfaceControl的位置和大小;mScreenRect的值是根据SurfaceView的view位置大小属性计算出来的。

mSurfaceControl是mBlastSurfaceControl的父图层,mBlastSurfaceControl大小受到mSurfaceControl限制。如下图,是原神的surfaceflinger dump信息。

根据上面的分析,决定screen size大小有两个因素:

  • SurfaceView的view大小和SurfaceView的mSurfaceWidth/mSurfaceHeight的比值决定了SurfaceView图层的screen size。

  • SurfaceView的mSurfaceWidth/mSurfaceHeight和Surface的mUserWidth/mUserHeight的比值决定了SurfaceViewBlast图层在SurfaceView图层里面的大小。

一般情况,不会同时修改SurfaceView的mSurfaceWidth/mSurfaceHeight和Surface的mUserWidth/mUserHeight的值。

JAVA层通过setFixedSize修改SurfaceView的mSurfaceWidth/mSurfaceHeight,来调整render size和 screen size。而NATIVE(NDK)层,通过ANativeWindow_setBuffersGeometry来修改Surface的mUserWidth/mUserHeight,来调整render size和 screen size。

从上面分析下来,发现Surface mReqWidth/mReqHeight好像用处不大。Surface mReqWidth/mReqHeight主要给VNDK用的,通常用来预旋转用的。如果VNDK出图支持预旋转(如GPU)时,会调用native_window_set_buffers_dimensions交换mReqWidth和mReqHeight,从而将分配的Buffer进行旋转。

相关推荐
2601_9617652935 分钟前
【分享】PlayerPro媒体音乐播放器 完整专业版
android·媒体
JohnnyDeng943 小时前
【Android】Android 包体积优化:R8/ProGuard 深度配置全攻略
android·性能优化·kotlin·jetpack
故渊at3 小时前
第九板块:Android 多媒体体系 | 第二十四篇:Camera Service 与 HAL3 成像流水线
android·camera·多媒体体系·hal3
Jinkxs6 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python
私人珍藏库7 小时前
【Android】VLLO-韩国热门手机剪辑APP
android·app·工具·软件·多功能
Cloud_Shy6187 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第六章 Item 40 - 43)
android·开发语言·人工智能·笔记·python·学习方法
AFinalStone8 小时前
Android12 U盘插拔链路源码全解析(五):Framework层(下) StorageManagerService
android·frameworks
林九生9 小时前
【实用技巧】MySQL 绿色版一键路径更新脚本详解 —— update_path.bat 深度解析
android·数据库·mysql
故渊at11 小时前
第十三板块:Android 综合架构与未来演进 | 第三十一篇:Android 架构演进与 Fuchsia OS 的挑战
android·架构·宏内核·微内核·fuchsia·ipc 性能博弈
aqi0011 小时前
一文速览 HarmonyOS 6.1.1 推出的十个新特性
android·华为·harmonyos·鸿蒙·harmony