Android CRT Screen 电视效果

阅读更多

Android 2.3 对关屏进行了优化,增加了一种类似于关闭电视的效果 

Android系统默认使用的关屏效果是fade,要激活旧CRT效果,需要修改以下文件,关闭fade效果。

 

 

frameworks/base/core/res/res/values/config.xml

 

 

  1.       
  2.   
  3. -    < bool   name = "config_animateScreenLights" > true bool >   
  4.   
  5. +    < bool   name = "config_animateScreenLights" > false bool >   

 

 

为啥如此修改就可以激活旧CRT效果,让我们跟踪下代码,先贴上相关代码:

 

 

frameworks\base\services\java\com\Android \server\PowerManagerService.java

 

 

  1.   475                  mAnimationSetting =  0 ;  
  2.   
  3.  476                   if  (windowScale >  0 .5f) {  
  4.   
  5.  477                      mAnimationSetting |= ANIM_SETTING_OFF;  
  6.   
  7.  478                  }  
  8.   
  9.   
  10.   
  11.   
  12.   
  13. 2284           public   void  run() {  
  14.   
  15. 2285               if  (mAnimateScreenLights) {  
  16.   
  17. 2286                   synchronized  (mLocks) {  
  18.   
  19. 2287                       long  now = SystemClock.uptimeMillis();  
  20.   
  21. 2288                       boolean  more = mScreenBrightness.stepLocked();  
  22.   
  23. 2289                       if  (more) {  
  24.   
  25. 2290                          mScreenOffHandler.postAtTime( this , now+( 1000 / 60 ));  
  26.   
  27. 2291                      }  
  28.   
  29. 2292                  }  
  30.   
  31. 2293              }  else  {  
  32.   
  33. 2294                   synchronized  (mLocks) {  
  34.   
  35. 2295                       // we're turning off   
  36.   
  37. 2296                       final   boolean  animate = animating && targetValue == Power.BRIGHTNESS_OFF;  
  38.   
  39. 2297                       if  (animate) {  
  40.   
  41. 2298                           // It's pretty scary to hold mLocks for this long, and we should   
  42.   
  43. 2299                           // redesign this, but it works for now.   
  44.   
  45. 2300                          nativeStartSurfaceFlingerAnimation(  
  46.   
  47. 2301                                  mScreenOffReason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR  
  48.   
  49. 2302                                  ?  0  : mAnimationSetting);  
  50.   
  51. 2303                      }  
  52.   
  53. 2304                      mScreenBrightness.jumpToTargetLocked();  
  54.   
  55. 2305                  }  
  56.   
  57. 2306              }  
  58.   
  59. 2307          }  
  60.   
  61. 2308      }  

 

frameworks/base/services/jni/com_Android_server_PowerManagerService.cpp

 

 

  1. class = "cpp"  name= "code" >     131   static   void  Android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation(JNIEnv* env,  
  2.   
  3.     132          jobject obj, jint mode) {  
  4.   
  5.     133      sp s(ComposerService::getComposerService());  
  6.   
  7.     134      s->turnElectronBeamOff(mode);  
  8.   
  9.     135  }  

 

 

 

frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp

 

  1. 2385  status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)  
  2.   
  3. 2386  {  
  4.   
  5. 2387       class  MessageTurnElectronBeamOff :  public  MessageBase {  
  6.   
  7. 2388          SurfaceFlinger* flinger;  
  8.   
  9. 2389          int32_t mode;  
  10.   
  11. 2390          status_t result;  
  12.   
  13. 2391       public :  
  14.   
  15. 2392          MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)  
  16.   
  17. 2393              : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {  
  18.   
  19. 2394          }  
  20.   
  21. 2395          status_t getResult()  const  {  
  22.   
  23. 2396               return  result;  
  24.   
  25. 2397          }  
  26.   
  27. 2398          virtual bool handler() {  
  28.   
  29. 2399              Mutex::Autolock _l(flinger->mStateLock);  
  30.   
  31. 2400              result = flinger->turnElectronBeamOffImplLocked(mode);  
  32.   
  33. 2401               return   true ;  
  34.   
  35. 2402          }  
  36.   
  37. 2403      };  
  38.   
  39. 2404   
  40.   
  41. 2405      sp msg =  new  MessageTurnElectronBeamOff( this , mode);  
  42.   
  43. 2406      status_t res = postMessageSync(msg);  
  44.   
  45. 2407       if  (res == NO_ERROR) {  
  46.   
  47. 2408          res = static_cast( msg.get() )->getResult();  
  48.   
  49. 2409   
  50.   
  51. 2410           // work-around: when the power-manager calls us we activate the   
  52.   
  53. 2411           // animation. eventually, the "on" animation will be called   
  54.   
  55. 2412           // by the power-manager itself   
  56.   
  57. 2413          mElectronBeamAnimationMode = mode;  
  58.   
  59. 2414      }  
  60.   
  61. 2415       return  res;  
  62.   
  63. 2416  }  
  64.   
  65.   
  66.   
  67.   
  68.   
  69. 2363  status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)  
  70.   
  71. 2364  {  
  72.   
  73. 2365      DisplayHardware& hw(graphicPlane( 0 ).editDisplayHardware());  
  74.   
  75. 2366       if  (!hw.canDraw()) {  
  76.   
  77. 2367           // we're already off   
  78.   
  79. 2368           return  NO_ERROR;  
  80.   
  81. 2369      }  
  82.   
  83. 2370       if  (mode & ISurfaceComposer::eElectronBeamAnimationOff) {  
  84.   
  85. 2371          electronBeamOffAnimationImplLocked();  
  86.   
  87. 2372      }  
  88.   
  89. 2373   
  90.   
  91. 2374       // always clear the whole screen at the end of the animation   
  92.   
  93. 2375      glClearColor( 0 , 0 , 0 , 1 );  
  94.   
  95. 2376      glDisable(GL_SCISSOR_TEST);  
  96.   
  97. 2377      glClear(GL_COLOR_BUFFER_BIT);  
  98.   
  99. 2378      glEnable(GL_SCISSOR_TEST);  
  100.   
  101. 2379      hw.flip( Region(hw.bounds()) );  
  102.   
  103. 2380   
  104.   
  105. 2381      hw.setCanDraw( false );  
  106.   
  107. 2382       return  NO_ERROR;  
  108.   
  109. 2383  }  
  110.   
  111.   
  112.   
  113. 2073  status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()  
  114.   
  115. 2074  {  
  116.   
  117. 2075      status_t result = PERMISSION_DENIED;  
  118.   
  119. 2076   
  120.   
  121. 2077       if  (!GLExtensions::getInstance().haveFramebufferObject())  
  122.   
  123. 2078           return  INVALID_OPERATION;  
  124.   
  125. 2079   
  126.   
  127. 2080       // get screen geometry   
  128.   
  129. 2081       const  DisplayHardware& hw(graphicPlane( 0 ).displayHardware());  
  130.   
  131. 2082       const  uint32_t hw_w = hw.getWidth();  
  132.   
  133. 2083       const  uint32_t hw_h = hw.getHeight();  
  134.   
  135. 2084       const  Region screenBounds(hw.bounds());  
  136.   
  137. 2085   
  138.   
  139. 2086      GLfloat u, v;  
  140.   
  141. 2087      GLuint tname;  
  142.   
  143. 2088      result = renderScreenToTextureLocked( 0 , &tname, &u, &v);  
  144.   
  145. 2089       if  (result != NO_ERROR) {  
  146.   
  147. 2090           return  result;  
  148.   
  149. 2091      }  
  150.   
  151. 2092   
  152.   
  153. 2093      GLfloat vtx[ 8 ];  
  154.   
  155. 2094       const  GLfloat texCoords[ 4 ][ 2 ] = { { 0 ,v}, { 0 , 0 }, {u, 0 }, {u,v} };  
  156.   
  157. 2095      glEnable(GL_TEXTURE_2D);  
  158.   
  159. 2096      glBindTexture(GL_TEXTURE_2D, tname);  
  160.   
  161. 2097      glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);  
  162.   
  163. 2098      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
  164.   
  165. 2099      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
  166.   
  167. 2100      glTexCoordPointer( 2 , GL_FLOAT,  0 , texCoords);  
  168.   
  169. 2101      glEnableClientState(GL_TEXTURE_COORD_ARRAY);  
  170.   
  171. 2102      glVertexPointer( 2 , GL_FLOAT,  0 , vtx);  
  172.   
  173. 2103   
  174.   
  175. 2104       class  s_curve_interpolator {  
  176.   
  177. 2105           const   float  nbFrames, s, v;  
  178.   
  179. 2106       public :  
  180.   
  181. 2107          s_curve_interpolator( int  nbFrames,  float  s)  
  182.   
  183. 2108          : nbFrames( 1 .0f / (nbFrames- 1 )), s(s),  
  184.   
  185. 2109            v( 1 .0f + expf(-s +  0 .5f*s)) {  
  186.   
  187. 2110          }  
  188.   
  189. 2111           float  operator()( int  f) {  
  190.   
  191. 2112               const   float  x = f * nbFrames;  
  192.   
  193. 2113               return  (( 1 .0f/( 1 .0f + expf(-x*s +  0 .5f*s))) -  0 .5f) * v +  0 .5f;  
  194.   
  195. 2114          }  
  196.   
  197. 2115      };  
  198.   
  199. 2116   
  200.   
  201. 2117       class  v_stretch {  
  202.   
  203. 2118           const  GLfloat hw_w, hw_h;  
  204.   
  205. 2119       public :  
  206.   
  207. 2120          v_stretch(uint32_t hw_w, uint32_t hw_h)  
  208.   
  209. 2121          : hw_w(hw_w), hw_h(hw_h) {  
  210.   
  211. 2122          }  
  212.   
  213. 2123           void  operator()(GLfloat* vtx,  float  v) {  
  214.   
  215. 2124               const  GLfloat w = hw_w + (hw_w * v);  
  216.   
  217. 2125               const  GLfloat h = hw_h - (hw_h * v);  
  218.   
  219. 2126               const  GLfloat x = (hw_w - w) *  0 .5f;  
  220.   
  221. 2127               const  GLfloat y = (hw_h - h) *  0 .5f;  
  222.   
  223. 2128              vtx[ 0 ] = x;         vtx[ 1 ] = y;  
  224.   
  225. 2129              vtx[ 2 ] = x;         vtx[ 3 ] = y + h;  
  226.   
  227. 2130              vtx[ 4 ] = x + w;     vtx[ 5 ] = y + h;  
  228.   
  229. 2131              vtx[ 6 ] = x + w;     vtx[ 7 ] = y;  
  230.   
  231. 2132          }  
  232.   
  233. 2133      };  
  234.   
  235. 2134   
  236.   
  237. 2135       class  h_stretch {  
  238.   
  239. 2136           const  GLfloat hw_w, hw_h;  
  240.   
  241. 2137       public :  
  242.   
  243. 2138          h_stretch(uint32_t hw_w, uint32_t hw_h)  
  244.   
  245. 2139          : hw_w(hw_w), hw_h(hw_h) {  
  246.   
  247. 2140          }  
  248.   
  249. 2141           void  operator()(GLfloat* vtx,  float  v) {  
  250.   
  251. 2142               const  GLfloat w = hw_w - (hw_w * v);  
  252.   
  253. 2143               const  GLfloat h =  1 .0f;  
  254.   
  255. 2144               const  GLfloat x = (hw_w - w) *  0 .5f;  
  256.   
  257. 2145               const  GLfloat y = (hw_h - h) *  0 .5f;  
  258.   
  259. 2146              vtx[ 0 ] = x;         vtx[ 1 ] = y;  
  260.   
  261. 2147              vtx[ 2 ] = x;         vtx[ 3 ] = y + h;  
  262.   
  263. 2148              vtx[ 4 ] = x + w;     vtx[ 5 ] = y + h;  
  264.   
  265. 2149              vtx[ 6 ] = x + w;     vtx[ 7 ] = y;  
  266.   
  267. 2150          }  
  268.   
  269. 2151      };  
  270.   
  271. 2152   
  272.   
  273. 2153       // the full animation is 24 frames   
  274.   
  275. 2154       const   int  nbFrames =  12 ;  
  276.   
  277. 2155      s_curve_interpolator itr(nbFrames,  7 .5f);  
  278.   
  279. 2156      s_curve_interpolator itg(nbFrames,  8 .0f);  
  280.   
  281. 2157      s_curve_interpolator itb(nbFrames,  8 .5f);  
  282.   
  283. 2158   
  284.   
  285. 2159      v_stretch vverts(hw_w, hw_h);  
  286.   
  287. 2160      glEnable(GL_BLEND);  
  288.   
  289. 2161      glBlendFunc(GL_ONE, GL_ONE);  
  290.   
  291. 2162       for  ( int  i= 0  ; i
  292.   
  293. 2163           float  x, y, w, h;  
  294.   
  295. 2164           const   float  vr = itr(i);  
  296.   
  297. 2165           const   float  vg = itg(i);  
  298.   
  299. 2166           const   float  vb = itb(i);  
  300.   
  301. 2167   
  302.   
  303. 2168           // clear screen   
  304.   
  305. 2169          glColorMask( 1 , 1 , 1 , 1 );  
  306.   
  307. 2170          glClear(GL_COLOR_BUFFER_BIT);  
  308.   
  309. 2171          glEnable(GL_TEXTURE_2D);  
  310.   
  311. 2172   
  312.   
  313. 2173           // draw the red plane   
  314.   
  315. 2174          vverts(vtx, vr);  
  316.   
  317. 2175          glColorMask( 1 , 0 , 0 , 1 );  
  318.   
  319. 2176          glDrawArrays(GL_TRIANGLE_FAN,  0 4 );  
  320.   
  321. 2177   
  322.   
  323. 2178           // draw the green plane   
  324.   
  325. 2179          vverts(vtx, vg);  
  326.   
  327. 2180          glColorMask( 0 , 1 , 0 , 1 );  
  328.   
  329. 2181          glDrawArrays(GL_TRIANGLE_FAN,  0 4 );  
  330.   
  331. 2182   
  332.   
  333. 2183           // draw the blue plane   
  334.   
  335. 2184          vverts(vtx, vb);  
  336.   
  337. 2185          glColorMask( 0 , 0 , 1 , 1 );  
  338.   
  339. 2186          glDrawArrays(GL_TRIANGLE_FAN,  0 4 );  
  340.   
  341. 2187   
  342.   
  343. 2188           // draw the white highlight (we use the last vertices)   
  344.   
  345. 2189          glDisable(GL_TEXTURE_2D);  
  346.   
  347. 2190          glColorMask( 1 , 1 , 1 , 1 );  
  348.   
  349. 2191          glColor4f(vg, vg, vg,  1 );  
  350.   
  351. 2192          glDrawArrays(GL_TRIANGLE_FAN,  0 4 );  
  352.   
  353. 2193          hw.flip(screenBounds);  
  354.   
  355. 2194      }  
  356.   
  357. 2195   
  358.   
  359. 2196      h_stretch hverts(hw_w, hw_h);  
  360.   
  361. 2197      glDisable(GL_BLEND);  
  362.   
  363. 2198      glDisable(GL_TEXTURE_2D);  
  364.   
  365. 2199      glColorMask( 1 , 1 , 1 , 1 );  
  366.   
  367. 2200       for  ( int  i= 0  ; i
  368.   
  369. 2201           const   float  v = itg(i);  
  370.   
  371. 2202          hverts(vtx, v);  
  372.   
  373. 2203          glClear(GL_COLOR_BUFFER_BIT);  
  374.   
  375. 2204          glColor4f( 1 -v,  1 -v,  1 -v,  1 );  
  376.   
  377. 2205          glDrawArrays(GL_TRIANGLE_FAN,  0 4 );  
  378.   
  379. 2206          hw.flip(screenBounds);  
  380.   
  381. 2207      }  
  382.   
  383. 2208   
  384.   
  385. 2209      glColorMask( 1 , 1 , 1 , 1 );  
  386.   
  387. 2210      glEnable(GL_SCISSOR_TEST);  
  388.   
  389. 2211      glDisableClientState(GL_TEXTURE_COORD_ARRAY);  
  390.   
  391. 2212      glDeleteTextures( 1 , &tname);  
  392.   
  393. 2213       return  NO_ERROR;  
  394.   
  395. 2214  }  
  396.   
  397. 2215   

 

 

 

OK,看完代码回来,首先是PowerManagerService.java中

mAnimationSetting如果标记为ANIM_SETTING_OFF,则打开旧CRT动画。

 

下面关屏动作run()中,因为我们将config_animateScreenLights置为false,因此mAnimateScreenLights为fasle

分支进入else,执行nativeStartSurfaceFlingerAnimation()函数。

 

nativeStartSurfaceFlingerAnimation()函数是一个JNI调用,在com_Android_server_PowerManagerService.cpp文件中,

对应surfaceflinger的s->turnElectronBeamOff(mode)函数。

 

好的,现在跳入SurfaceFlinger.cpp函数,具体调用顺序是:

turnElectronBeamOff()

|

turnElectronBeamOffImplLocked()

|

electronBeamOffAnimationImplLocked()

 

electronBeamOffAnimationImplLocked()函数将调用openGL绘值旧CRT关屏效果,大概有24帧。

 

当然,该函数有许多限制,不符合就会半途退出,你就看不到动画效果啦。

你可能感兴趣的:(android,crt,screen,电视效果)