1.几个问题
- surface绘制的buffer是怎么来的
- 绘制完的buffer是怎么提交的
2.绘制的时候怎么申请到buffer
仍然在ViewRootImpl中进行
private void performDraw() {
draw(fullRedrawNeeded);
}
private void draw(boolean fullRedrawNeeded) {
drawSoftware();
}
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
boolean scalingRequired, Rect dirty) {
//获取Canvas 就是buffer
Canvas canvas = mSurface.lockCanvas(dirty);
mView.draw(canvas);
//提交 buffer
surface.unlockCanvasAndPost(canvas);
}
[-> Surface]
在surface中去获取canvas,也就是锁定一块画布
public Canvas lockCanvas(Rect inOutDirty)
throws Surface.OutOfResourcesException, IllegalArgumentException {
synchronized (mLock) {
mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
}
}
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
// 获取surface 其中nativeObject就是用来获取surface的变量
sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
ANativeWindow_Buffer outBuffer;
surface->lock(&outBuffer, dirtyRectPtr);
}
这里有两个概念:前台buffer和后台buffer,前台buffer用于展示,后台的用于绘制
[-> Surface.cpp]
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
reqFormat, reqUsage, &mBufferAge,
enableFrameTimestamps ? &frameTimestamps
: nullptr);
if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
// 使用GraphicBufferProducer创建buffer
result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
}
}
3.buffer的提交
status_t Surface::unlockAndPost()
{
int fd = -1;
status_t err = mLockedBuffer->unlockAsync(&fd);
err = queueBuffer(mLockedBuffer.get(), fd);
return err;
}
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
//
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
}
总结:
==当应用需要绘制ui的时候,需要利用surface去申请buffer,这些buffer都存在BufferQueue里面,它是一个双端队列,当应用得到buffer,将ui绘制到buffer后,再将buffer提交到Queue里面去,并且通知SurfaceFlinger去从Queue中去取buffer显示到屏幕上去,SurfaceFlinger是buffer的唯一消费者。 对于suface来说,GraphicBufferProducer是它的灵魂,buffer的申请和提交都是通过它来操作的,其中BufferQueue是用来存放buffer的==
