Android之Surface
⼀、Surface是什么
Handleontoarawbufferthatisbeingmanagedbythescreencompositor.
⼤概意思是处理由屏幕合成器管理的原理缓存区。
⼆、Surface实现原理
在Surface类⾥有⼀个Canvas对象,在Canvas⾥有⼀个Bitmap,Bitmap是真正的画布。
Bitmap是什么
Bitmap缩写是BMP,是⼀种存储像素的数据结构。
三、Surface跨进程间传递
源码:frameworks/ba/core/java/android/view/
/**
*Handleontoarawbufferthatisbeingmanagedbythescreencompositor.
*
*
ASurfaceisgenerallycreatedbyorfromaconsumerofimagebuffers(suchasa
*{@eTexture},{@ecorder},or
*{@tion}),andishandedtosomekindofproducer(suchas
*{@14#eglCreateWindowSurface(play,fig,,int[],int)OpenGL},
*{@layer#tSurfaceMediaPlayer},or
*{@Device#createCaptureSessionCameraDevice})todraw
*into.
*
*
Note:ASurfaceactslikea
*{@ferenceweakreference}
*itlfitwillnotkeepitsparentconsumerfrombeingreclaimed.
*/
publicclassSurfaceimplementsParcelable{
……
}
Surface继承⾃Parcelable,Parcelable是⼀个序列化接⼝,将对象转化为⼆进制流(⼆进制序列)的过程。⼆进制流可以通过Socket传
输或者保存到本地。
在Android中Surface是怎么在进程间传递的,应⽤如何将Surface传递给SurfaceFlinger进程绘制的。
Java层实现:
在Parcelable中有两个关键函数:
/**
*将数据写⼊Parcel对象
*/
publicvoidwriteToParcel(Parceldest,intflags){}
/**
*从Parcel对象中读取数据
*/
publicvoidreadFromParcel(Parcelsource){}
先看oParcel()函数:
@Override
publicvoidwriteToParcel(Parceldest,intflags){
synchronized(mLock){
//NOTE:Thismustbekeptsynchronizedwiththenativeparcelingcode
//inframeworks/native/libs/
tring(mName);
nt(mIsSingleBuffered?1:0);
nativeWriteToParcel(mNativeObject,dest);
}
}
dest是⼀个Parcel对象,将name写⼊Parcel对象dest,再调⽤nativeWriteToParcel()函数,将mNativeObject写⼊到Parcel对象。
mNativeObject是什么?
longmNativeObject;//packagescopeonlyforSurfaceControlaccess
mNativeObject是Long型变量,存储Native层的对象指针。
nativeWriteToParcel()函数定义:
privatestaticnativevoidnativeWriteToParcel(longnativeObject,Parceldest);
nativeWriteToParcel()函数是Native层函数。
下⾯看看readFromParcel()函数:
publicvoidreadFromParcel(Parcelsource){
synchronized(mLock){
//nativeReadFromParcel()willeitherreturnmNativeObject,or
//createanewnativeSurfaceandreturnitafterreducing
//way,itis
//notnecessarytocallnativeRelea()here.
//NOTE:Thismustbekeptsynchronizedwiththenativeparcelingcode
//inframeworks/native/libs/
mName=ring();
mIsSingleBuffered=t()!=0;
tNativeObjectLocked(nativeReadFromParcel(mNativeObject,source));
}
}
从Surface对象中读取name数据,再调⽤nativeReadFromParcel()函数,通过tNativeObjectLocked()函数将nativeReadFromParcel()
函数返回的数据保存起来。
nativeReadFromParcel()函数定义:
privatestaticnativelongnativeReadFromParcel(longnativeObject,Parcelsource);
tNativeObjectLocked()函数实现:
privatevoidtNativeObjectLocked(longptr){
if(mNativeObject!=ptr){
mNativeObject=ptr;
}
}
将nativeReadFromParcel()函数返回值赋值给mNativeObject变量。
Native层:
源码:frameworks/ba/core/jni/android_view_
nativeWriteToParcel()函数实现:
staticvoidnativeWriteToParcel(JNIEnv*env,jclassclazz,
jlongnativeObject,jobjectparcelObj){
//(1)获取parcel对象,从Java层
Parcel*parcel=parcelForJavaObject(env,parcelObj);
if(parcel==NULL){
jniThrowNullPointerException(env,NULL);
return;
}
//(2)Native层的Surface对象
sp
android::view::SurfacesurfaceShim;
if(lf!=nullptr){
//(3)
cBufferProducer=lf->getIGraphicBufferProducer();
}
//salreadywrittenthenameoftheSurface
//totheParcel
oParcel(parcel,/*nameAlreadyWritten*/true);
}
//(3)
sp
returnmProducer;
}
(1)通过parcelFroJavaOjbect()获取Parcel对象:
Parcel*parcelForJavaObject(JNIEnv*env,jobjectobj)
{
if(obj){
Parcel*p=(Parcel*)env->GetLongField(obj,ePtr);
if(p!=NULL){
returnp;
}
jniThrowException(env,"java/lang/IllegalStateException","Parcelhasbeenfinalized!");
}
returnNULL;
}
(1)通过JNI调⽤,在Native层通过Native层保存的Java层Parcel指针获取Native层对应Java层的Parcel对象。
(2)通过Native层保存的Java层Surface对象指针,在Native层恢复Surface对象。
(3)将Native层的IGraphicBufferProducer对象传递给Java层的cBufferProducer变量。
nativeReadFromParcel()函数实现:
staticjlongnativeReadFromParcel(JNIEnv*env,jclassclazz,
jlongnativeObject,jobjectparcelObj){
//(1)
Parcel*parcel=parcelForJavaObject(env,parcelObj);
android::view::SurfacesurfaceShim;
//(2)
sp
//updatetheSurfaceonlyiftheunderlyingIGraphicBufferProducer
//haschanged.
//(3)
if(lf!=nullptr
&&(IInterface::asBinder(lf->getIGraphicBufferProducer())==
IInterface::asBinder(cBufferProducer))){
//sameIGraphicBufferProducer,returnourlves
returnjlong(());
}
//(4)
sp
if(cBufferProducer!=nullptr){
//wehaveanewIGraphicBufferProducer,createanewSurfaceforit
sur=newSurface(cBufferProducer,true);
//andkeepareferencebeforepassingtojava
sur->incStrong(&sRefBaOwner);
}
if(lf!=NULL){
//andloothejavareferencetoourlves
lf->decStrong(&sRefBaOwner);
}
//(5)
returnjlong(());
}
(1)获取Native层对应Java层的Parcel对象。
(2)获取Native层对应Java层的Surface对象。
(3)获取IGraphicBufferProducer对象,⼀个Binder对象。
(4)通过IGraphicBufferProducer对象创建⼀个新的Surface对象。
(5)将Native层的新Surface对象通过JNI调⽤传递给Java层。
对象Java层的Surface对应Native层的Surface对象,对于Native层的Surface对应Native层的IGraphicBufferProducer对象。
四、总结
AndroidApp中,⼀个Window对应⼀个Surface对象,应⽤与绘制服务SurfaceFlinger服务的通信是基于共享内存实现的,应⽤中在
Java层将Surface对象通过Parcel转化为⼆进制流,并且⼆进制流存储在共享内存。
Android每个应⽤都有在共享内存中都会有⼀个SharedClicent,再应⽤的Window对应⼀个Surface,⽽每个Surface对应共享内存的
SharedBufferStack。
Surface中Buffer是没有进程跨进程传递的,应⽤与SurfaceFlinger服务通信传递的是共享内存的物理地址,应⽤将Surface的Buffer写⼊
到SharedClient中,再将SharedClient中的SharedBufferStack的地址通过Binder通信传递给SurfaceFlinger。SurfaceFlinger服务通过共享内
存的物理地址到SharedClicent读取SharedBufferStack数据。
在SharedBufferStack中分为双缓冲与三级缓冲,在Android4.1版本前是双缓冲机制,在4.1版本后是三级缓冲机制。
SharedBufferStack分为:
FontBuffer:在屏幕中显⽰。
BackBuffer:绘制Buffer。
TripleBuffer:是Android对绘制优化,Vsync垂直同步提供的机制。TripleBuffer是CPU/GPU在空闲时提前准备数据的Buffer。
PS:可以配合⼀⽂⼀起阅读。
本文发布于:2023-03-15 19:35:39,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/418c58c539348e0328c8d4ed30bc303e.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:windows平板电脑.doc
本文 PDF 下载地址:windows平板电脑.pdf
留言与评论(共有 0 条评论) |