详细,可参照
http://www.360doc.com/content/14/0329/23/10366845_364802340.shtml
首先,从BootAnimation开始分析,BootAnimation在启动脚本init。Rc被配置成一个服务
1.service bootanim /system/bin/bootanimation
2. class main
3. user graphics
4. group system audio graphics cw_access
5. disabled
6. oneshot
而其代码在frameworks/cmds/bootanimation
int main(int argc, char** argv)
{
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
#endif
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.nobootanimation", value, "0");
int noBootAnimation = atoi(value);
ALOGI_IF(noBootAnimation, "boot animation disabled");
if (!noBootAnimation) {
sp
ProcessState::self()->startThreadPool();
// create the boot animation object
sp
IPCThreadState::self()->joinThreadPool();
}
return 0;
}
从代码可以看出,bootanimation的启动是通过new一个BootAnimation
可以看出BootAnimation最终继承了RefBase
所以会执行了onFirstRef()
BootAnimation::BootAnimation() : Thread(false)
{
mSession = new SurfaceComposerClient();
}
void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);
ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
if (err == NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);
}
}
而SurfaceComposerClient的linkToComposerDeath函数获取了SurfaceFlinger服务,成功获取了之后
调用run,让BootAnimation线程跑起来,Thread会先跑到readyToRun(),然后再跑:threadLoop()
tatus_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
sp dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
if (status)
return -1;
// create the native surface
sp control = session()->createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction();
sp s = control->getSurface();
// initialize opengl and egl
const EGLint attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 0,
EGL_NONE
};
EGLint w, h, dummy;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
surface = eglCreateWindowSurface(display, config, s.get(), NULL);
context = eglCreateContext(display, config, NULL, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
return NO_INIT;
mDisplay = display;
mContext = context;
mSurface = surface;
mWidth = w;
mHeight = h;
mFlingerSurfaceControl = control;
mFlingerSurface = s;
mAndroidAnimation = true;
// If the device has encryption turned on or is in process
// of being encrypted we show the encrypted boot animation.
char decrypt[PROPERTY_VALUE_MAX];
property_get("vold.decrypt", decrypt, "");
bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt);
if ((encryptedAnimation &&
(access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) ||
((access(USER_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) ||
((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
(mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) {
mAndroidAnimation = false;
}
return NO_ERROR;
}
首先,通过向surfaceflinger service发送
sp dtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
告诉surfaceflinger service 获取DisplayId的Binder
rameworks/native/libs/gui/ISurfaceComposer.cpp
class BpSurfaceComposer : public BpInterface
{
...
virtual sp getBuiltInDisplay(int32_t id)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeInt32(id);
remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply);
return reply.readStrongBinder();
}
....
};
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case GET_BUILT_IN_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
int32_t id = data.readInt32();
sp display(getBuiltInDisplay(id));
reply->writeStrongBinder(display);
return NO_ERROR;
} break;
}
}
接着获取一个 DisplayInfo dinfo;
status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
同样看SurfaceFlinger.cpp
status_t SurfaceFlinger::getDisplayInfo(const sp& display, DisplayInfo* info)
{
int32_t type = NAME_NOT_FOUND;
for (int i=0 ; i 0) {
density = atoi(property);
}
return density;
}
public:
static int getEmuDensity() {
return getDensityFromProperty("qemu.sf.lcd_density"); }
static int getBuildDensity() {
return getDensityFromProperty("ro.sf.lcd_density"); }
};
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// The density of the device is provided by a build property
float density = Density::getBuildDensity() / 160.0f;
if (density == 0) {
// the build doesn't provide a density -- this is wrong!
// use xdpi instead
ALOGE("ro.sf.lcd_density must be defined as a build property");
density = xdpi / 160.0f;
}
if (Density::getEmuDensity()) {
// if "qemu.sf.lcd_density" is specified, it overrides everything
xdpi = ydpi = density = Density::getEmuDensity();
density /= 160.0f;
}
info->density = density;
// TODO: this needs to go away (currently needed only by webkit)
sp hw(getDefaultDisplayDevice());
info->orientation = hw->getOrientation();
getPixelFormatInfo(hw->getFormat(), &info->pixelFormatInfo);
} else {
// TODO: where should this value come from?
static const int TV_DENSITY = 213;
info->density = TV_DENSITY / 160.0f;
info->orientation = 0;
}
info->w = hwc.getWidth(type);
info->h = hwc.getHeight(type);
info->xdpi = xdpi;
info->ydpi = ydpi;
info->fps = float(1e9 / hwc.getRefreshPeriod(type));
// All non-virtual displays are currently considered secure.
info->secure = true;
return NO_ERROR;
}
接着,按返回的DisplayInfo创建一个native surface
/ create the native surface
sp control = session()->createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
接着
SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction();
etLayer从代码里看是设置z-order,层级越高越接近客户
设置完Z-order后
sp s = control->getSurface();
通过SurfaceControl获取了一个Surface
sp SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
mSurfaceData = new Surface(mGraphicBufferProducer);
}
return mSurfaceData;
}
Surface的创建则通过createsurface时创建的mGraphicBufferProducer(SurfaceTextureLayer)来初始化
Surface::Surface(
const sp& bufferProducer)
: mGraphicBufferProducer(bufferProducer)
{
// 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(ANativeWindow::minSwapInterval) = 0;
const_cast(ANativeWindow::maxSwapInterval) = 1;
mReqWidth = 0;
mReqHeight = 0;
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mDefaultWidth = 0;
mDefaultHeight = 0;
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
}
接着通过这个surface对象初始化egl
surface = eglCreateWindowSurface(display, config, s.get(), NULL);
其他都是走egl流程
然后,继续分析BootAnimation,跑完systemReadyRun,则会跑threadloop循环
bool BootAnimation::threadLoop()
{
bool r;
if (mAndroidAnimation) {
r = android();
} else {
r = movie();
}
// No need to force exit anymore
property_set(EXIT_PROP_NAME, "0");
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mFlingerSurface.clear();
mFlingerSurfaceControl.clear();
eglTerminate(mDisplay);
IPCThreadState::self()->stopProcess();
return r;
}
可以看出,如果mAndroidAnimation为true则跑android,不成功则跑movie