通过前面的篇文章我们简单了解了 Surface 和 Layer,并且知道了 SurfaceComposerClient 的 createSurface() 方法最终创建的其实是一个 Layer,这里我们来看一下真正的获取 Surface 的方法。
一、获取Surface
通过系统动画的播放流程中我们知道真正获取 Surface 的方法是 SurfaceControl 中的 getSurface() 函数,这里我们先来看一下 SurfaceControl 的构造函数。
1、SurfaceControl
源码位置:/frameworks/native/libs/gui/SurfaceControl.cpp
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbp, int32_t layerId, uint32_t w, uint32_t h,
PixelFormat format, uint32_t transform, uint32_t flags)
: mClient(client),
mHandle(handle),
mGraphicBufferProducer(gbp),
mLayerId(layerId),
mTransformHint(transform),
mWidth(w),
mHeight(h),
mFormat(format),
mCreateFlags(flags) {}
此时 SurfaceControl 同时持有了 Client 的 Binder,图元生产者以及 SurfaceComposerClient 服务。 当 SurfaceControl 有了之后,需要绘制像素,是绘制在 SurfaceControl 生成的 Surface 上。
getSurface
sp<Surface> SurfaceControl::getSurface()
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == nullptr) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
这里调用了 generateSurfaceLocked() 函数。
generateSurfaceLocked
sp<Surface> SurfaceControl::generateSurfaceLocked()
{
uint32_t ignore;
auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow | ISurfaceComposerClient::eOpaque);
// 这里创建一个新的名为"bbq-wrapper"的Layer
mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat, flags, mHandle, {}, &ignore);
// 创建BLASTBufferQueue
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
// 从BLASTBufferQueue中获取实际的Surface对象
mSurfaceData = mBbq->getSurface(true);
return mSurfaceData;
}
该函数为 SurfaceControl 实例创建并返回一个 Surface 对象。这个 Surface 对象是通过创建一个中间的 BufferQueue(BBQ,即 BLASTBufferQueue)图层来间接获得的,用于图形内容的显示和管理。
2、BLASTBufferQueue.cpp
源码位置:/frameworks/native/libs/gui/BLASTBufferQueue.cpp
sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
std::unique_lock _lock{mMutex};
sp<IBinder> scHandle = nullptr;
if (includeSurfaceControlHandle && mSurfaceControl) {
scHandle = mSurfaceControl->getHandle();
}
return new BBQSurface(mProducer, true, scHandle, this);
}
class BBQSurface : public Surface {
}
这里创建一个 BBQSurface,而 BBQSurface 又继承自 Surface,所以这里就完成了 Surface 的创建。也就是把图元生产者设置到 Surface 中。
二、Surface初始化
Surface 才是面向我们客户端,开发者的绘制图层。我们不会直接操作图元生产者。一切的事情都交给 Surface 来发送。这里面包含了很重要的图元发送等逻辑。
1、Surface.h
源码位置:/frameworks/native/libs/gui/include/gui/Surface.h
/**
* ANativeWindow的实现,它将图形缓冲区提供给BufferQueue
*/
class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
可以看到 Surface 继承了一个 ANativeObjectBase 模版类,这个模版类只是处理引用计数。
2、ANativeObjectBase.h
源码位置:/frameworks/native/libs/ui/include/ui/ANativeObjectBase.h
/*
* 这个助手类将ANativeXXX对象类型转换为c++引用计数对象;使用适当的类型转换。
*/
template <typename NATIVE_TYPE, typename TYPE, typename REF,
typename NATIVE_BASE = android_native_base_t>
class ANativeObjectBase : public NATIVE_TYPE, public REF
{
public:
// 消除REF中的incStrong和NATIVE_TYPE之间的歧义
void incStrong(const void* id) const {
REF::incStrong(id);
}
void decStrong(const void* id) const {
REF::decStrong(id);
}
protected:
typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF, NATIVE_BASE> BASE;
ANativeObjectBase() : NATIVE_TYPE(), REF() {
NATIVE_TYPE::common.incRef = incRef;
NATIVE_TYPE::common.decRef = decRef;
}
static inline TYPE* getSelf(NATIVE_TYPE* self) {
return static_cast<TYPE*>(self);
}
static inline TYPE const* getSelf(NATIVE_TYPE const* self) {
return static_cast<TYPE const *>(self);
}
static inline TYPE* getSelf(NATIVE_BASE* base) {
return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));
}
static inline TYPE const * getSelf(NATIVE_BASE const* base) {
return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));
}
static void incRef(NATIVE_BASE* base) {
ANativeObjectBase* self = getSelf(base);
self->incStrong(self);
}
static void decRef(NATIVE_BASE* base) {
ANativeObjectBase* self = getSelf(base);
self->decStrong(self);
}
};
使用模版了类决定了继承关系。换句话说其实相当于一个 Hook,在不改变设计结构下,增加了引用的特性。
3、ANativeWindow
源码位置:/frameworks/native/libs/nativewindow/include/system/window.h
struct ANativeWindow
{
#ifdef __cplusplus
ANativeWindow()
: flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
{
common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
common.version = sizeof(ANativeWindow);
memset(common.reserved, 0, sizeof(common.reserved));
}
/* 实现sp<ANativeWindow>期望的方法,以便它可以用来自动重新计算ANativeWindow的。 */
void incStrong(const void* /*id*/) const {
common.incRef(const_cast<android_native_base_t*>(&common));
}
void decStrong(const void* /*id*/) const {
common.decRef(const_cast<android_native_base_t*>(&common));
}
#endif
struct android_native_base_t common;
/* 描述此表面或其更新程序的某些属性的标志 */
const uint32_t flags;
/* 此更新支持的最小交换缓冲 */
const int minSwapInterval;
/* 此更新支持的最大交换缓冲 */
const int maxSwapInterval;
/* DPI中的水平和垂直分辨率 */
const float xdpi;
const float ydpi;
/* 一些存储保留给OEM的驱动程序 */
intptr_t oem[4];
/* 设置该表面的交换缓冲 */
int (*setSwapInterval)(struct ANativeWindow* window, int interval);
/* 由EGL调用以获取缓冲区的Hook */
int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer);
/* 由EGL调用来锁定缓冲区的Hook */
int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
/* 由EGL调用完成对渲染缓冲区的修改的Hook */
int(*queueBuffer_DEPRECATED)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
/* 用于检索有关本机窗口的信息Hook */
int (*query)(const struct ANativeWindow* window, int what, int* value);
/* 用于在表面执行各种操作Hook */
int (*perform)(struct ANativeWindow* window, int operation, ... );
/* 用于取消已退出队列的缓冲区Hook */
int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer);
/* 由EGL调用以获取缓冲区的Hook */
int (*dequeueBuffer)(struct ANativeWindow* window, struct ANativeWindowBuffer** buffer, int* fenceFd);
/* 由EGL调用完成对渲染缓冲区的修改的Hook */
int (*queueBuffer)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd);
/* 用于取消已退出队列的缓冲区的Hook */
int (*cancelBuffer)(struct ANativeWindow* window, struct ANativeWindowBuffer* buffer, int fenceFd);
};
这里别看名叫 Window,实际上 ANativeWindow 不是作为图元存储的结构体,他是用来控制 ANativeWindowBuffer 像素缓存的。大致上有四个操作,queueBuffer 图元入队,dequeueBuffer 图元出队,lockBuffer 图元锁定,query 图元查找等。当然还有setSwapInterval 交换缓冲。
接下来再来看看整个 Surface 的初始化。
4、Surface
源码位置:/frameworks/native/libs/gui/Surface.cpp
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
const sp<IBinder>& surfaceControlHandle)
: mGraphicBufferProducer(bufferProducer),
mCrop(Rect::EMPTY_RECT),
mBufferAge(0),
mGenerationNumber(0),
mSharedBufferMode(false),
mAutoRefresh(false),
mAutoPrerotation(false),
mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
mSharedBufferHasBeenQueued(false),
mQueriedSupportedTimestamps(false),
mFrameTimestampsSupportsPresent(false),
mEnableFrameTimestamps(false),
mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
ANativeWindow::queueBuffer = hook_queueBuffer;
ANativeWindow::query = hook_query;
ANativeWindow::perform = hook_perform;
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
mReqWidth = 0;
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mDataSpace = Dataspace::UNKNOWN;
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mStickyTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
mProducerControlledByApp = controlledByApp;
mSwapIntervalZero = false;
mMaxBufferCount = NUM_BUFFER_SLOTS;
mSurfaceControlHandle = surfaceControlHandle;
}
在 Surface 初始化的时候,同时为每一个方法指针都赋值了,让 Surface 拥有了操作的能力。
总结
其实整个过程就是图元缓冲队列的初始化流程。在这个初始化流程中,初步的搭建了整个生产者-消费者模型。剩下的步骤就是生产图元,写入生产者,生产者把数据写进缓冲队列,通知消费者进行消费。
标签:const,struct,int,ANativeWindow,Surface,SurfaceFlinger,Android,NATIVE From: https://blog.csdn.net/c19344881x/article/details/140046960
- createSurface 通过 SurfaceFlinger 的 Client 对象创建了一个图元生产者,并且赋值给 SurfaceControl 中。
- setLayer 设置 layer 图层在 Z 轴上的层级。
- getSurface 通过 SurfaceControl 生产 Surface 对象,真正进行交互是 Surface 对象。