[TOC]
上层Client和SurfaceFlinger的交互
为了很好的切入主题,我们这里基于Native的Framework进行应用的开发呢,不是指的NDK应用。我们直接用系统接口,进行开发。Native应用直接抛弃掉Android的Java上层,AMS,WMS,View等,直接在Native开发,这样便于我们理解显示系统。
Native应用建立
在显示子系统中,Surface是一个很重要的类,通过Surface我们就能获取到Buffer,我们就能够和Android Native窗口系统建立连接。我们就基于Surface来写一个Native的应用。
首先,我们先定义一个封装类WindowSurfaceWrapper,WindowSurfaceWrapper和Surface进行交互。
class WindowSurfaceWrapper : public RefBase {
public:
// Creates the window.
WindowSurfaceWrapper(const String8& name);
virtual ~WindowSurfaceWrapper() {}
virtual void onFirstRef();
// Retrieves a handle to the window.
sp getSurface() const;
int width() {
return mWidth;
}
int height() {
return mHeight;
}
private:
WindowSurfaceWrapper(const WindowSurfaceWrapper&);
WindowSurfaceWrapper& operator=(const WindowSurfaceWrapper&);
sp mSurfaceControl;
int mWidth;
int mHeight;
String8 mName;
};
WindowSurfaceWrapper对应的实现如下:
WindowSurfaceWrapper::WindowSurfaceWrapper(const String8& name) {
mName = name;
}
void WindowSurfaceWrapper::onFirstRef() {
status_t err;
sp surfaceComposerClient = new SurfaceComposerClient;
err = surfaceComposerClient->initCheck();
if (err != NO_ERROR) {
fprintf(stderr, "SurfaceComposerClient::initCheck error: %#x\n", err);
return;
}
// Get main display parameters.
sp mainDisplay = SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain);
DisplayInfo mainDisplayInfo;
err = SurfaceComposerClient::getDisplayInfo(mainDisplay, &mainDisplayInfo);
if (err != NO_ERROR) {
fprintf(stderr, "ERROR: unable to get display characteristics\n");
return;
}
uint32_t width, height;
if (mainDisplayInfo.orientation != DISPLAY_ORIENTATION_0 &&
mainDisplayInfo.orientation != DISPLAY_ORIENTATION_180) {
// rotated
width = mainDisplayInfo.h;
height = mainDisplayInfo.w;
} else {
width = mainDisplayInfo.w;
height = mainDisplayInfo.h;
}
sp surfaceControl = surfaceComposerClient->createSurface(
mName, width, height,
PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
if (surfaceControl == NULL || !surfaceControl->isValid()) {
fprintf(stderr, "Failed to create SurfaceControl\n");
return;
}
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControl, 0x7FFFFFFF)
.show(surfaceControl)
.apply();
mSurfaceControl = surfaceControl;
mWidth = width;
mHeight = height;
}
sp WindowSurfaceWrapper::getSurface() const {
sp anw = mSurfaceControl->getSurface();
return anw;
}
getSurface
获取Native 窗口,这个窗口能够和Native的窗口系统建立联系,我们直接往这个窗口里面绘制我们需要的界面就OK了。
int main(int argc, char *argv[]) {
unsigned samples = 0;
printf("usage: %s [samples]\n", argv[0]);
if (argc == 2) {
samples = atoi( argv[1] );
printf("Multisample enabled: GL_SAMPLES = %u\n", samples);
}
sp proc(ProcessState::self());
ProcessState::self()->startThreadPool();
sp windowSurface(new WindowSurfaceWrapper(String8("NativeBinApp")));
drawNativeWindow(windowSurface->getSurface().get(), windowSurface->width(), windowSurface->height());
IPCThreadState::self()->joinThreadPool();
return EXIT_SUCCESS;
}
解释一下代码中的关键点:
- 创建一个SurfaceComposerClient,这是应用端,是SurfaceFlinger的Client端,它将建立和SurfaceFlinger服务的通信
- getDisplayInfo,获取手机屏幕的信息
- createSurface,创建SurfaceControl,在SurfaceFlinger创建对应的Layer等~
- setLayer,设置窗口的z-Oder,SurfaceFlinger根据z-Oder决定窗口的可见性及可见大小
- show,让当前窗口可见
- apply,这时,上面的设置的属性才真正生效,传给SurfaceFlinger
至于怎么画界面,我们接来下再介绍,稍后再给出drawNativeWindow的代码。我们先来看,目前都干了什么。
应用和SurfaceFlinger的链接建立
应用和SurfaceFlinger是两个不同的进程,他们采用Binder通信,应用是Client端,SurfaceFlinger是服务端。在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个进程只有一个对象,这个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能通过Binder通信。与之相关的是IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责Binder的读取,写入和请求处理框架。IPCThreadState在构造的时候获取进程的ProcessState并记录在自己的成员变量mProcess中,通过mProcess可以获得Binder的句柄。
我们这里将不详细的介绍Binder。有需求的可以提,我们开一个专题。
SurfaceComposerClient的 定义非常简单,继承RefBase~,这样我们就可以直接用智能指针sp,wp管理SurfaceComposerClient对象,不用担心SurfaceComposerClient对象的回收问题。
智能指针sp,wp,我们这里也不做详细的介绍,有需求的可以提,我们开一个专题。
在SurfaceComposerClient的构造函数中,只初始化了一个装mStatus。
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{
}
第一次引用的时候,才真正的建立连接:
*frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp sf(ComposerService::getComposerService());
if (sf != 0 && mStatus == NO_INIT) {
auto rootProducer = mParent.promote();
sp conn;
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
sf->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
ComposerService继承模板类Singleton,ComposerService是一个单例。
ComposerService::ComposerService()
: Singleton() {
Mutex::Autolock _l(mLock);
connectLocked();
}
ComposerService在构建时,创建链接:
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
assert(mComposerService != NULL);
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService& mComposerService;
virtual void binderDied(const wp& who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}
建立连接时,采用轮循的方式,getService时,如果SurfaceFlinger服务还没有启动,等待250000后再查询,知道等到SurffaceFlinger进程启动。DeathObserver是监听SurfaceFlinger进程是否死掉,做善后处理的。
getComposerService直接返回单实例mComposerService。
/*static*/ sp ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != NULL);
ALOGD("ComposerService reconnected");
}
return instance.mComposerService;
}
createScopedConnection函数,将建立和SurfaceFlinger的连接。
void SurfaceComposerClient::onFirstRef() {
sp sf(ComposerService::getComposerService());
if (sf != 0 && mStatus == NO_INIT) {
auto rootProducer = mParent.promote();
sp conn;
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
sf->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
对于我们这里的使用来说,rootProducer是nullptr,所以直接走的sf->createConnection()。Bn端SurfaceFlinger的实现为:
* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp SurfaceFlinger::createConnection() {
return initClient(new Client(this));
}
static sp initClient(const sp& client) {
status_t err = client->initCheck();
if (err == NO_ERROR) {
return client;
}
return nullptr;
}
Client继承BnSurfaceComposerClient,是ISurfaceComposerClient的Bn端。
我们来看一下,显示系统中,Client和SurfaceFlinger的关系:
应用端SurfaceComposerClient通过接口ISurfaceComposerClient和SurfaceFlinger的Client建立联系。应用端通过的ComposerService通过ISurfaceComposer和SurfaceFlinger建立联系。
SurfaceFlinger的启动
SurfaceFlinger是一个系统级的服务,Android系统启动的过程中就会启动SurfaceFlinger,在初始化init时。
* frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
既然是独立的进程,系统级的服务,那就有自己的main函数:
* frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
startHidlServices();
signal(SIGPIPE, SIG_IGN);
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
sp ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
sp flinger = new SurfaceFlinger();
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
// Put most SurfaceFlinger threads in the system-background cpuset
// Keeps us from unnecessarily using big cores
// Do this after the binder thread pool init
if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);
// initialize before clients can connect
flinger->init();
// publish surface flinger
sp sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
// publish GpuService
sp gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO");
}
// run surface flinger in this thread
flinger->run();
return 0;
}
SurfacFlinger进程中主要4个服务:
- startHidlServices主要是启动allocator
- DisplayService,主要负责DisplayEvent的处理
- SurfaceFlinger,主要显示相关的,最重要的服务
- GpuService,GPU相关的服务,为访问GPU
SurfaceFlinger类定义如下:
* frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback
SurfaceComposer是ISurfaceComposer的Bn端。实现了HWC2的ComposerCallback回调。死亡回收DeathRecipient,以及Dump信息PriorityDumper。
构造函数如下:
* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
mTransactionFlags(0),
mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false),
mLayersAdded(false),
mRepaintEverything(0),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
mGeometryInvalid(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mForceFullDamage(false),
mInterceptor(this),
mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mHasColorMatrix(false),
mHasPoweredOff(false),
mNumLayers(0),
mVrFlingerRequestsDisplay(false),
mMainThreadId(std::this_thread::get_id())
{
ALOGI("SurfaceFlinger is starting");
vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
&ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
... ...
mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
... ...
property_get("ro.sf.disable_triple_buffer", value, "1");
mLayerTripleBufferingDisabled = atoi(value);
ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
... ...
}
在构造函数中,主要是做初始化。从Android O开始,vendor的一些配置,都采用configstore的方式提供,就是这里的ISurfaceFlingerConfigs,这是一个系统服务。对应的接口在 hardware/interfaces/configstore/ 。当然,采用属性进行设置,但是属性设置的是debug的参数居多。
SurfaceFlinger真正的初始化,是在init函数中:
void SurfaceFlinger::init() {
... ...
Mutex::Autolock _l(mStateLock);
// start the EventThread
sp vsyncSrc =
new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this, false);
sp sfVsyncSrc =
new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
mEventQueue.setEventThread(mSFEventThread);
// set EventThread and SFEventThread to SCHED_FIFO to minimize jitter
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
}
if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for EventThread");
}
// Get a RenderEngine for the given display / config (can't fail)
getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
"Starting with vr flinger active is not currently supported.");
getBE().mHwc.reset(new HWComposer(getBE().mHwcServiceName));
getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
// This callback is called from the vr flinger dispatch thread. We
// need to call signalTransaction(), which requires holding
// mStateLock when we're not on the main thread. Acquiring
// mStateLock from the vr flinger dispatch thread might trigger a
// deadlock in surface flinger (see b/66916578), so post a message
// to be handled on the main thread instead.
sp message = new LambdaMessage([=]() {
ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
mVrFlingerRequestsDisplay = requestDisplay;
signalTransaction();
});
postMessageAsync(message);
};
mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(),
getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
vrFlingerRequestDisplayCallback);
if (!mVrFlinger) {
ALOGE("Failed to start vrflinger");
}
}
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
initializeDisplays();
getBE().mRenderEngine->primeCache();
// Inform native graphics APIs whether the present timestamp is supported:
if (getHwComposer().hasCapability(
HWC2::Capability::PresentFenceIsNotReliable)) {
mStartPropertySetThread = new StartPropertySetThread(false);
} else {
mStartPropertySetThread = new StartPropertySetThread(true);
}
if (mStartPropertySetThread->Start() != NO_ERROR) {
ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
}
在init函数中,主要做了一下几件事:
- 创建两个EventThread及其DispSyncSource,主要是用以处理和分发如Vsync;App和SurfaceFlinger的如Vsync是分开的,不是同一个。
- 创建了自己的消息队列mEventQueue,SurfaceFlinger的消息队列
- 初始化了Client合成模式(GPU)合成时,需要用到的RenderEngine
- 初始化HWComposer,注册回调接口registerCallback,HAL会回调一些方法。
- 如果是VR模式,创建mVrFlinger
- 创建mEventControlThread,处理Event事件,如Vsync事件和hotplug事件。
- 初始化显示设备initializeDisplays
SurfaceFlinger第一次引用时,启动mEventQueue消息队列
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
SurfaceFlinger这边后续再继续,先回到Native应用的创建
获取Display信息
Android支持多给屏幕,多个屏幕可以显示一样的内容,也可以显示不一样的内容。我们通常的把他们称为主显,外显和虚显。主显就是内置的,默认的手机屏幕;外显就是HDMI,MHL等连接的屏幕;虚显,就是虚拟显示器,通过WFD连接的屏幕,或者是类似屏幕一样的Buffer消费者。
屏幕都是通过ID来标记的:
* frameworks/native/services/surfaceflinger/DisplayDevice.h
enum DisplayType {
DISPLAY_ID_INVALID = -1,
DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY, //主显
DISPLAY_EXTERNAL = HWC_DISPLAY_EXTERNAL, //外显
DISPLAY_VIRTUAL = HWC_DISPLAY_VIRTUAL, //虚显4
NUM_BUILTIN_DISPLAY_TYPES = HWC_NUM_PHYSICAL_DISPLAY_TYPES,
};
通过getBuiltInDisplay,去获取指定ID的屏幕。
sp SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
return ComposerService::getComposerService()->getBuiltInDisplay(id);
}
getBuiltInDisplay是一个Binder调用,中间的Binder就省掉了,直接看实现:
sp SurfaceFlinger::getBuiltInDisplay(int32_t id) {
if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
return NULL;
}
return mBuiltinDisplays[id];
}
前面初始化的时候,屏幕都是采用热插拔的形式上报。内置屏幕也是这样。这个后续再介绍。
获取屏幕后,通过getDisplayInfo函数,就能获取屏幕的信息。
DisplayInfo mainDisplayInfo;
err = SurfaceComposerClient::getDisplayInfo(mainDisplay, &mainDisplayInfo);
if (err != NO_ERROR) {
fprintf(stderr, "ERROR: unable to get display characteristics\n");
return;
}
一个屏幕可以有多个config信息,当前再用的是activeconfig。在SurfaceComposerClient中,获取config信息时,先获取多有的config信息,再获取active的config的ID,根据ID去取Display信息。
status_t SurfaceComposerClient::getDisplayInfo(const sp& display,
DisplayInfo* info) {
Vector configs;
status_t result = getDisplayConfigs(display, &configs);
if (result != NO_ERROR) {
return result;
}
int activeId = getActiveConfig(display);
if (activeId < 0) {
ALOGE("No active configuration found");
return NAME_NOT_FOUND;
}
*info = configs[static_cast(activeId)];
return NO_ERROR;
}
getDisplayConfigs还是通过ComposerService去获取的,走的ISurfaceComposer的接口。
status_t SurfaceComposerClient::getDisplayConfigs(
const sp& display, Vector* configs)
{
return ComposerService::getComposerService()->getDisplayConfigs(display, configs);
}
在看SurfaceFlinger中getDisplayConfigs的实现之前。我们先来看DisplayInfo的定义,看看Display信息都包含哪些。看看怎么来描述一个显示屏幕。
struct DisplayInfo {
uint32_t w{0}; // 屏幕的宽
uint32_t h{0}; // 屏幕的高
float xdpi{0}; // 屏幕的x方向每英寸的像素点
float ydpi{0}; // 屏幕y方向每英寸的像素点
float fps{0}; // FPS屏幕的刷新率
float density{0}; // 屏幕的密度
uint8_t orientation{0}; // 屏幕的旋转方式
bool secure{false}; // 屏幕是否是安全的
nsecs_t appVsyncOffset{0}; // App的Vsync的偏移
nsecs_t presentationDeadline{0}; // 显示的最后时间
};
我们结合SurfaceFlinger中getDisplayConfigs的实现,来说说Display的信息。
- 首先,根据Display的IBinder,找到Display的类型type。
* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::getDisplayConfigs(const sp& display,
Vector* configs) {
... ...
int32_t type = NAME_NOT_FOUND;
for (int i=0 ; i
- 在根据type去获取驱动中配置的信息getConfigs,getHwComposer().getConfigs(type);
ConditionalLock _l(mStateLock,
std::this_thread::get_id() != mMainThreadId);
for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
- 最后,根据驱动给的配置,和一些设置,构建完整的显示屏信息,下面是关键信息,删掉了一些log和注解。
for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
DisplayInfo info = DisplayInfo();
float xdpi = hwConfig->getDpiX();
float ydpi = hwConfig->getDpiY();
if (type == DisplayDevice::DISPLAY_PRIMARY) {
float density = Density::getBuildDensity() / 160.0f;
if (density == 0) {
density = xdpi / 160.0f;
}
if (Density::getEmuDensity()) {
xdpi = ydpi = density = Density::getEmuDensity();
density /= 160.0f;
}
info.density = density;
sp hw(getDefaultDisplayDeviceLocked());
info.orientation = hw->getOrientation();
} else {
static const int TV_DENSITY = 213;
info.density = TV_DENSITY / 160.0f;
info.orientation = 0;
}
info.w = hwConfig->getWidth();
info.h = hwConfig->getHeight();
info.xdpi = xdpi;
info.ydpi = ydpi;
info.fps = 1e9 / hwConfig->getVsyncPeriod();
info.appVsyncOffset = vsyncPhaseOffsetNs;
... ...
info.presentationDeadline = hwConfig->getVsyncPeriod() -
sfVsyncPhaseOffsetNs + 1000000;
// All non-virtual displays are currently considered secure.
info.secure = true;
configs->push_back(info);
}
return NO_ERROR;
}
屏幕信息:
-
屏幕宽高(W*H)
屏幕的宽高是用分辨率来描述的,也就是像素点的多少。像素是指在由一个数字序列表示的图像中的一个最小单位,称为像素。屏幕多宽,就是指,屏幕横向可以显示多少个像素点。屏幕多高就是指,屏幕纵向可以显示多少给像素点。平常所说的720P屏幕,就是1080x720,横向可以显示1080个像素点,纵向可以显示720个像素点。
此图是,平常什么所说的一些分辨率:
每英寸的点数xdpi,ydpi
显示屏幕的物理大小,用英寸来描述,描述屏幕对角线的长度。比如iPhoneX 5.8英寸,指的是对角线的长度5.8英寸。而dpi,即Dots Per Inch,表示每英寸有多少给点。百度百科的解释为,dpi是一个量度单位,用于点阵数码影像,指每一英寸长度中,取样、可显示或输出点的数目。
PPI(pixels per inch)和DPI是措辞的差别,很多时候,都是混用的。如iPhoneX是458 ppi;荣耀V9的DPI为488左右。density密度
这里的desity是一个缩放因子,是 DPI / (160像素/英寸) 后得到的值,是一个比例值。
这可以看DisplayMetrics中关于density的定义:
frameworks/base/core/java/android/util/DisplayMetrics.java
/**
* The logical density of the display. This is a scaling factor for the
* Density Independent Pixel unit, where one DIP is one pixel on an
* approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
* providing the baseline of the system's display. Thus on a 160dpi screen
* this density value will be 1; on a 120 dpi screen it would be .75; etc.
*
* This value does not exactly follow the real screen size (as given by
* {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
* the overall UI in steps based on gross changes in the display dpi. For
* example, a 240x320 screen will have a density of 1 even if its width is
* 1.8", 1.3", etc. However, if the screen resolution is increased to
* 320x480 but the screen size remained 1.5"x2" then the density would be
* increased (probably to 1.5).
*
* @see #DENSITY_DEFAULT
*/
public float density;
以设备无关像素DIP(device independent pixels)在160dpi屏幕上显示为基础。160dip在160dpi的屏幕上,density就是1,在120dpi的屏幕上,density就为0.75。
屏幕刷新率FPS
FPS(Frame per second),帧每秒。表示屏幕一描述,可以显示多少帧图像数据。目前多少的手机显示屏还是60FPS,显示一帧16.67ms左右。orientation屏幕旋转方向
手机默认竖屏,0度竖屏。
/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
enum {
DISPLAY_ORIENTATION_0 = 0,
DISPLAY_ORIENTATION_90 = 1,
DISPLAY_ORIENTATION_180 = 2,
DISPLAY_ORIENTATION_270 = 3
};
- 屏幕是否安全secure
这主要是用于DRM(数字版权保护)时,确保显示的设备是安全的,以防止DRM的内容被在显示的过程中被截取。只有安全的设备才能显示DRM的内容。
Android默认,所有的非虚拟显示都是安全的。
// All non-virtual displays are currently considered secure.
info.secure = true;
- appVsyncOffset和presentationDeadline
这两个都和 Vsync有关,后续会再介绍。appVsyncOffset是一个偏移量,在系统(或硬件Vsync)的基础上做一些偏移。presentationDeadline表示,一帧数据,多就内,必现要显示出来。
Ok~到此,SurfaceComposerClient端就拿到了多个config信息了,在configs中。
Active config,就是当前被激活使用的:
int SurfaceFlinger::getActiveConfig(const sp& display) {
if (display == NULL) {
ALOGE("%s : display is NULL", __func__);
return BAD_VALUE;
}
sp device(getDisplayDevice(display));
if (device != NULL) {
return device->getActiveConfig();
}
return BAD_VALUE;
}
SurfaceFlinger服务中,Display的描述,用的DisplayDevice。每添加一个显示屏,都会创建一个DisplayDevice。
int DisplayDevice::getActiveConfig() const {
return mActiveConfig;
}
activeconfig,是一个索引值,对应驱动中,对应的config的索引。一般来说,active的config,都是默认的0。当然SurfaceFlinger或上层是可以去设置的。
void DisplayDevice::setActiveConfig(int mode) {
mActiveConfig = mode;
}
回到应用~
Native创建图层Layer
拿到显示信息后,根据转屏,这边的尺寸需要做一下交换。因为不关屏幕怎么旋转,我们需要显示的内容大小是没有变的。
uint32_t width, height;
if (mainDisplayInfo.orientation != DISPLAY_ORIENTATION_0 &&
mainDisplayInfo.orientation != DISPLAY_ORIENTATION_180) {
// rotated
width = mainDisplayInfo.h;
height = mainDisplayInfo.w;
} else {
width = mainDisplayInfo.w;
height = mainDisplayInfo.h;
}
接下里,就可以创建图层了。
sp surfaceControl = surfaceComposerClient->createSurface(
mName, width, height,
PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
if (surfaceControl == NULL || !surfaceControl->isValid()) {
fprintf(stderr, "Failed to create SurfaceControl\n");
return;
}
createSurface函数如下:
sp SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags,
SurfaceControl* parent,
uint32_t windowType,
uint32_t ownerUid)
{
sp sur;
if (mStatus == NO_ERROR) {
sp handle;
sp parentHandle;
sp gbp;
if (parent != nullptr) {
parentHandle = parent->getHandle();
}
status_t err = mClient->createSurface(name, w, h, format, flags, parentHandle,
windowType, ownerUid, &handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
sur = new SurfaceControl(this, handle, gbp);
}
}
return sur;
}
先解释一下,其中的参数:
name
name就是图层的名字,没有实际意义,主要是便于debug,有有名字,就可以知道,我们创建的图层是哪个了。w,h
这个是图层的宽高,我们用只是从DisplayInfo中读出来的,跟屏幕的大小一样。format
图层的格式,应用中,我们用的格式是PIXEL_FORMAT_RGBX_8888。
我们通过RGB,红,绿,蓝,三原色可以调配所有的颜色。在数字世界里面,也是用RGB来表示颜色,外加一个Alpha通道,就是RGBA。
RGBA_8888,表示R,G,B,A分别用8bit表示。也就是说,R的取值范围为0255。R从0255,表示最不红到最红,值的大小,表示红的程度不同。
同样,Alpha A,也是表示透明的程度,RGBX中的X表示,X为255,不透明。
下面是Android中,常用的一些格式。
* frameworks/native/libs/ui/include/ui/PixelFormat.h
enum {
//
// these constants need to match those
// in graphics/PixelFormat.java & pixelflinger/format.h
//
PIXEL_FORMAT_UNKNOWN = 0,
PIXEL_FORMAT_NONE = 0,
// logical pixel formats used by the SurfaceFlinger -----------------------
PIXEL_FORMAT_CUSTOM = -4,
// Custom pixel-format described by a PixelFormatInfo structure
PIXEL_FORMAT_TRANSLUCENT = -3,
// System chooses a format that supports translucency (many alpha bits)
PIXEL_FORMAT_TRANSPARENT = -2,
// System chooses a format that supports transparency
// (at least 1 alpha bit)
PIXEL_FORMAT_OPAQUE = -1,
// System chooses an opaque format (no alpha bits required)
// real pixel formats supported for rendering -----------------------------
PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA
PIXEL_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0
PIXEL_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB
PIXEL_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, // 16-bit RGB
PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA
PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit ARGB
PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit ARGB
PIXEL_FORMAT_RGBA_FP16 = HAL_PIXEL_FORMAT_RGBA_FP16, // 64-bit RGBA
PIXEL_FORMAT_RGBA_1010102 = HAL_PIXEL_FORMAT_RGBA_1010102, // 32-bit RGBA
};
- flags
createSurface时,可用的flag如下:
* frameworks/native/libs/gui/include/gui/ISurfaceComposerClient.h
// flags for createSurface()
enum { // (keep in sync with Surface.java)
eHidden = 0x00000004,
eDestroyBackbuffer = 0x00000020,
eSecure = 0x00000080,
eNonPremultiplied = 0x00000100,
eOpaque = 0x00000400,
eProtectedByApp = 0x00000800,
eProtectedByDRM = 0x00001000,
eCursorWindow = 0x00002000,
eFXSurfaceNormal = 0x00000000,
eFXSurfaceColor = 0x00020000,
eFXSurfaceMask = 0x000F0000,
};
Flag | 作用 | 说明 |
---|---|---|
eHidden | 隐藏 | 表示Layer是不可见的 |
eDestroyBackbuffer | 销毁Back Buffer | 表示Layer不保存Back Buffer |
eSecure | 安全layer | 表示安全的Layer,只能显示在Secure屏幕上 |
eNonPremultiplied | 非自左乘 | 针对Alpha通道的,如果没有Alpha通道没有实际意义 |
eOpaque | 非透明的 | 表示Layer不是透明的 |
eProtectedByApp | 应用保护 | 应用将请求一个安全的硬件通道传输到外显 |
eProtectedByDRM | DRM保护 | 应用请求一个安全的通道传输DRM |
eCursorWindow | Cursor Layer | 其实这Layer就是鼠标一类的图标 |
eFXSurfaceNormal | 普通的Layer | 系统中大多数layer都是此类 |
eFXSurfaceColor | 颜色layer | 在之前的版本中,这个被称为Dim Layer |
- windowType
窗口类型,可以参照WindowManager.java中的定义,如FIRST_SYSTEM_WINDOW,TYPE_STATUS_BAR等。默认值为0。
- ownerUid
可以指定这个是哪个UID的Layer。
继续看createSurfface,Service端的实现如下:
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
const sp& parentHandle, uint32_t windowType, uint32_t ownerUid,
sp* handle,
sp* gbp)
{
sp parent = nullptr;
... ...
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
... ...
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle, uint32_t windowType, uint32_t ownerUid,
sp* gbp,
sp* parent)
: flinger(flinger), client(client),
handle(handle), gbp(gbp), result(NO_ERROR),
name(name), w(w), h(h), format(format), flags(flags),
parent(parent), windowType(windowType), ownerUid(ownerUid) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
windowType, ownerUid, handle, gbp, parent);
return true;
}
};
sp msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle,
windowType, ownerUid, gbp, &parent);
mFlinger->postMessageSync(msg);
return static_cast( msg.get() )->getResult();
}
Client类中,创建Layer时,先找到parent Layer,对于我们的应用来说,是没有parent Layer的。然后再postMessageSync到SurfaceFlinger中,去创建,调用的SurfaceFlinger的createLayer方法。
SurfaceFlinger中,都是采用post Message的形式调到SurfaceFlinger的主线程中。
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
uint32_t windowType, uint32_t ownerUid, sp* handle,
sp* gbp, sp* parent)
{
if (int32_t(w|h) < 0) {
ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
}
status_t result = NO_ERROR;
sp layer;
String8 uniqueName = getUniqueLayerName(name);
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = createBufferLayer(client,
uniqueName, w, h, flags, format,
handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceColor:
result = createColorLayer(client,
uniqueName, w, h, flags,
handle, &layer);
break;
default:
result = BAD_VALUE;
break;
}
if (result != NO_ERROR) {
return result;
}
// window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java
// TODO b/64227542
if (windowType == 441731) {
windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL
layer->setPrimaryDisplayOnly();
}
layer->setInfo(windowType, ownerUid);
result = addClientLayer(client, *handle, *gbp, layer, *parent);
if (result != NO_ERROR) {
return result;
}
mInterceptor.saveSurfaceCreation(layer);
setTransactionFlags(eTransactionNeeded);
return result;
}
getUniqueLayerName,确保Layer 的name没有重名。
SurfaceFlinger中,主要处理两中类似的Layer,eFXSurfaceNormal和eFXSurfaceColor。两种类似分别有createBufferLayer和createColorLayer两个接口实现。怎么创建的这里就不介绍了,后续再介绍。
addClientLayer做了什么:
status_t SurfaceFlinger::addClientLayer(const sp& client,
const sp& handle,
const sp& gbc,
const sp& lbc,
const sp& parent)
{
// add this layer to the current state list
{
Mutex::Autolock _l(mStateLock);
if (mNumLayers >= MAX_LAYERS) {
ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers,
MAX_LAYERS);
return NO_MEMORY;
}
if (parent == nullptr) {
mCurrentState.layersSortedByZ.add(lbc);
} else {
if (parent->isPendingRemoval()) {
ALOGE("addClientLayer called with a removed parent");
return NAME_NOT_FOUND;
}
parent->addChild(lbc);
}
mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
mLayersAdded = true;
mNumLayers++;
}
// attach this layer to the client
client->attachLayer(handle, lbc);
return NO_ERROR;
}
将新创建的Layer添加到当前的layer列表中,按照Z-order。如果有parent的,添加到parent中。mGraphicBufferProducerList保存了当前的所有Layer内容的生产者。最后,将Layer关联的Client上。
Layer创建完成后,调用setTransactionFlags函数,告诉SurfaceFlinger,新增加了Layer,有新的显示,有很多显示数据需要去更新。SurfaceFlinger根据flag,决定是否需要换醒服务。
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if ((old & flags)==0) { // wake the server up
signalTransaction();
}
return old;
}
Layer创建完成,回到我们的应用~
处理状态的传送
应用的代码如下:
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControl, 0x7FFFFFFF)
.show(surfaceControl)
.apply();
C++的新特性,是不是有点类似Java了。
从Android P开始,google又重构了这一块的代码。之前的代码中,是SurfaceComposerClient提供全局的状态处理;从Android P开始,transactions 被区分为不同的对象,直接处理对象。这是Transaction一个类图。
可见,将处理类型分为了两类:
- ComposerState 合成处理状态
struct ComposerState {
sp client;
layer_state_t state;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
ComposerState封装了layer_state_t,Layer的状态,再实现Binder通信时的write,read。
- DisplayState 显示屏状态
struct DisplayState {
enum {
eOrientationDefault = 0,
eOrientation90 = 1,
eOrientation180 = 2,
eOrientation270 = 3,
eOrientationUnchanged = 4,
eOrientationSwapMask = 0x01
};
enum {
eSurfaceChanged = 0x01,
eLayerStackChanged = 0x02,
eDisplayProjectionChanged = 0x04,
eDisplaySizeChanged = 0x08
};
DisplayState();
void merge(const DisplayState& other);
uint32_t what;
sp token;
sp surface;
uint32_t layerStack;
uint32_t orientation;
Rect viewport;
Rect frame;
uint32_t width, height;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
Display的状态目前就4个,也就是
enum {
eSurfaceChanged = 0x01, // Surface改变了
eLayerStackChanged = 0x02, // layerStack改变了
eDisplayProjectionChanged = 0x04, // Display的Projection改变了
eDisplaySizeChanged = 0x08 // Size改变了
};
这里的what,就是用以标记mark到底是哪个属性改变了,有多个属性改变的时候,加上对应的mark标记位即可。
ComposerState中的layer_state_t和这里的DisplayState类似。也是采用what来标记的。Layer的状态处理,包括以下属性。
enum {
ePositionChanged = 0x00000001,
eLayerChanged = 0x00000002,
eSizeChanged = 0x00000004,
eAlphaChanged = 0x00000008,
eMatrixChanged = 0x00000010,
eTransparentRegionChanged = 0x00000020,
eFlagsChanged = 0x00000040,
eLayerStackChanged = 0x00000080,
eCropChanged = 0x00000100,
eDeferTransaction = 0x00000200,
eFinalCropChanged = 0x00000400,
eOverrideScalingModeChanged = 0x00000800,
eGeometryAppliesWithResize = 0x00001000,
eReparentChildren = 0x00002000,
eDetachChildren = 0x00004000,
eRelativeLayerChanged = 0x00008000,
eReparent = 0x00010000,
eColorChanged = 0x00020000
};
好了,让我们通过本实例中的示例,来看看状态处理是怎么传递,生效的。
setLayer,实际上是设置Layer的z-order,
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
const sp& sc, int32_t z) {
layer_state_t* s = getLayerStateLocked(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eLayerChanged;
s->z = z;
return *this;
}
getLayerStateLocked,就是根据SurfaceCotrol对象去找,对应的layer_state_t。
layer_state_t* SurfaceComposerClient::Transaction::getLayerStateLocked(const sp& sc) {
ComposerState s;
s.client = sc->getClient()->mClient;
s.state.surface = sc->getHandle();
ssize_t index = mComposerStates.indexOf(s);
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mComposerStates.add(s);
}
ComposerState* const out = mComposerStates.editArray();
return &(out[index].state);
}
我们看,setLayer时,增加mask标识what是layer_state_t::eLayerChanged,而对应的值保存到layer_state_t z中。注意,这里的设置并没有立即生效。
同样,show时,也是将对应的mask表示加到what中,而是否显示的标识存放在layer_state_t的flag中。
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
const sp& sc) {
return setFlags(sc, 0, layer_state_t::eLayerHidden);
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
const sp& sc, uint32_t flags,
uint32_t mask) {
layer_state_t* s = getLayerStateLocked(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
if ((mask & layer_state_t::eLayerOpaque) ||
(mask & layer_state_t::eLayerHidden) ||
(mask & layer_state_t::eLayerSecure)) {
s->what |= layer_state_t::eFlagsChanged;
}
s->flags &= ~mask;
s->flags |= (flags & mask);
s->mask |= mask;
return *this;
}
我们设置的处理状态,在apply时,才生效。
status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
if (mStatus != NO_ERROR) {
return mStatus;
}
sp sf(ComposerService::getComposerService());
Vector composerStates;
Vector displayStates;
uint32_t flags = 0;
mForceSynchronous |= synchronous;
composerStates = mComposerStates;
mComposerStates.clear();
displayStates = mDisplayStates;
mDisplayStates.clear();
if (mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous;
}
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
mForceSynchronous = false;
mAnimation = false;
sf->setTransactionState(composerStates, displayStates, flags);
mStatus = NO_ERROR;
return NO_ERROR;
}
apply时,最重要的就是调用setTransactionState,
void SurfaceFlinger::setTransactionState(
const Vector& state,
const Vector& displays,
uint32_t flags)
{
ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
... ...
// Animation flag的处理,在Androd P上很少用到,重要是用做模拟back-pressure
}
// 处理Display State
size_t count = displays.size();
for (size_t i=0 ; i binder = IInterface::asBinder(s.client);
if (binder != NULL) {
if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
sp client( static_cast(s.client.get()) );
transactionFlags |= setClientStateLocked(client, s.state);
}
}
}
}
// 处理假动画和同步模式
if (transactionFlags == 0 &&
((flags & eSynchronous) || (flags & eAnimation))) {
transactionFlags = eTransactionNeeded;
}
if (transactionFlags) {
... ...
}
}
SurfaceFlinger中,处理状态是怎么工作的呢?
SurfaceF中,有两个状态: mCurrentState 和 mDrawingState。
- mCurrentState主要是用作接受Client的处理变更请求;需要状态锁mStateLock的保护
- mDrawingState主要用作,控制合成;只能在SurfaceFlinger的主线程中使用,不需要锁的保护。
其实这很好理解,每个状态中都有显示数据及其处理的描述。mCurrentState在做显示数据的准备,mDrawingState状态,就是将显示数据合成送给Display。两个处理同时进行,两个都处理完后,再将mCurrentState处理状态,给到mDrawingState。主线程根据mDrawingState中描述的显示数据和处理,把数据进行合成。
状态的处理,同样分为Display和Layer。
Client端采用Mask标记的方式,标记处理状态的改变。SurfaceFlinger这边收到后,根据mask标记,再将参数还原出来。保存到mCurrentState中。Display状态的处理如下:
uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
{
ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
if (dpyIdx < 0)
return 0;
uint32_t flags = 0;
DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
if (disp.isValid()) {
const uint32_t what = s.what;
... ...
if (what & DisplayState::eDisplaySizeChanged) {
if (disp.width != s.width) {
disp.width = s.width;
flags |= eDisplayTransactionNeeded;
}
if (disp.height != s.height) {
disp.height = s.height;
flags |= eDisplayTransactionNeeded;
}
}
}
return flags;
}
Layer状态的处理也是类似的,我们来看一下z-order的处理。
uint32_t SurfaceFlinger::setClientStateLocked(
const sp& client,
const layer_state_t& s)
{
... ...
if (what & layer_state_t::eLayerChanged) {
// NOTE: index needs to be calculated before we update the state
const auto& p = layer->getParent();
if (p == nullptr) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z) && idx >= 0) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
} else {
if (p->setChildLayer(layer, s.z)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
}
... ...
}
SurfaceFlinger有两个状态,Layer也是有两个状态的。
bool Layer::setLayer(int32_t z) {
if (mCurrentState.z == z) return false;
mCurrentState.sequence++;
mCurrentState.z = z;
mCurrentState.modified = true;
// Discard all relative layering.
if (mCurrentState.zOrderRelativeOf != nullptr) {
sp strongRelative = mCurrentState.zOrderRelativeOf.promote();
if (strongRelative != nullptr) {
strongRelative->removeZOrderRelative(this);
}
mCurrentState.zOrderRelativeOf = nullptr;
}
setTransactionFlags(eTransactionNeeded);
return true;
}
到此,我们的WindowSurfaceWrapper基本算构建完成。
小结
本章从Native应用的角度出发,讲解了应用怎么和SurfaceFlinger建立联系,同时介绍了SurfaceFlinger的启动。我们做应用开发,坑需要根据实际的屏幕参数来做,所以介绍了怎么获取显示屏参数信息;SurfaceFlinger中显示的数据都是通过Layer进行封装,介绍了创建Layer的过程。最后,介绍了,显示的数据参数,也就说处理的状态,怎么从Client端传到SurfaceFlinger的。