很多人讲lockcanvas,没有讲清楚到底是怎么回事。
问题1:lockcanvas出来的canvas到底是什么东西? 里面的位图到底是什么?
问题2:整个android系统到底有多少个Buffer?android的多个进程又是通过什么方式来共享buffer的。
先讲一个静态基本概念:
ISurfaceTexture 是一个很关键的概念,建立了客户端Buffer与服务端的连接通道。
在ISurfaceTexture.h文件中可以看到另外一个本地接口BnSurfaceTexture,这个是作为服务器端的接口而存在的。
最重要的是如下几个接口。
virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
virtual status_t dequeueBuffer(int *slot, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) = 0;
virtual status_t queueBuffer(int slot, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
virtual void cancelBuffer(int slot) = 0;
这个四个接口android的帧缓冲的管理方式的关键所在。
Surface_lockCanvas 是个很关键的方法。在android_view_Surface.cpp中:
按照本人的分析风格,只看关键部分。其余全删除。
static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
{
status_t err = surface->lock(&info, &dirtyRegion);
SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
SkBitmap bitmap;
bitmap.setPixels(info.bits);
nativeCanvas->setBitmapDevice(bitmap); return canvas;}
非常简单的几句代码,就得到了一个canvas。canvas中的bitmap是从info得到的Pixels。
所以看到这里。就必须去看这一句。
status_t err = surface->lock(&info, &dirtyRegion);
在目录 frameworks/base/libs/gui/Surface.cpp中,有这么几行:
按照本人的分析风格,只看关键部分。其余全删除。
status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) {
status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
}
这几行代码再简单不过了,只是继续lock而已,一次转发。
在目录 frameworks/base/libs/gui/SurfaceTextureClient.cpp中,有这么几行
按照本人的分析风格,只看关键部分。其余全删除。这段代码重要的不是lockBuffer,lockBuffer的附加效果才是最重要的,也就是dequeueBuffer。
status_t SurfaceTextureClient::lock(
ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
{
int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
ANativeWindowBuffer* out;
status_t err = dequeueBuffer(&out);
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
err = lockBuffer(backBuffer.get());
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
copyBlt(backBuffer, frontBuffer, copyback);
void* vaddr;
status_t res = backBuffer->lock(
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
newDirtyRegion.bounds(), &vaddr);
mLockedBuffer = backBuffer;
outBuffer->width = backBuffer->width;
outBuffer->height = backBuffer->height;
outBuffer->stride = backBuffer->stride;
outBuffer->format = backBuffer->format;
outBuffer->bits = vaddr;
}
}
return err;
}
上面代码中的lockBuffer一看就猜个大概就是锁住一个临界区域。
int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
LOGV("SurfaceTextureClient::lockBuffer");
Mutex::Autolock lock(mMutex);
return OK;
}
文件在frameworks/base/include/gui/ISurfaceTexture.h,有几个成员函数:
virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
virtual status_t dequeueBuffer(int *slot, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) = 0;
virtual status_t queueBuffer(int slot, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
virtual void cancelBuffer(int slot) = 0;
这仅仅是一些客户端的接口,最终通过
class BnSurfaceTexture : public BnInterface<ISurfaceTexture>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
的子类 SurfaceTexture,文件在 目录 frameworks/base/libs/gui/SurfaceTexture.cpp
和frameworks/base/include/gui/SurfaceTexture.h