Android60 亮屏灭屏流程DisplayPowerControlerWMS二亮度设置.docx
《Android60 亮屏灭屏流程DisplayPowerControlerWMS二亮度设置.docx》由会员分享,可在线阅读,更多相关《Android60 亮屏灭屏流程DisplayPowerControlerWMS二亮度设置.docx(16页珍藏版)》请在冰豆网上搜索。
Android60亮屏灭屏流程DisplayPowerControlerWMS二亮度设置
Android6.0亮屏灭屏流程(DisplayPowerControler、WMS)
(二)亮度设置
从这个函数开始分析,主要分析下亮度的设置流程。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
publicvoidsetScreenState(intstate){
if(mScreenState!
=state){
if(DEBUG){
Slog.d(TAG,"setScreenState:
state="+state);
}
mScreenState=state;
mScreenReady=false;
scheduleScreenUpdate();
}
}
scheduleScreenUpdate主要通过消息方式,最后调用到下面函数。
当我们屏幕刚要点亮,这个时候mScreenBrightness为0,所以这个时候调用mPhotonicModulator.setState设置state是点亮,但是brightness是0的。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
privatefinalRunnablemScreenUpdateRunnable=newRunnable(){
@Override
publicvoidrun(){
mScreenUpdatePending=false;
intbrightness=mScreenState!
=Display.STATE_OFF
&&mColorFadeLevel>0f?
mScreenBrightness:
0;
if(mPhotonicModulator.setState(mScreenState,brightness)){
if(DEBUG){
Slog.d(TAG,"Screenready");
}
mScreenReady=true;
invokeCleanListenerIfNeeded();
}else{
if(DEBUG){
Slog.d(TAG,"Screennotready");
}
}
}
};
DisplayPowerState的设置亮度状态逻辑分析
mPhotonicModulator.setState应该要PhotonicModulator的run函数结合一起看。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
publicbooleansetState(intstate,intbacklight){
synchronized(mLock){
booleanstateChanged=state!
=mPendingState;
booleanbacklightChanged=backlight!
=mPendingBacklight;
if(stateChanged||backlightChanged){
if(DEBUG){
Slog.d(TAG,"Requestingnewscreenstate:
state="
+Display.stateToString(state)+",backlight="+backlight);
}
mPendingState=state;
mPendingBacklight=backlight;
booleanchangeInProgress=mStateChangeInProgress||mBacklightChangeInProgress;
mStateChangeInProgress=stateChanged;
mBacklightChangeInProgress=backlightChanged;
if(!
changeInProgress){
Slog.d(TAG,"notifysetbacklightthreadrun");
mLock.notifyAll();
}
}
return!
mStateChangeInProgress;
}
}
两者结合看先setState设置了状态,只有状态改变时,我们才能重新设置状态(设置到mpendingState和mPendingBacklight)。
而在run函数中,当设置的状态mPendingState、mPendingBacklight和mActualState、mActualBacklight(真正设置到背光的状态、亮度)不一样时,才会调用mBlanker.requestDisplayState设置亮度。
否则状态没有改变,就会把mStateChangeInProgress和mBacklightChangeInProgress设置为false,然后线程就wait住。
而此时setState重新设置下来的话,这个时候把亮度和状态设置到mPendingState和mPendingBacklight。
然后这时mStateChangeInProgress和mBacklightChangeInProgress都是false。
这样就可以调用mLock的notifyAll函数重新唤醒线程,这样就把把前面setState设置下来的mPendingState和mPendingBacklight再通过mBlanker.requestDisplayState设置到背光设备中去。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
@Override
publicvoidrun(){
for(;;){
//Getpendingchange.
finalintstate;
finalbooleanstateChanged;
finalintbacklight;
finalbooleanbacklightChanged;
synchronized(mLock){
state=mPendingState;
stateChanged=(state!
=mActualState);
backlight=mPendingBacklight;
backlightChanged=(backlight!
=mActualBacklight);
if(!
stateChanged){
//Statechangedapplied,notifyouterclass.
postScreenUpdateThreadSafe();
mStateChangeInProgress=false;
}
if(!
backlightChanged){
mBacklightChangeInProgress=false;
}
if(!
stateChanged&&!
backlightChanged){
try{
mLock.wait();
}catch(InterruptedExceptionex){}
continue;
}
mActualState=state;
mActualBacklight=backlight;
}
//Applypendingchange.
if(true){
Slog.d(TAG,"Updatingscreenstate:
state="
+Display.stateToString(state)+",backlight="+backlight);
}
mBlanker.requestDisplayState(state,backlight);
Slog.d(TAG,"kangchenUpdatingscreenstate:
state=");
}
}
设置亮度、状态到背光设备
DisplayBlanker的requestDisplayState如下,主要调用requestGlobalDisplayStateInternal函数。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
DisplayBlankerblanker=newDisplayBlanker(){
@Override
publicvoidrequestDisplayState(intstate,intbrightness){
//Theorderofoperationsisimportantforlegacyreasons.
if(state==Display.STATE_OFF){
requestGlobalDisplayStateInternal(state,brightness);
}
callbacks.onDisplayStateChange(state);
if(state!
=Display.STATE_OFF){
requestGlobalDisplayStateInternal(state,brightness);
}
}
};
requestGlobalDisplayStateInternal函数先是对state和brightness的处理,然后把这个两个变量放在mGlobalDisplayState和mGlobalDisplayBrightness成员变量中。
紧接着调用applyGlobalDisplayStateLocked函数mTempDisplayStateWorkQueue作为参数。
最后再调用mTempDisplayStateWorkQueue各个成员的run函数(这里返回的是Runnable接口,这里就会设置状态和亮度到设备中去)。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
privatevoidrequestGlobalDisplayStateInternal(intstate,intbrightness){
if(state==Display.STATE_UNKNOWN){
state=Display.STATE_ON;
}
if(state==Display.STATE_OFF){
brightness=PowerManager.BRIGHTNESS_OFF;
}elseif(brightness<0){
brightness=PowerManager.BRIGHTNESS_DEFAULT;
}elseif(brightness>PowerManager.BRIGHTNESS_ON){
brightness=PowerManager.BRIGHTNESS_ON;
}
synchronized(mTempDisplayStateWorkQueue){
try{
synchronized(mSyncRoot){
if(mGlobalDisplayState==state
&&mGlobalDisplayBrightness==brightness){
return;//nochange
}
mGlobalDisplayState=state;
mGlobalDisplayBrightness=brightness;
applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
}
//Settingthedisplaypowerstatecantakehundredsofmilliseconds
//tocompletesowedeferthemostexpensivepartoftheworkuntil
//afterwehaveexitedthecriticalsectiontoavoidblockingother
//threadsforalongtime.
for(inti=0;imTempDisplayStateWorkQueue.get(i).run();//设置亮度、状态到设备
}
}finally{
mTempDisplayStateWorkQueue.clear();
}
}
}
applyGlobalDisplayStateLocked函数会遍历各个显示设备(多显示),然后调用updateDisplayStateLocked函数返回一个Runnable,最后把这个Runnable放入之前传入的mTempDisplayStateWorkQueue队列中。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
privatevoidapplyGlobalDisplayStateLocked(ListworkQueue){
finalintcount=mDisplayDevices.size();
for(inti=0;iDisplayDevicedevice=mDisplayDevices.get(i);
Runnablerunnable=updateDisplayStateLocked(device);
if(runnable!
=null){
workQueue.add(runnable);
}
}
}
那下面我们看下updateDisplayStateLocked函数,主要是调用了DisplayDevice的requestDisplayStateLocked函数,当然mGlobalDisplayState和mGlobalDisplayBrightness作为参数。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
privateRunnableupdateDisplayStateLocked(DisplayDevicedevice){
//Blankorunblankthedisplayimmediatelytomatchthestaterequested
//bythedisplaypowercontroller(ifknown).
DisplayDeviceInfoinfo=device.getDisplayDeviceInfoLocked();
if((info.flags&DisplayDeviceInfo.FLAG_NEVER_BLANK)==0){
returndevice.requestDisplayStateLocked(mGlobalDisplayState,mGlobalDisplayBrightness);
}
returnnull;
}
这里的DisplayDevice的requestDisplayStateLocked函数,是在LocalDisplayAdapter中实现的,这里吧state和brightness保存在mState和mBrightness中,然后返回Runnable接口,最后在Runnable接口中设置亮度和状态。
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
publicRunnablerequestDisplayStateLocked(finalintstate,finalintbrightness){
//Assumethatthebrightnessisoffifthedisplayisbeingturnedoff.
assertstate!
=Display.STATE_OFF||brightness==PowerManager.BRIGHTNESS_OFF;
finalbooleanstateChanged=(mState!
=state);
finalbooleanbrightnessChanged=(mBrightness!
=brightness)&&mBacklight!
=null;
if(stateChanged||brightnessChanged){
finalintdisplayId=mBuiltInDisplayId;
finalIBindertoken=getDisplayTokenLocked();
finalintoldState=mState;
if(stateChanged){
mState=state;//保存state
updateDeviceInfoLocked();
}
if(brightnessChanged){
mBrightness=brightness;//保存brightness
}
//Deferactuallysettingthedisplaystateuntilafterwehaveexited
//thecriticalsectionsinceitcantakehundredsofmilliseconds
//tocomplete.
returnnewRunnable(){//返回Runnable
@Override
publicvoidrun(){
//Exitasuspendedstatebeforemakinganychanges.
intcurrentState=oldState;
if(Display.isSuspendedState(oldState)
||oldState==Display.STATE_UNKNOWN){
if(!
Display.isSuspendedState(state)){
setDisplayState(state);
currentState=state;
}elseif(state==Display.STATE_DOZE_SUSPEND
||oldState==Display.STATE_DOZE_SUSPEND){
setDisplayState(Display.STATE_DOZE);
currentState=Display.STATE_DOZE;
}else{
return;//oldstateandnewstateisoff
}
}
//Applybrightnesschangesgiventhatweareinanon-suspendedstate.
if(brightnessChanged){
Slog.d(TAG,"kangchensetDisplayBrightnessbrightness1="+brightness);
setDisplayBrightness(brightness);
Slog.d(TAG,"kangchensetDisplayBrightnessbrightness2="+brightness);
}
//Enterthefinaldesiredstate,possiblysuspended.
if(state!
=currentState){
setDisplayState(state);
}
}
privatevoidsetDisplayState(intstate){
if(DEBUG){
Slog.d(TAG,"setDisplayState("
+"id="+displayId
+",state="+Display.stateToString(state)+")");
}
try{
finalintmode=getPowerModeForState(state);
SurfaceControl.setDisplayPowerMode(token,mode);//到SurfaceControl设置状态
}finally{
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
privatevoidsetDisplayBrightness(intbrightness){
try{
mBacklight.setBrightness(brightness);//设置亮度
}finally{
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
};
}
returnnull;
}
DisplayPowerControl设置亮度逻辑(根据VSync信号将亮度慢慢变亮)
上面在DisplayPowerState中仅仅是设置状态,比如刚点亮屏幕这个时候其实设置的brightness为0,我们继续分析DisplayPowerState的updatePowerState函数。
在updatePowerState函数中,当设置亮度时会调用如下代码:
[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片
if(!
mPendingScreenOff){
if(state==Display.STATE_ON||state==Display.STATE_DOZE){
animateScreenBrightness(brightness,
slowChange?
BRIGHTNESS_RAMP_RATE_SLOW:
BRIGHTNESS_RAMP_RATE_FAST);