1.g bufferԴ??
2.javaä¸:System.out.println("String".replace('g','G')=="String".replace('g','G')); 为ä»ä¹è¿åfalse
3.电脑系统苹果和微软之外的系统苹果电脑系统和windows系统的区别
4.UE5.1卡通渲染管线修改 学习笔记(改源码版)
5.UE5实践1.配置环境以及简单的shadingmodel添加
6.Android性能优化:定性和定位Android图形性能问题——以后台录屏进程为例
g bufferԴ??
VC-摄像头控制SDK源码
#include <windows.h>
#include <stdio.h>
#include <vfw.h>
#pragma comment(lib,"vfw.lib")
HWND ghWndCap ; //捕获窗的句柄
CAPDRIVERCAPS gCapDriverCaps ; //视频驱动器的能力
CAPSTATUS gCapStatus ; //捕获窗的状态
char szCaptureFile[] = "MYCAP.AVI";
char gachBuffer[];
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK StatusCallbackProc(HWND hWnd,int nID,LPSTR lpStatusText)
{
if(!ghWndCap)return FALSE;//获得捕获窗的状态
capGetStatus(ghWndCap,&gCapStatus,sizeof(CAPSTATUS));//更新捕获窗的大小
SetWindowPos(ghWndCap,NULL,0,0,gCapStatus.uiImageWidth,gCapStatus.uiImageHeight,SWP_NOZORDER|SWP_NOMOVE);
if(nID==0){ //清除旧的状态信息
SetWindowText(ghWndCap,(LPSTR)"hello");
return (LRESULT)TRUE;
}//显示状态ID和状态文本
wsprintf(gachBuffer,"Status# %d: %s",nID,lpStatusText);
SetWindowText(ghWndCap,(LPSTR)gachBuffer);
return (LRESULT)TRUE;
}
LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int nErrID,LPSTR lpErrorText)
{
if(!ghWndCap)return FALSE;
if(nErrID==0)return TRUE;//清除旧的错误
wsprintf(gachBuffer,"Error# %d",nErrID);//显示错误标识和文本
MessageBox(hWnd, lpErrorText, gachBuffer,MB_OK | MB_ICONEXCLAMATION);
return (LRESULT) TRUE;
}
LRESULT CALLBACK FrameCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
{
FILE *fp;
fp=fopen("caram.dat","w");
if(!ghWndCap)return FALSE;//假设fp为一打开的.dat文件指针
fwrite(lpVHdr->lpData,1,lpVHdr->dwBufferLength,fp);
return (LRESULT)TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
static TCHAR szAppName[]=TEXT("HelloWin");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("This program requires WindowsNT!"),szAppName,MB_ICONERROR);
return 0;
}
hwnd=CreateWindow(szAppName,TEXT("The Hello Program"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch(message)
{
case WM_CREATE:
{
ghWndCap=capCreateCaptureWindow((LPSTR)"Capture Window",WS_CHILD|WS_VISIBLE,0,0,,,(HWND)hwnd,(int)0);
capSetCallbackOnError(ghWndCap,(FARPROC)ErrorCallbackProc);
capSetCallbackOnStatus(ghWndCap,(FARPROC)StatusCallbackProc);
capSetCallbackOnFrame(ghWndCap,(FARPROC)FrameCallbackProc);
capDriverConnect(ghWndCap,0); // 将捕获窗同驱动器连接
//获得驱动器的能力,相关的信息放在结构变量gCapDriverCaps中
capDriverGetCaps(ghWndCap,&gCapDriverCaps,sizeof(CAPDRIVERCAPS));
capPreviewRate(ghWndCap, ); // 设置Preview模式的显示速率
capPreview(ghWndCap, TRUE); //启动Preview模式
if(gCapDriverCaps.fHasOverlay) //检查驱动器是否有叠加能力
capOverlay(ghWndCap,TRUE); //启动Overlay模式
if(gCapDriverCaps.fHasDlgVideoSource)capDlgVideoSource(ghWndCap); //Video source 对话框
if(gCapDriverCaps.fHasDlgVideoFormat)capDlgVideoFormat(ghWndCap); // Video format 对话框
if(gCapDriverCaps.fHasDlgVideoDisplay)capDlgVideoDisplay(ghWndCap); // Video display 对话框
capFileSetCaptureFile( ghWndCap, szCaptureFile); //指定捕获文件名
capFileAlloc(ghWndCap, (L * L * 5)); //为捕获文件分配存储空间
capCaptureSequence(ghWndCap); //开始捕获视频序列
capGrabFrame(ghWndCap); //捕获单帧图像
}
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rect);
DrawText(hdc,TEXT("Hello,Windows!"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
{
capSetCallbackOnStatus(ghWndCap,NULL);
capSetCallbackOnError(ghWndCap,NULL);
capSetCallbackOnFrame(ghWndCap,NULL);
capCaptureAbort(ghWndCap);//停止捕获
capDriverDisconnect(ghWndCap); //将捕获窗同驱动器断开
PostQuitMessage(0);
}
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
javaä¸:System.out.println("String".replace('g','G')=="String".replace('g','G')); 为ä»ä¹è¿åfalse
第ä¸ä¸ªæ¯è°ç¨æ¹æ³è¿åäºä¸¤ä¸ªString对象
第äºä¸ªæ¯ä½¿ç¨äºå¸¸éæ± ï¼å¾å°çæ¯ä¸ä¸ªString对象
电脑系统苹果和微软之外的系统苹果电脑系统和windows系统的区别
一 系统除了微软系统和苹果系统以外。还有哪些操作系统。。。。目前的asp 导航站源码操作系统有很多的
大致分成三大类
第一是WINDOWS,这一类是被最广泛使用的。其中包含了WIN7,VISTA,XP,ME,,,,甚至 更早的等等。
第二类是LINUX,这一类操作系统是内核开放式的,可以自己DIY自己的系统。
第三类就是苹果操作系统了,苹果的系统据我所知只能在苹果的机子上面安装,最早的时候苹果机也是只能装苹果的系统的,因为听说以前苹果公司想垄断系统市场。但是后来WINDOWS使用率却最广也发展的很快,迫于压力苹果机子上现在也兼容了WINDOWS,但是苹果系统还是只能在苹果机上用。
现在还有ubuntu的系统
二 苹果系统和windows系统的区别
苹果的东西好(火星探测都用的苹果,图形处理方面没人能比),先进(理念和创新)苹果的系统好用,根本不象微软的系统,操作那么复杂,漏洞那么多,简单易学由于年代后期,苹果在战略决策上的失误导致年代的下滑,所以才有了WINDOWS(年代到年代初期,电脑的系统几乎全是苹果的)年代是电脑软件和硬件飞速发展的年代,苹果就这么错过了,所以苹果的软件相对于微软来说,少太多了。甚至在驱动程序方面都比较难找,这是残酷的事实。当你真正接触过苹果之后,你才会发现什么的先进,什么是艺术,什么是唯美。。每一个接触过苹果的人,都会爱上苹果的(也许有电夸张,不过是事实)苹果早就支持EFI(下一代BIOS技术),而微软呢,甚至在下一个版本的操作系统里都还不支持该技术顺便说一句,视窗操作系统是苹果的发明
三 在电脑端微软的系统和苹果的系统有什么差别
要说两个操作系统的最大不同,便是内核的不同了。这一点在上面的文字中已经说得很清楚了。如今的Mac OS X,是以BSDUNIX为基础的Darwin内核,而如今的Windows操作系统是以微软的NT技术为内核的,而NT是基于OS/2NT的基础编制的(NT所指的便是“新技术”(New Technology)之意)。当然,除去这些的不同,无论是苹果操作系统,还是Windows操作系统,都是十分易于使用的,只不过他们的某些操作方式和基本的元素定义不太一样。如果你长时间使用Windows,突然转向Mac OSX的平台,自然会感到非常的别扭,下面便是一些:窗口按钮Windows的最大化、最小化和关闭按钮位于窗口的右上角,而MacOSX则位于左上角。虽然这是一个非常小的问题,但足以让新用户迷茫半天。关闭窗口并不退出程序当你关闭一个窗口,并不会像Windows中一样退出该程序。除非使用菜单中的“退出”命令,否则该程序仍在后台运行。新Mac用户常常会留下许多程序未关闭。Mac解释:Mac用户确实不经常退出程序,和Windows不同,在后台留下二三十个程序是经常的事情,这并不会拖慢系统运行速度。菜单统一位于屏幕顶端无论程序窗口大小,该程序的菜单都在屏幕顶端显示。新Mac用户经常迷茫在程序窗口内找不到该程序的菜单。而如果使用双屏幕时,程序位于第二块屏幕,要把鼠标移回主屏幕顶部的菜单实在太远了。Mac解释:苹果的思维是这样的,你甚至不需要看屏幕,只要把鼠标一直向上就能移到菜单栏,不用在窗口中努力寻找那窄窄的一条。没有盘符和所有UNIX操作系统一样,MacOSX中的分区没有盘符。习惯了C盘、D盘的用户会极不习惯。Mac解释:卷标或者说分区名不是更好记么?理解DockWindows用户短期很难习惯MacOS X中的Dock。基本上,它可以相当于Windows中的任务栏+快速启动栏。正在运行中的android webkit 源码程序会显示在Dock中,而你也可以把任何程序或文档拖进Dock中方便使用。更改窗口大小Windows下,鼠标指向窗口的任意边缘都可以拖动更改窗口大小。而在Mac OSX下,只有在窗口右下角拖动才能实现这一功能。没有“确定键”在OSX的许多地方,你都找不到Windows中常见的“OK”确定键。比如,在设置菜单中,更改任何设置都会马上生效。当然,这要视程序而定,有些程序操作仍然需要用户确定。不存在剪贴Windows中常见的文件剪切+粘贴操作在OS X中并不存在。要想在OSX移动一个文件的位置,只有复制,然后删除原文件。Mac解释:实际上,你只要把文件从原目录拖动到新目录就行了。同名目录问题Windows下,如果复制一个文件夹和目标目录中的文件夹重名,选择“覆盖”后会是一个增量覆盖的过程。比如文件夹A包含文件1、2、3,新目录中的文件夹A包含文件2、3、4,复制完成后的文件夹A将包含1、2、3、4。而在Mac OSX下,复制时会提示是否要“替代”,选择此项完成后的文件夹A内容为1、2、3。安装程序问题Windows下存在开始-程序菜单,现在连许多Linux系统都有程序菜单,但Mac OSX中却不存在这样的地方。大多数情况下,程序会保存在“Applications”应用程序目录中,但也有一些程序并不会出现在那里。你需要在硬盘中浩瀚的目录内寻找到该程序运行。而删除程序在许多情况下也只是将文件放进垃圾箱,此时与该程序关联的一些文件并不会自动删除。Mac解释:Mac OSX下,没有注册表、DLL这些垃圾。程序和操作系统互不相干,保存着自己的设置、统计等等文件。任何一个拥有安装程序Installer的软件在安装完成后都会加入“Applications”应用程序目录,而那些无需安装的软件才需要手动将其加入。
四 现在除了微软和苹果的操作系统 还有别的吗
Windows 开发商 Microsoft
Windows/me
Windows/XP
Windows Server
Windows Vista
Windows/me是基于MS-DOS的混合的/位操作系统正慢慢的退出PC舞台了,/X
P以及Server都是基于WindowsNT的位操作系统,XP/Server已经有位版本了。
Vista是微软最新开发的版本预计在年推出。主要支持Intel,AMD,后来增加了对Power
PC,MIPS的支持。微软的操作系统基本上统治了个人PC市场,大概占了%的市场份额。
UNIX-like
AIX 开发商 IBM
AIX是Advanced Interactive eXecutive的简称,它是IBM 公司的UNIX操作系统,整个
系统的设计从网络、主机硬件系统,到操作系统完全遵守开放系统的原则.
RS/ 采用IBM 的UNIX操作系统-AIX作为其操作系统.这是一个目前操作系统界最成
功,应用领域最广,最开放的第二代的UNIX系统。它特别适合于做关键数据处理(CRITIC
AL).
支持PowerPC POWER处理器.
目前的版本是AIX 5L 5.3,
支持棵处理器,2TB内存,TB JFS2文件系统,TB JFS2文件.
HP-UX 开发商 HP
惠普公司在年随着推出位PA-处理器,开始了位技术的实施计划,它形成
了工业界运算最快的商业和工程技术应用服务器的基础。为了与先进的硬件配套,惠普公
司已经逐步地把位功能放入惠普公司在工业界领先的UNIX操作系统HP-UX。HP-UX .
和.分别具有非常大的文件系统和文件。
HP-UX .也有位版本,使得基于位PA-7X系统也可以得到HP-UX .的新功
能和特色;基于PA-8X的K系列和T系列系统的客户要在HP-UX的位或位版本之间做出选
择。惠普公司单机系统性能在工业界领先(,TPMS)的V系列系统,只可以运行位的H
P-UX .。
主要运行于HP公司的PA-系列处理器以及Intel的安腾系列处理器上.
最新的版本HP-UX i v2.
可以管理棵处理器,1TB内存,TB文件系统,最大2TB的文件。
IRIX 开发商 SGI
SGI公司最早是专门生产图形显示终端的, OpenGL标准便是由SGI提出来的.公司开发的
这个操作系统是主要运行在基于MIPS处理器的图形工作站上,年SGI收购了MIPS,年
MIPS又脱离了SGI成立MIPS技术公司.年SGI推出了基于Linux的Altix系列操作系统.
Mac OS X 开发商 Apple
Apple公司的Macintosh机上的操作系统, 苹果机主要用于图形领域,在图形处理领域占
有很大市场份额。Mac OS是首个在商用领域成功的图形用户界操作系统。Mac OS9及以前的
版本都在搭在苹果机上销售的。它不支持其它设备,每当有新的设备时都要通过添加扩展
来支持设备。新的Mac OS X结合BSDUnix、NeXTStep和Mac OS 9的元素。采用Unix风格的内
存管理和抢占式多任务处理,它的最底层建基于BSDUnix的内核,实行的是部分开放源代码
现行的最新的系统版本是Mac OS X v.4.2。
只能运行在PowerPC G3以上处理器的mina 2.0 源码苹果机上,苹果公司正在跟Intel合作,表示以后
苹果机会采用x处理器。
Solaris 开发商 SUN
最早也是基于BSD Unix开发的,那时就直接叫Sun OS,从Sun OS5以后就以Solaris的
名字面市,从Solaris开始它也是免费开源的软件了,开始主要是为SPARC和x写的,后来
经过一些改动也可以支持一大批的处理器.Solaris开始支持位处理器.
FreeBSD 开发者 Nate Williams,Rod Grimes,Jordan Hubbard.
Bill Jolitz的 BSD发展形成3个分支FreeBSD,NetBSD,OpenBSD了,这些都是免费的
开源操作系统。第一张FreeBSD光盘是在年月发布的。
FreeBSD 是一个在个人电脑上执行的作业系统,主要支持x处理器,其他跟 Intel 相
容的 CPU 如 AMD 跟 Cyrix也被支持。
FreeBSD 能提供你许多昂贵工作站才有的先进功能,这些特色包括:
抢占式多任务处理.
完整的 TCP/IP 网路功能 包含 SLIP, PPP, NFS 跟 NIS。
内存保护(Memory protection) 能确保一个使用者不能打扰其他人。而一个应用程式
也不能影响其他的程式。
标准的 X 视窗系统 (X Window, XR6) 提供良好的图形用户接口(GUI)以便在一般的
VGA 显示卡以及萤幕上使用, 并且提供完整的原始程式码。
能直接执行在其他作业系统 (如 SCO, BSDI, NetBSD, Linux 跟 BSD)上编译的 (
Binary) 程式。
数以千计 可以直接执行(ready-to-run) 的应用程式, 可以在 FreeBSD ports 及 pa
ckages 中找到。 免去你上网路到处找软体的苦境。
需要时才置换的虚拟记忆体(Demand paged virtual memory 以及合理的虚拟记忆体及
档案缓冲区之缓冲功能(merged VM/buffer cache)
NetBSD 开发者 NetBSD小组
NetBSD是一种完全免费的类UNIX操作系统,它是一个重于夸平台应用的BSD分支,它支
持多种硬件平台,具有高度可移植性和硬件平台兼容性.它可以运行在从位alpha服务器
到手持设备的多种硬件平台上.NetBSD的清晰设计以及它的众多高级特性使得它不论作为产
品还是研究环境都表现得非常出色。而且它对用户在资源上进行全方位的支持。其上的应
用程序很多都可以非常容易地获得。
OpenBSD 开发者 由NetBSD的前核心成员Theo de Raddt领导的一个开发小组。
OpenBSD由NetBSD分支出的计划,
它是一个免费、多平台、基于4.4BSD的类Unix操作系统。目标在于强调正确性、安全
性、标准化以及可移植性。着重于安全性,致力于成为最安全的操作系统。OpenBSD支持包
括SVR4(Solaris),FreeBSD,Linux,BSDI,SunOS和HPUX等大部分二进制的模拟。
Linux
RedHat/Fedora 开发商 RedHat.Inc
Redhat linux是最早的Linux发行版本之一,也是最早使用软件管理包RPM的Linux版本
, Redhat 自9.0以后,不再发布桌面版的,而是把这个项目与开源社区合作,于是就有了
Fedora 这个 Linux 发行版。最新版本是FC4.0.
Slackware 开发商Slackware Linux, Inc
Slackware Linux是由Patrick Volkerding开发的GNU/Linux发行版。与很多其他的发
行版不同,它坚持KISS(Keep It Simple Stupid)的原则,就是说没有任何配置系统的图形
界面工具。一开始,配置系统会有一些困难,但是更有经验的用户会喜欢这种方式的透明
性和灵活性。
Slackware Linux的另一个突出的特性也符合KISS原则:Slackware没有如RPM之类的成
熟的软件包管理器。Slackware的软件包都是通常的tgz(tar/gzip)格式文件再加上安装脚
本。Tgz对于有经验的用户来说,比RPM更为强大,并避免了RPM之类管理器的依赖性问题。
Slackware还有一个众所周知的特性就是BSD风格的初始化脚本。Slackware对所有的运行级
(runlevel)/任务都用同一个脚本,而不是在不同的运行级中建立一堆脚本的链接。这样让
你不必自己写新的脚本就能很容易地调整系统。
Debian 开发商Debian project
Debian 以其忠于Unix和自由软件以及丰富的选择出名,它的最新版本包含有5万个软件
包,支持十一种体系结构,从ARM到IBM S,以及个人电脑上的x到PowerPC.它的软包管理
工具APT一样有名.最新发布版本是Debian3.1也叫sarge
Mandriva 开发商 Conectiva
Mandriva Linux的前身是欧洲最大的Linux厂商之一Mandrakesoft,长期以来Mandrak
e Linux以最为方便、易用、华丽的Linux发行版着称。Mandrake Linux早期方便的字体安
装工具和默认的中文支持,为Linux普及做出了很大的贡献。但是年前后Mandrakesof
t陷入财务危机,濒临破产。公司于年2月日与拉丁美洲最大的Linux厂商Conectiva
达成了收购协议,金额为万欧元,新公司旗下品牌Mandrake Linux更名为Mandriva Li
nux。Mandriva以rpm作为软件管理工具,部分兼容Red Hat Linux/Fedora Core的预编译包
.
SuSE 开发商 Novell
SUSE LINUX是德国的一个发行版,原是以Slackware Linux为基础,并提供完整德文使
用界面的产品,年Novell收购了SUSE.
Gentoo
Gentoo Linux为用户提供了大量的应用程序源代码。Gentoo Linux的每一部分都可以
在最终用户的系统上重新编译建造,甚至包括最基本的系统库和编译器自身。 通过依赖关
系描述和源代码镜像的形式提供软件,Gentoo Linux提供了大量软件供用户选择。 标准的
源代码镜像包括G的数据。 选择不仅在软件整体方面,也存在于软件的内部。由于可以
在本地编译软件,参数和变量的选择可以由用户自己指定。
事实上,在软件的安装和升级方面,Gentoo拥有自己独特的优势。由于Portage技术的
产生,Gentoo Linux可以担当一个理想的安全服务器、开发平台、专业级桌面应用、游戏
服务器、嵌入式应用等等各种角色。由于其无限制的可配置性,我们甚至可以称Gentoo L
inux为一个准发行版。
嵌入式式操作系统.
uClinux
uClinux是一种优秀的嵌入式Linux版本。uclinux是一个源码开放的操作系统,面向没
有MMU(Memory Management Unit)的硬件平台。同标准Linux相比,asp源码 电力它集成了标准Linux操
作系统的稳定性、强大网络功能和出色的文件系,它是完全免费的.
uC/OS II 开发商 Micrium
抢占式实时多任务实时操作系统,可以管理个任务,开源的嵌式操作系统,商业应用需
要得到Micrium公司的授权,
VxWorks 开发商 WindRiver
VxWorks操作系统是美国风河(WindRiver)公司于年设计开发的一种嵌入式实时操
作系统(RTOS),是嵌入式开发环境的关键组成部分。良好的持续发展能力、高性能的内
核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地。它以其良好的可
靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求
极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。在美国的 F-、FA-
战斗机、B-2 隐形轰炸机和爱国者导弹上,甚至连年7月在火星表面登陆的火星探测
器上也使用到了VxWorks
VxWorks 的实时性做得非常好,其系统本身的开销很小,进程调度、进程间通信、中
断处理等系统公用程序精练而有效,它们造成的延迟很短。
PalmOS 开发商 PalmSource,Inc
早期由US Robotics(其后被3Com收购,再独立改名为Palm公司)研制的专门用于其产
品"Palm"的操作系统。主要用于PDA产器
WindowsCE 开发商 Microsoft
它是微软针对个人电脑以外的电脑产品所研发的嵌入式操作系统,而CE则为Customer
Embedded的缩写。
五 苹果MAC系统和WINDOWS系统的差别
1、体系模型
window是开放的平台,由系统统筹整体IT产业链条。硬件需要根据系统来走。因为的他的开放性,所以window成为最普及和用户最多的系统。
它就像规划师,安排好硬件,软件适应window的匹配标准,然后大家一起来干吧。这种模式的优点就是成本低,市场成熟度快,众人拾柴火焰高。缺点就是稳定性与性能发挥,相对来说,稍有不足。
MAC是反其道而行之,它的系统仅仅适配自己的硬件,它的软件必须通过app store购买。这种模式的优点就是软件与硬件高度的适配,稳定性与性能超强发挥。所以为什么window电脑用上3年就会卡,mac依然流畅如云。
2、软件安装
mac没有所谓的安装目录与注册表。安装简洁方便。重要的是mac里面的软件没有window里的软件安装时候流软件。这点让人超级省心。
3、续航
台式机不存在这个问题,笔记本这个影响很大,mac可以保持工作5个小时以上,window普遍都在2-3个小时,用上2年以上,就更差了。现在有些高端的window笔记本号称可以达8个小时,一般也就在5小时,都是比较高端的笔记本。
4、游戏
Mac的游戏从数量上以及兼容性上就和windows没有可比性。
5、性能
MAC对游戏性能不如Windows,而办公设计Windows不如MAC。
6、软件丰富度
日常基本软件大家都有,windows的兼容开放场景都比mac系统多。
(5)电脑系统苹果和微软之外的系统:
Mac OS X Lion是苹果首款通过Mac App Store提供数字版本下载的Mac操作系统,不过其4GB的容量可能会让不少网络条件不好的用户感到头疼,所以苹果此次专门为OS X Lion推出了一款预装U盘。
OS X Mountain Lion 中没有了苹果即时通信工具 iChat,替代它的是更为好用的 Messages 应用。就是 iOS 平台的 iMessage,苹果认为它能做 iChat 做的一切事情,甚至能做更多。
Messages 可以在 Mac 上和任何运行有 iOS 5 的 iPhone、iPad、iPod touch 进行无限制的即时通信:发送、视频、文档、通讯录——甚至群发短信。
六 除了windows和苹果外,还有其他的操作系统吗
linux,可以安装一个模拟windows的android asmack 源码软件
免费的,很多版本,最安全的系统
opensuse,redhat……等版本
七 苹果电脑系统和windows系统的区别
1、体系模型
window是开放的平台。
MAC的系统仅仅适配自己的硬件,它的软件必须通过app store购买。
2、续航
对于笔记本来说,mac可以保持工作5个小时以上,window普遍都在2-3个小时。
3、性能
MAC对游戏性能不如Windows,而办公设计Windows不如MAC。
Windows操作系统的特点
1、人机操作性优异
Windows操作系统界面友好,窗口制作优美,操作动作易学,多代系统之间有良好的传承,计算机资源管理效率较高,效果较好。
2、支持的应用软件较多
Windows操作系统的大量应用软件为客户提供了方便。这些应用软件门类全,功能完善,用户体验性好。
3、对硬件支持良好
Windows操作系统支持多种硬件平台对于硬件生产厂商宽泛、自由的开发环境,激励了这些硬件公司选择与Windows操作系统相匹配,也激励了Windows操作系统不断完善和改进,同时,硬件技术的提升,也为操作系统功能拓展提供了支撑。
八 除了微软和苹果有操作系统外,还有哪些系统
操作系统有上千种,科学领域
军用
公司用
个人用的
开源与非开源。。。就当当微软的也分不同用途有好多种
每一种又有几个版本。windows
server
专业版
企业版
(网络操作系统,主要应用是搭建各种应用服务器)
九 操作系统除了WINDOWS 和 苹果的 还有哪些
早期操作系统(专利保护)TRS-DOS,ROM OS's TI-4 Commodore PET,,和 VIC-, 第一套IBM-PC 苹果电脑 Sinclair Micro和QnX等 非Unix商业操作系统CPM操作系统 MP/M- UCSD P-system Mini-FLEX SSB-DOS CP/M- DR-DOS FreeDOS MS-DOS PC-DOS Mach 由卡纳尼基梅隆大学研究 L4微内核 第二代微内核 CHORUS Choices Multics OS-9 NSJ Netware:一种网络服务器操作系统 Unix及类似系统A/UX(Apple UNIX) Unix 微软Xenix ChorusOS Cromix UNIflex OS-9 IBM的AIX BSD FreeBSD NetBSD OpenBSD DragonFly BSD PC-BSD Digital UNIX,即之后康柏Tru DNIX HP的HP-UX GNU/Hurd SGI的IRIX Inferno Linux(或称GNU/Linux) Mac OS X MenuetOS Minix OSF/1 Plan9 SCO的SCO UNIX Sun的SunOS,即之后的Solaris System V Ultrix UniCOS 麒麟操作系统(Kylin),由国防科技大学、中软公司、联想公司、浪潮公司和民族恒星公司五家单位合作研制的服务器操作系统 OS/ z/OS Syllable 其他AcornArthur ARX RISC OS RISCiX AmigaAmigaOS Atari STTOS MultiTOS MiNT 苹果电脑(Apple/Macintosh)Apple DOS ProDOS Mac OS Mac OS X pink OS BeOS A/UX BeBeOS BeIA Digital/康柏(Compaq)AIS OS-8 RSTS/E RSX- RT- TOPS- TOPS- VMS(后更名为OpenVMS) IBMOS/2 AIX OS/ OS/ VM/CMS DOS/VSE VSE/SP VSE/ESA OS/ MFT MVT SVS MVS TPF ALCS z/OS PC-DOS pink OS 微软(Microsoft)MS-DOS Xenix Microsoft Bob 基于MS-DOS操作系统的Windows Windows 1.0 Windows 2.0 Windows 3.1 Windows Windows Windows ME Windows NT Windows NT 3.5 Windows NT 4 Windows Windows XP Windows XP SP1Windows XP SP2Windows XP SP3Windows XPWindows XP Media Center Edition Windows XP Home Edition Windows XP Professional Windows XP Professional x Edition Windows Server Windows Server -bit Edition Windows Vista Windows VistaSP1Windows Vista Home Basic Windows Vista Home Premium Windows Vista Business Windows Vista Ultimate Windows Vista Enterprise Windows Vista Starter NovellNetWare Unixware SUSE Linux NeXTNEXTSTEP(即之后的Mac OS X) Plan 9 Inferno Prime ComputerPrimos 西门子BS - 用于西门子公司的大型主机。 SINIX(也称Reliant UNIX) - 用于西门子公司的UNIX电脑系统。 个人电子助理(PDA)操作系统Palm OS Pocket PC EPOC Microsoft Windows CE Linux 智能手机操作系统Windows Mobile系列 Embedded Linux由Montavista创造,在Motorola's A,E等机型上使用 Mobilinux由Montavista创造 Symbian OS系列 其他操作系统动态可扩展操作系统 MIT的Exo Kernel 华盛顿大学的 SPIN 哈佛大学的 VINO illinois大学的Choices ReactOS
UE5.1卡通渲染管线修改 学习笔记(改源码版)
UE5.1的卡通渲染管线修改笔记
起始于提升MMD制作质量的需求,从C4D的octane到Blender的Eevee和Cycle,再到现在的UE5,探索了各种卡渲方法,包括后处理和自发光。现在转向直接修改源码,回顾过去发现自己的学习路径混乱,缺乏记录,因此决定补写这篇学习笔记,以供参考。
在探索过程中,我借鉴了前辈们在卡通渲染领域的成果,通过预加载ToonShaderShadowAtlas和ToonShaderSpecularAtlas两个曲线图谱,以及相应的Sampler和高度参数。添加ShadingModel时,我选择了Toon、ToonSSP和ToonSDF,涉及了阴影重映射、高光重映射,以及整体阴影着色的优化。
对于KajiyaKai高光,我利用Anisotropy作为输入,并通过一个参数控制是否启用。SDF阴影着色方面,尝试将算法内置Shader以解决现有问题,尽管初期尝试受限。扩展GBuffer以适应新增ShadingModel的需求,特别关注了ToonData的处理。
在Material文件夹中,我创建了MaterialExpressionToonShaderCustomOutput,结合ToonCurve选择、环境反射、SDF输入等功能,实现了定制化的输出。同时,我还注意到了Lumen修正和BackFace方案的选用。
UE5.1版本中,修改CreateToonOutLinePassProcessor是关键步骤,以处理超过个Pass的问题。尽管扩展ShadingModel上限的方案暂未使用,但已做了相关笔记,涉及GBufferInfo、ShaderGenerationUtil和EngineType的改动。
总结来说,本文记录了从理论学习到实践应用的UE5.1卡通渲染管线修改过程,供后来者参考和学习。
UE5实践1.配置环境以及简单的shadingmodel添加
环境配置:使用Windows 系统,Unreal引擎版本5.0.2,Rider版本.1.1,Epic Games。首先,需要关联GitHub账户以访问私有引擎源码,通过github.com/EpicGames/Unreal获取源码。
构建项目:解压源码后,执行Setup命令,等待下载引擎文件,大约需时G左右,注意预留足够的磁盘空间。接着运行GenerateProjectFiles生成项目文件,此时可以看到.sln文件,可使用Rider或Visual Studio打开并构建项目。构建过程中可能会耗时较长,例如在晚上:开始构建,次日3:左右完成,最终成功启动引擎。
解决BUG:启动引擎后可能会遇到模块加载问题,这通常与使用Rider导致的插件加载问题有关。解决方法是在代码中将相关插件的EnabledByDefault属性设置为false即可。
自定义着色模型:在配置环境后,可以参考相关文章进行自定义着色模型的添加。具体步骤包括修改C++文件中的EngineTypes.h、MaterialShader.cpp、Material.cpp、MaterialShared.cpp等文件,以实现着色模型的添加。同时,需要修改HLSLMaterialTranslator.cpp、ShaderMaterial.h、ShaderMaterialDerivedHelpers.cpp、ShaderGenerationUtil.cpp等文件,以完成Gbuffer的写入。此外,调整PixelInspectorResult.h、PixelInspectorResult.cpp、PixelInspectorDetailsCustomization.cpp等文件,以优化序列化显示。
修改着色模型部分:通过修改ShadingCommon.ush、Definitions.usf、BasePassCommon.ush、DeferredShadingCommon.ush、ShadingModelsMaterial.ush等文件,实现自定义着色模型的添加。同时,需要调整ToonShadingCommon.ush、ShadingModels.ush、BasePassPixelShader.usf文件,以支持多光源的自定义着色模型。
最终效果:通过上述步骤,可以实现自定义着色模型的添加,支持多光源渲染,并得到支持多光源的CustomShadingModel效果。此外,还存在一种无需修改引擎代码的方法实现自定义着色模型。
Android性能优化:定性和定位Android图形性能问题——以后台录屏进程为例
简介发现、定性与定位
总结
跟不上旋律节奏的VSYNC
严重异常耗时的dequeueBuffer
VirtualDisplay合成耗时
结论
FPS
初步定位问题
定性问题
定位问题
成果展示
参考
简介本文记录一次Android图形性能问题的分析过程——发现、定性和定位图形性能问题,以及探讨的性能优化方案。
环境:Android Q + MTK + ARM Mali-G。
所分析的性能问题(下称case):打开录屏应用并启动后台录屏,滑动前台应用(滑屏)。性能表现差:CPU、GPU负载显著升高、掉帧、用户明显卡顿感,帧率不足帧,帧渲染、合成耗时急剧飙升(渲染耗时平均为ms左右)。
经过优化后,相同环境和条件下,渲染帧率稳定在帧(提升一倍),渲染耗时平均为8.ms左右(为优化前的不到三分之一的消耗)。
关键词 Keywords: Screen Recording; Frame rate; FPS; GPU utilization; Jank; MediaProjection; VirtualDisplay; MediaCodec; Perfetto; Inferno; Surface; SurfaceTexture; VSYNC; SurfaceFlinger; HWC; Hardware composer; GPU; OpenGL;
发现、定性与定位FPS计算FPS的方法和工具 Android框架层通过hwui配合底层完成渲染。该框架本身提供了逐帧渲染分段耗时记录。通过dumpsys gfxinfo可以获取。
io.microshow.screenrecorder/io.microshow.screenrecorder.activity.MainActivity/android.view.ViewRootImpl@6b9b8a9?(visibility=0)DrawPrepare?Process?Execute3...................1................使用工具统计帧率与平均耗时(同时打印GPU负载),在开启后台录屏的情况下滑动屏幕,平均渲染耗时高达~ms,超出.ms一倍,导致帧率仅帧,显著低于帧。
Average?elapsed?.?msFPS:??│?9.?0.?.?2.#?GPU负载?LOADING?BLOCKING?IDLE?0?#?case的对比——未开启后台录屏Average?elapsed?9.?msFPS:??│?1.?0.?5.?1.通过gfx柱状图直观感受性能数据 直观地感受图形渲染性能,除了帧率感受、触控延时外,还可以通过将gfxinfo的分段耗时通过柱状图展示在屏幕上。
这是case性能问题的gfxinfo柱状图,可以看到红柱和绿柱都非常高,远远超越了流畅标准。其中,绿柱异常放大表明两个Vsync之间耗时显著增长,红柱异常放大表明应用层应用加速使用的DisplayLists大量增长、或图形层使用GLES调用GPU耗时显著增多导致的GPU执行绘制指令耗时变长。
初步定位问题本节记录初步的分析思路和定位过程。首先我们完成实验(启停后台录屏并滑动屏幕触发渲染)、观测以及记录,拿到了后台录屏启停情况下的FPS、分阶段耗时以及GPU负载(相关数据位于FPS小节)。
开发的工具输出的统计数据计算结果非常直观,一眼可见,后台录屏为Draw阶段带来额外的~8倍或~8ms耗时,给Process阶段带来额外的~2倍或~ms耗时。帧率从帧坠落到~帧。
耗时分析 可以看到,主要的额外耗时来自Draw和Process。接下来重点围绕着两part定位问题问题。
StageDescriptionCompDraw创建DisplayLists的耗时。Android的View如果支持硬件加速,绘制工作均通过DisplayLists由GPU绘制,可以处理为onDraw的耗时额外~8ms或~8倍Prepare准备没有额外耗时ProcessDisplayLists执行耗时。即硬件加速机制下提交给GPU绘制的工作耗时额外~ms或~2倍ExecuteFramebuffer前后缓冲区flip动作的耗时,上屏耗时额外不到~1msHz下,上述4个步骤合计耗时小于.ms为正常情况。case为~ms。主要增量来自Draw和Process。
经过上述初步分析、观测后,接下来的分析可以围绕Draw和Process开展。由于Android Draw部分涉及较广,包含App 渲染线程(DisplayLists)、UI线程(onDraw方法创建DisplayLists),以及图形栈耗时如SurfaceFlinger、RenderEngine等都可能增加Draw耗时。
这里一个技巧可以初步判断耗时来自App进程(渲染线程和UI线程)还是来自图形栈。如果能判断耗时来自App或图形栈,那么可以缩小分析范围、减少分析工作量。上述四大阶段的耗时统计分类比较宽,实际上还有更详细的分阶段耗时,它呈现在前文描述过的gfx统计信息柱状图上。gfx柱状图会以蓝色(RGB(,,))呈现onDraw方法创建和更新DisplayLists的耗时。如果case与正常情况对比后,这部分耗时(蓝柱大小对比)差异很小,即可说明额外的Draw耗时不是来自App的,极可能来自图形栈。Besides,结合过度绘制分析,判断case与正常情况下是否有更多的额外绘制次数可以协同判断。
——根据上述指导思想,排查出了case的额外Draw耗时与App onDraw无关,多出来的DisplayLists来自App以外的进程,可能是图形栈如SurfaceFlinger。
定性问题本小节介绍问题追踪过程,通过一些方法定位到各阶段的耗时原因,并定性地得出case性能问题的性质。从本小节开始,围绕Perfetto进行分析。这里贴出perfetto的总览,我将关键的信息排序到顶部。前四行分别为SF负责图形的线程、提交到GPU等待完成的工作、Vsync-App、Vsync-sf,最后两行为case中出现卡顿掉帧的App的主线程(UI)和渲染线程(RenderThread)。
跟不上旋律节奏的VSYNC容易看到,Vsync-sf非常不规律。Vsync-sf是触发SurfaceFlinger一次合成工作的基于Hardware VSYNC虚拟出来的一个信号。它相对于真实硬件信号(HW_VSYNC)一个规律的偏移(在case设备上,Vsync-app与Vsync-sf都被配置为8.3ms,即硬件VSYNC到达后,虚拟的Vsync-app和Vsync-sf延时8.3ms后发出,分别触发App绘制、SurfaceFlinger合成。
而case的Vsync-sf交错、残次、不齐、无规律,显然工况不佳。它将导致SurfaceFlinger不能按照预期的时间间隔将合成的帧提交到Framebuffer(经过Flip后,被提交的Framebuffer将上屏成为显示器的下一帧图像),出现掉帧/丢帧。
As we can see,case的VSYNC-sf出现严重的漂移(见图,第二行的VSYNC-sf残次不齐、跟不上规律、难看且混乱),这导致了丢帧。(但VSYNC-sf的失控仅表示与丢帧的相关性,并不直接表明因果性。)
VSYNC-sf为什么会出现偏差? 出于功耗的考虑,VSYNC-sf合VSYNC-app并不是一定会触发的。如果app或sf并没有更新画面的需求,那么死板固定地调度它们进行绘制和合成是不必的。编程上,负责触发VSYNC-sf和VSYNC-app的两个EventThread会在requestNextVsync调用后才会将下一个VSYNC-sf或VSYNC-app发出。因此,当(各自EventThread的)requestNextVsync没有调用时,VSYNC-app和VSYNC-sf也就出现漂移。BufferQueueLayer::onFrameAvailable会在应用提交后调用,该方法通过调用SF的signalLayerUpdate触发产生下一个VSYNC-sf。
换而言之,出于功耗,或别的什么原因(比如耗时导致的延期,人家是线程实现的消息队列),SurfaceFlinger的SFEventThread有可能不调用requestNextVsync,这将导致Vsync-sf在窗口期内短暂消失——但是也不会出现参差不齐的情况。结合case的VSYNC信号报告来看,VSYNC-sf信号异常切实地提示了性能问题——它的不规律现象表明前后Vsync之间有异常耗时,而非低功耗机制被激活或无屏幕刷新(case性能问题复现时一直在滑前台应用的屏,它每ms都有画面更新的需求)。
VSYNC-sf虽然出现了偏差,但是它与卡顿问题仅有相关性(或者说它是性能问题的结果),并非因果关系。猜测是其他卡顿问题导致了SF延缓了对VSYNC的request,导致其信号出现漂移。VSYNC-sf信号偏差实质上指导意义重大,因为它能提示我们,问题发生在比App更底层的地方(前文分析的结论),且比SurfaceFlinger提交到Framebuffer更上层的位置(VSYNC-sf用于触发合成,合成完成后提交到屏幕双缓冲区)。
这样,将case性能问题的上下界都确定了,问题分析范围从原先的整个图形栈,有效的缩小到了SurfaceFlinger渲染和合成阶段了。
严重异常耗时的dequeueBuffer通读Perfetto,可以看到,出了难看的Vsync-sf以外,还可以看到刺眼的超长耗时的draw(App UI线程)以及耗时变态长的dequeueBuffer(App 渲染线程)调用。相对于正常情况,perfetto报告提示的case的draw方法成倍增长的耗时非常容易被误认为耗时“居然来自一开始就排除掉的App进程",这与前文提出的”问题范围“是不能自洽的——它们是相反的结论,肯定哪里不对。仔细分析才能发现,draw方法确实是消耗了更多墙上时间(但是不意味着消耗了更多CPU时间,因为等待过程是sleep的),但是draw方法是因为等待渲染线程的dequeueBuffer造成的耗时,而dequeueBuffer的严重异常耗时却是被底层的图形栈拖累的。
我们看到,draw严重耗时,渲染线程dequeueBuffer消耗掉~ms的时间。As we all known,Android的Graphics buffer是生产者消费者模型,当作为消费者的SF来不及处理buffer并释放,渲染线程也就需要额外耗时等待buffer就绪。上面还有一段"Waiting GPU Completion"的trace没有贴上来(下图),这段耗时比不开启后台录屏的case下高得多(~3ms对比~ms),说明了一定的GPU性能问题或SF的性能问题,甚至有可能是Display有问题(HWC release耗时过长也会导致SF释放buf、生产者渲染线程dequeueBuffer额外等待)。
这里的机制比较复杂,不熟悉底层Graphics buffer的流水线模型就不好理解。In one world, dequeueBuffer申请的buffer不是凭空new出来的,而是在App-SurfaceFlinger-Framebuffer这一流水线中循环使用的。流水线中的buffer不是无限的,而是有穷的几个。当底层的伙计,如SF和HWC,使用了buffer但是没有来得及释放时(它们的工作没做完之前不会释放buffer),流水线(可以理解成头尾相接的单向队列(ring buffer))没有可用的buffer,此时dequeueBuffer就不得不进入等待,出现耗时看上去很长的问题。实际上,dequeueBuffer耗时的唯一原因几乎仅仅只有一个:底层消费太慢了,流水线没有剩余buffer,因此需要等待。
这个模型抽象理解非常简单。下图,右边消费者是底层图形栈——它每消费完一个buffer就会释放掉,每释放一个buffer应用层能用的buffer就加1。左边生产者是App渲染线程——它调用dequeueBuffer申请一个buffer以将它的画面绘制到这个buffer上。buffer送入BufferQueue后由右边的消费者(图形栈)进行消费(合成、上屏显示),然后释放buffer。当图形栈来不及release buffer时,dequeueBuffer的调用者(App渲染线程)将由于无可用buffer,就必须挂起等待了,在perfetto上就留下长长的一段”耗时“(实际上是墙上时间,大部分都没有占用CPU)。
以上,这就是为什么说App渲染线程dequeueBuffer严重耗时中的耗时为什么要打引号,为什么要说是被图形层拖累了。
下图可以看到,刨去dequeueBuffer的严重异常耗时,执行渲染的部分耗时相对于正常的case几乎没有差异,这可以断言渲染线程的惨烈耗时主要就是被dequeueBuffer浪费了。
从GPU Completion来看,此时GPU正在为SF工作,因为在图中看到(不好意思没有截全,下图你是看不出来的),dequeueBuffer总是在SF的GPU Completion结束之后结束的,这就表明SF正在通过GPU消费buffer(调用GPU进行合成后提交,然后标记buffer允许被渲染线程dequeue)。dequeueBuffer获取到就绪的buffer此时此刻取决于SF的消费能力——因为case中它是短板。(当然图形层的buffer可用不止SurfaceFlinger需要释放,因为SF释放后buffer实质上流转到更底层的HWC,等它将Buffer提交到屏幕后才会释放,这里释放后才能给App再次使用(上面哪个模型图把SF和HWC合并为流水线的图形层buffer消费者)。
从perfetto报告看HWC release非常及时、余量充足,SF的GPU Completion则较紧密地接着dequeueBuffer返回,基本断言是SF太慢了——排除HWC的责任。(下图看不出来,当时没有截图到HWC的release情况。)
到这里,除了再次确认排除了前台App的问题外,还可以断言问题来自SurfaceFlinger过分耗时。此外将问题范围的下界从整个SF合成流程(上文的Vsync-sf)缩小到了排除HWC的范围。
结论:渲染耗时一切正常,问题出现在SF消费buffer(合成图形)失速了,导致没有可用的buffer供渲染线程使用。从下图的SF的工况(第三列)来看,情况确实如此。
既然一口咬定是SF的锅,那就瞧瞧SF。先看SF的INVALIDATE,这没啥好看的,异常case和正常case都是~2.5ms。主要看refresh,正常case ~6.8ms,异常case ~.8ms。refresh包含SF的合成四件套,包括rebuildLayerStack、CalcuateWorkingSet、Prepare、doComposition。Perfetto报告直接表明,case的后台录屏导致的额外一次合成和配套工作是主要的耗时增量。
之所以会执行两次合成,是因为后台录屏工具编程上通过Android SDK提供的MediaProjection配合VirtualDisplay实现一个虚拟的镜像的屏幕。SurfaceFlinger会将画面输送一份到这个虚拟的Display以实现屏幕图像传送到录屏工具,虚拟的屏幕要求额外的一次合成。从上图可以直接得出结论,case带来的额外工作消耗就是对该录屏用的VirtualDisplay的合成工作(doComposition)带来的。
VirtualDisplay合成耗时由于问题范围已经缩小到了很小的一个范围,在SurfaceFlinger的Refresh过程中,case相对正常应用有巨大的差异耗时,几乎完全来自于对VirtualDisplay的合成耗时(doComposition)。同时也可以看到,两次合成(一次是设备的物理屏幕,一次是case的后台录屏工具创建的虚拟屏幕)中,虚拟屏幕的耗时远远高于物理屏幕(4倍以上)。
通过查看ATRACE的tag(上图,Perfetto中SurfaceFlinger中主线程的各个trace point都是用ATRACE打的tag),结合dumpsys SurfaceFlinger,能直接看到的线索是:
虚拟屏显著耗时,且合成工作通过GLES调用GPU完成
物理屏合成耗时很小,它通过HWC合成
结合图中提示的trace tag、耗时,可以得出结论,使用GPU合成的虚拟屏中因GPU合成耗时很长,导致它显著高于物理屏HWC合成耗时。如果GPU合成能够和HWC合成一样快,或者干脆让虚拟屏也使用HWC合成,那么可以预期SurfaceFlinger的合成工作的消耗将显著降低。
结论本小节综合上述三个小节的分析,对节”定性问题“下一个结论。
耗时的本质已经被看透,录屏工具申请创建的VirtualDisplay没有通过HWC进行合成,而是通过GPU进行合成,它耗时很长导致界面卡顿。In one word,case使用的VirtualDisplay的合成方式不够高效。
HWC是Hardward Composer。它接收图形数据,类似于往桌面(真的桌面,不是电脑和手机的桌面)上面叠放照片和纸张——即合成过程。这个工作能将界面上几个窗口叠加在一起后送到屏幕上显示。通过GLES调动GPU也能干这活,不过HWC执行合成的动作是纯硬件的——它很快,比GPU快几倍。
定位问题前面虽然定性了问题原因是合成方式不够高效,但是没有得出其中的原理——为什么虚拟屏不使用高效的HWC进行合成。本节通过介绍HWC的原理、SurfaceFlinger控制合成方式、虚拟屏Surface特性等来介绍图形栈中合成方式的处理模式。掌握了相关管理后,探讨一些尽量通用的共性的解决方案实现性能优化。最后着重介绍多套优化方案中的一种直面根本原因的解决方法——MediaCodec.MediaFormat创建的支持HWC合成的Surface方案。
SurfaceFlinger如何决定使用HWC还是GPU合成? SurfaceFlinger合成主要可以依靠两条路径。其中之一是”纯硬“的HWC合成(在dumpsys SurfaceFlinger中可以看到Composition type为DEVICE),另一个是通过OpenGL让GPU进行合成(Composition type为CLIENT)。
除非是功耗上的设计,否则SurfaceFlinger总是会优先检查本次合成是否支持使用HWC。编程上,在合成阶段之一的prepare过程中,SurfaceFlinger通过prepareFrame在RenderSurface与Hardware Composer(即HWC)的HIDL服务通信,完成hwc layer的创建。但是,layer能够成功创建不意味着一定支持HWC合成。SurfaceFlinger通过getChangedCompositionTypes向HWC查询不支持HWC合成的Layer。该方法返回的layer如果被标记为CLIENT合成,那么这部分Layer无法由HWC进行合成,而只能通过GPU进行合成——case的VirtualDisplay就是这个情况。
部分layer可能不能由HWC合成的原因(除功耗策略、其他软件策略外):
HWC layer达到上限 Hardware Composer支持的layer数量是有限的。查阅公开资料可知,HWC合成动作属于硬件提供的能力,它们的合成能力受到硬件本身的限制。Google官方资料对Android设备的要求是,HWC最少应该支持4个Layer,分别用于一个常规页面上最常见的4个层:壁纸、状态栏、导航栏和应用窗口。 在case设备中,经过测试,该平台的HWC最多支持7个能进行HWC合成的layer,从第8个layer开始,完完全全只能使用CLIENT合成亦即SurfaceFlinger调用RenderEngine通过OpenGL调动GPU进行合成。 正是由于HWC合成layer有上限,因此在弹出多个弹窗、叠加过于复杂时,即使界面简单也有可能出现比较明显的卡顿。
VirtualDisplay的Surface格式不受HWC支持 HWC的硬件合成能力对buffer(Surface封装)内保存的图像的格式有要求。比如,HWC不能处理缩放,仅支持一部分的格式,大多数都还有其他因素会导致不支持,如旋转、部分Alpha等等。In one word,图像格式的数量是远远多于HWC支持的类型数的。当HWC碰到不支持合成的Surface时,就会在前文提过的getChangedCompositionTypes中通知SurfaceFlinger,由SurfaceFlinger转为使用GPU合成。
结合上述几种情况,设计实验验证。其中通过在物理屏上弹窗来增加Layer以获取HWC Layer上限。确认case无法使用HWC合成不是Layer上限导致的问题后,通过对比来验证Surface格式问题。Surface是对native层的buffer的封装,其类型广泛、实现复杂,一个一个试是不现实的。通过对比性能强劲的类似实现可以一探究竟。Android adb提供一个出厂自带的录屏命令screenrecord、用于测试双屏显示功能的虚拟辅助屏幕(开发者模式-模拟辅助屏)、著名远程窥屏工具scrcpy等三个工具是一系列重要参考。
经过测试,screenrecord和scrcpy创建的VirtualDisplay支持HWC合成——这是优化目标。首先看看它们的实现。
编程上,虚拟辅助屏幕采用了与case一模一样的实现——通过创建VirtualDisplay让图形层额外合成一次屏幕到该虚拟屏幕中。虚拟屏幕本质上将画面发送给录屏功能实现,而非进行显示来完成录屏。
通读screenrecord源码,逻辑上,它与虚拟辅助屏、case录屏应用是相同的——VirtualDisplay录屏。但是编程上略有差异:
screenrecord直接通过binder与SurfaceFlinger通信,获取了raw VirtualDisplay,而