// by the power-manager itself
2413 mElectronBeamAnimationMode = mode;
2414 }
2415 return res;
2416 }
2363 status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
2364 {
2365 DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
2366 if (!hw.canDraw()) {
2367 // we're already off
2368 return NO_ERROR;
2369 }
2370 if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
2371 electronBeamOffAnimationImplLocked();
2372 }
2373
2374 // always clear the whole screen at the end of the animation
2375 glClearColor(0,0,0,1);
2376 glDisable(GL_SCISSOR_TEST);
2377 glClear(GL_COLOR_BUFFER_BIT);
2378 glEnable(GL_SCISSOR_TEST);
2379 hw.flip( Region(hw.bounds()) );
2380
2381 hw.setCanDraw(false);
2382 return NO_ERROR;
2383 }
2073 status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
2074 {
2075 status_t result = PERMISSION_DENIED;
2076
2077 if (!GLExtensions::getInstance().haveFramebufferObject())
2078 return INVALID_OPERATION;
2079
2080 // get screen geometry
2081 const DisplayHardware& hw(graphicPlane(0).displayHardware());
2082 const uint32_t hw_w = hw.getWidth();
2083 const uint32_t hw_h = hw.getHeight();
2084 const Region screenBounds(hw.bounds());
2085
2086 GLfloat u, v;
2087 GLuint tname;
2088 result = renderScreenToTextureLocked(0, &tname, &u, &v);
2089 if (result != NO_ERROR) {
2090 return result;
2091 }
2092
2093 GLfloat vtx[8];
2094 const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
2095 glEnable(GL_TEXTURE_2D);
2096 glBindTexture(GL_TEXTURE_2D, tname);
2097 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2098 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2099 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2100 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
2101 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2102 glVertexPointer(2, GL_FLOAT, 0, vtx);
2103
2104 class s_curve_interpolator {
2105 const float nbFrames, s, v;
2106 public:
2107 s_curve_interpolator(int nbFrames, float s)
2108 : nbFrames(1.0f / (nbFrames-1)), s(s),
2109 v(1.0f + expf(-s + 0.5f*s)) {
2110 }
2111 float operator()(int f) {
2112 const float x = f * nbFrames;
2113 return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
2114 }
2115 };
2116
2117 class v_stretch {
2118 const GLfloat hw_w, hw_h;
2119 public:
2120 v_stretch(uint32_t hw_w, uint32_t hw_h)
2121 : hw_w(hw_w), hw_h(hw_h) {
2122 }
2123 void operator()(GLfloat* vtx, float v) {
2124 const GLfloat w = hw_w + (hw_w * v);
2125 const GLfloat h = hw_h - (hw_h * v);
2126 const GLfloat x = (hw_w - w) * 0.5f;
2127 const GLfloat y = (hw_h - h) * 0.5f;
2128 vtx[0] = x; vtx[1] = y;
2129 vtx[2] = x; vtx[3] = y + h;
2130 vtx[4] = x + w; vtx[5] = y + h;
2131 vtx[6] = x + w; vtx[