已知Surface对应着SurfaceFlinger管理的一个Layer,而LayerBuffer在C++和java空间中分别对应着ISurfaceComposer.h中的ePushBuffers与Surface.java中的PUSH_BUFFERS类型的Surface。创建LayerBuffer时,会先看是否支持硬件copybit加速:
if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
copybit_open(module, &mLayer.mBlitEngine);
}
copybit_device_t* copybit = mLayer.mBlitEngine;
... ...
err = initTempBuffer();
const NativeBuffer& dst(mTempBuffer);
region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b)));
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
err = copybit->stretch(copybit, &dst.img, &src.img, &dst.crop, &src.crop, &clip);
否则,就使用mTextureManager.loadTexture(&mTexture, dirty, t)通过glTexSubImage2D或glTexImage2D操作把数据渲染到mTexture贴图上面去的。也就是由OpenGL来做resize。/frameworks/base/services/surfaceflinger/LayerBuffer.cpp
GGLSurface t;
t.version = sizeof(GGLSurface);
t.width = src.crop.r;
t.height = src.crop.b;
t.stride = src.img.w;
t.vstride = src.img.h;
t.format = src.img.format;
t.data = (GGLubyte*) src.img.base;
const Region dirty(Rect(t.width, t.height));
mTextureManager.loadTexture(&mTexture, dirty, t);
resize操作完成以后,mTexture会被绘制到SurfaceFlinger的共享显存上面,SurfaceFlinger把各个Layer的mTexture进行Compose,然后交给GPU或FrameBuffer。后面的这几步操作是各个Layer都要经历的。
有一个地方还需要注意一下,上面有这么一句:we can fail here is the passed buffer is purely software。
需要看一下/frameworks/base/media/libstagefright/colorconversion/SoftwareRenderer.cpp中的代码段:
mMemoryHeap = new MemoryHeapBase("/dev/pmem_adsp", 2 * mFrameSize);
if (mMemoryHeap->heapID() < 0) {
LOGI("Creating physical memory heap failed, reverting to regular heap.");
mMemoryHeap = new MemoryHeapBase(2 * mFrameSize);
} else {
sp<MemoryHeapPmem> pmemHeap = new MemoryHeapPmem(mMemoryHeap);
pmemHeap->slap();
mMemoryHeap = pmemHeap;
}
可以看到,系统会先尝试使用pmem分配,失败的话,就会在regular heap(常规内存)中分配。如果存放视频帧原始数据(已经在被ColorConversion由decode过的YUV数据转化成RGB55)的内存是在regular heap中分配的话,在LayerBuffer中进行resize时是不会进行硬件copybit加速的。
综上,如果要实现resize的硬件加速的话,需要做这么几点:
1、保证内存由pmem分配。
2、实现gralloc的perform操作。可以参照msm7k的gralloc实现。
3、硬件copybit加速除了GPU和FB以外再增加对PMEM内存的支持。
通过1和2让系统知道可以使用硬件加速,3是硬件加速的具体实现。