add Surface 绘制原理

master
Omooo 5 years ago
parent 5c55f3131c
commit 9b693085f7
  1. 93
      blogs/Android/Framework/Interview/UI 体系相关/Surface 的绘制原理.md
  2. BIN
      images/Android/Framework/Interview/Surface 绘制原理.png

@ -0,0 +1,93 @@
---
Surface 的绘制原理
---
1. Surface 绘制的 buffer 是怎么来的?
2. buffer 绘制完了又是怎么提交的?
```java
private void performTraversals(){
performMeasure();
performLayout();
performDraw();
}
private void draw(boolean fullRedrawNeeded){
Surface surface = mSurface;
drawSoftware(surface, mAttachInfo, ..., dirty);
}
private boolean drawSoftware(Surface surface, ...){
final Canvas canvas;
canvas = mSurface.lockCanvas(dirty);
mView.draw(canvas);
surface.unlockCanvasAndPost(canvas);
}
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj, jobject dirtyRectObj){
sp<Surface> surface(reinterpert_cast<Surface *>(nativeObject));
ANativeWindow_Buffer outBuffer;
surface->lock(&outBuffer, dirtyRectPtr);
SkBitmap bitmap;
bitmap.setPixels(outBuffer.bits);
Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
nativeCanvas->setBitmap(bitmap);
sp<Surface> lockedSurface(surface);
return (jlong)lockedSurface.get();
}
```
每次绘制都要重新申请一块 buffer,它是怎么申请的?
```c++
status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ...){
ANativeWindowBuffer* out;
dequeueBuffer(&out, &fenceFd);
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
void* vaddr;
status_t res = backBuffer->lockAsync(..., &vaddr, fenceFd);
mLockedBuffer = backBuffer;
outBuffer->bits = vaddr;
}
int Surface::dequeueBuffer(android_native_buffer_t** buffer, ...){
int buf = -1;
status_t result = mGraphicBufferProduct->dequeueBuffer(&buf, ...);
sp<GraphicBuffer>& gbuf(mSlot[buf].buffer);
if((result&IGraphicBufferProduct::BUFFER_NEEDS_REALLOCATION)||gbuf == 0){
result = mGraphicBufferProduct->requestBuffer(buf, &gbuf);
}
*buffer = gbuf.get();
return OK;
}
```
Buffer 是怎么提交的?
```c++
public void unlockCanvasAndPost(Canvas canvas){
synchronized(mLock){
unlockSwCanvasAndPost(canvas);
}
}
private void unlockSwCanvasAndPost(Canvas canvas){
nativeUnlockCanvasAndPost(mLockedObject, canvas);
nativeRelease(mLockedObject);
mLockedObject = 0;
}
static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj) {
sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
nativeCanvas->setBitmap(SkBitmap());
surface->unlockAndPost();
}
status_t Surface::unlockAndPost(){
mLockedBuffer->unlockAsync(...);
queueBuffer(mLockedBuffer.get(), ...);
mPostedBuffer = mLockedBuffer;
mLockedBuffer = 0;
return err;
}
int Surface::queueBuffer(android_native_buffer_t* buffer, ...){
int i = getSlotFromBufferLocked(buffer);
mGraphicBufferProducer->queueBuffer(i, ...);
}
```
![](https://i.loli.net/2020/03/26/l1QyIsgBtPSvLpF.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Loading…
Cancel
Save