19630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/* 29630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Copyright (C) 2012 The Android Open Source Project 39630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 49630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 59630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * you may not use this file except in compliance with the License. 69630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * You may obtain a copy of the License at 79630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 89630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 99630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Unless required by applicable law or agreed to in writing, software 119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * See the License for the specific language governing permissions and 149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * limitations under the License. 159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownpackage com.android.server.power; 189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 190449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport java.io.PrintWriter; 200449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport java.nio.ByteBuffer; 210449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport java.nio.ByteOrder; 220449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport java.nio.FloatBuffer; 237f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown 249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.graphics.PixelFormat; 250449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport android.graphics.SurfaceTexture; 269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.opengl.EGL14; 279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.opengl.EGLConfig; 289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.opengl.EGLContext; 299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.opengl.EGLDisplay; 309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.opengl.EGLSurface; 319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.opengl.GLES10; 320449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport android.opengl.GLES11Ext; 339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.os.Looper; 349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.FloatMath; 359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.util.Slog; 369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.Display; 379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.DisplayInfo; 38a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkinimport android.view.Surface.OutOfResourcesException; 399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.Surface; 403866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl; 419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport android.view.SurfaceSession; 429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 430449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport com.android.server.display.DisplayManagerService; 440449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopianimport com.android.server.display.DisplayTransactionListener; 459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown/** 479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Bzzzoooop! *crackle* 488b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown * <p> 499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Animates a screen transition from on to off or off to on by applying 509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * some GL transformations to a screenshot. 518b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown * </p><p> 529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This component must only be created or accessed by the {@link Looper} thread 539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * that belongs to the {@link DisplayPowerController}. 548b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown * </p> 559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownfinal class ElectronBeam { 579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static final String TAG = "ElectronBeam"; 589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static final boolean DEBUG = false; 609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // The layer for the electron beam surface. 629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // This is currently hardcoded to be one layer above the boot animation. 639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static final int ELECTRON_BEAM_LAYER = 0x40000001; 649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // The relative proportion of the animation to spend performing 669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // the horizontal stretch effect. The remainder is spent performing 679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // the vertical stretch effect. 683c584f20ac8fe9378c094ad3b63936bca35954baJeff Brown private static final float HSTRETCH_DURATION = 0.5f; 699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static final float VSTRETCH_DURATION = 1.0f - HSTRETCH_DURATION; 709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 7178eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // The number of frames to draw when preparing the animation so that it will 7278eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // be ready to run smoothly. We use 3 frames because we are triple-buffered. 7378eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // See code for details. 7478eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown private static final int DEJANK_FRAMES = 3; 7578eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown 769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Set to true when the animation context has been fully prepared. 779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean mPrepared; 788b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private int mMode; 799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 807f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown private final DisplayManagerService mDisplayManager; 819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private int mDisplayLayerStack; // layer stack associated with primary display 829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private int mDisplayWidth; // real width, not rotated 839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private int mDisplayHeight; // real height, not rotated 849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private SurfaceSession mSurfaceSession; 853866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian private SurfaceControl mSurfaceControl; 8686e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian private Surface mSurface; 877f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown private NaturalSurfaceLayout mSurfaceLayout; 889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private EGLDisplay mEglDisplay; 899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private EGLConfig mEglConfig; 909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private EGLContext mEglContext; 919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private EGLSurface mEglSurface; 929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean mSurfaceVisible; 93252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown private float mSurfaceAlpha; 949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Texture names. We only use one texture, which contains the screenshot. 969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private final int[] mTexNames = new int[1]; 979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean mTexNamesGenerated; 98a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin private final float mTexMatrix[] = new float[16]; 999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Vertex and corresponding texture coordinates. 1019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // We have 4 2D vertices, so 8 elements. The vertices form a quad. 1029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private final FloatBuffer mVertexBuffer = createNativeFloatBuffer(8); 1039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8); 1049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 105252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown /** 106252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown * Animates an electron beam warming up. 107252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown */ 1088b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown public static final int MODE_WARM_UP = 0; 109252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown 110252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown /** 111252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown * Animates an electron beam shutting off. 112252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown */ 1138b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown public static final int MODE_COOL_DOWN = 1; 114252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown 115252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown /** 116252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown * Animates a simple dim layer to fade the contents of the screen in or out progressively. 117252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown */ 118252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown public static final int MODE_FADE = 2; 1198b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown 1200449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian 1217f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown public ElectronBeam(DisplayManagerService displayManager) { 1227f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayManager = displayManager; 1239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 1269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Warms up the electron beam in preparation for turning on or off. 1279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * This method prepares a GL context, and captures a screen shot. 1289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 1298b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown * @param mode The desired mode for the upcoming animation. 1309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @return True if the electron beam is ready, false if it is uncontrollable. 1319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1328b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown public boolean prepare(int mode) { 1339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 1348b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown Slog.d(TAG, "prepare: mode=" + mode); 1359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1378b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown mMode = mode; 1389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1397f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown // Get the display size and layer stack. 1407f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown // This is not expected to change while the electron beam surface is showing. 1417f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); 1427f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayLayerStack = displayInfo.layerStack; 1437f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayWidth = displayInfo.getNaturalWidth(); 1447f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayHeight = displayInfo.getNaturalHeight(); 1459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Prepare the surface for drawing. 1478b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown if (!tryPrepare()) { 1489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown dismiss(); 1499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 1509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1528b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown // Done. 1539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mPrepared = true; 15478eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown 15578eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // Dejanking optimization. 15678eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // Some GL drivers can introduce a lot of lag in the first few frames as they 15778eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // initialize their state and allocate graphics buffers for rendering. 15878eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // Work around this problem by rendering the first frame of the animation a few 15978eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // times. The rest of the animation should run smoothly thereafter. 16078eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // The frames we draw here aren't visible because we are essentially just 16178eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown // painting the screenshot as-is. 16278eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown if (mode == MODE_COOL_DOWN) { 16378eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown for (int i = 0; i < DEJANK_FRAMES; i++) { 16478eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown draw(1.0f); 16578eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown } 16678eb122450f127d66d4e8cf7f65cad80ea85d3acJeff Brown } 1679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 1689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1708b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private boolean tryPrepare() { 1718b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown if (createSurface()) { 172252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown if (mMode == MODE_FADE) { 1738b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return true; 1748b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 1758b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return createEglContext() 1768b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown && createEglSurface() 1778b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown && captureScreenshotTextureAndSetViewport(); 1788b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 1798b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return false; 1808b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 1818b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown 1829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 1839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Dismisses the electron beam animation surface and cleans up. 1849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 1859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * To prevent stray photons from leaking out after the electron beam has been 1869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * turned off, it is a good idea to defer dismissing the animation until the 1879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * electron beam has been turned back on fully. 1889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 1899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void dismiss() { 1909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 1919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "dismiss"); 1929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 1949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown destroyScreenshotTexture(); 1959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown destroyEglSurface(); 1968b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown destroySurface(); 1979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mPrepared = false; 1989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 1999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Draws an animation frame showing the electron beam activated at the 2029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * specified level. 2039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @param level The electron beam level. 2059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @return True if successful. 2069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public boolean draw(float level) { 2089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 2099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "drawFrame: level=" + level); 2109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2128b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown if (!mPrepared) { 2138b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return false; 2148b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 2158b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown 216252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown if (mMode == MODE_FADE) { 2178b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return showSurface(1.0f - level); 2188b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 2198b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown 2209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (!attachEglContext()) { 2219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 2229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 2249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Clear frame to solid black. 2259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glClearColor(0f, 0f, 0f, 1f); 2269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glClear(GLES10.GL_COLOR_BUFFER_BIT); 2279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Draw the frame. 2299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (level < HSTRETCH_DURATION) { 2309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown drawHStretch(1.0f - (level / HSTRETCH_DURATION)); 2319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } else { 2329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown drawVStretch(1.0f - ((level - HSTRETCH_DURATION) / VSTRETCH_DURATION)); 2339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (checkGlErrors("drawFrame")) { 2359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 2369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.eglSwapBuffers(mEglDisplay, mEglSurface); 2399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } finally { 2409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown detachEglContext(); 2419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2428b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return showSurface(1.0f); 2439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 2469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Draws a frame where the content of the electron beam is collapsing inwards upon 2479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * itself vertically with red / green / blue channels dispersing and eventually 2489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * merging down to a single horizontal line. 2499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 2509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * @param stretch The stretch factor. 0.0 is no collapse, 1.0 is full collapse. 2519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 2529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private void drawVStretch(float stretch) { 2539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // compute interpolation scale factors for each color channel 2549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float ar = scurve(stretch, 7.5f); 2559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float ag = scurve(stretch, 8.0f); 2569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float ab = scurve(stretch, 8.5f); 2579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 2589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "drawVStretch: stretch=" + stretch 2599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown + ", ar=" + ar + ", ag=" + ag + ", ab=" + ab); 2609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 2619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // set blending 2639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glBlendFunc(GLES10.GL_ONE, GLES10.GL_ONE); 2649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glEnable(GLES10.GL_BLEND); 2659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // bind vertex buffer 2679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer); 2689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY); 2699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2700449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian // set-up texturing 2710449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glDisable(GLES10.GL_TEXTURE_2D); 2720449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); 2730449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian 2749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // bind texture and set blending for drawing planes 2750449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]); 2769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE, 2778b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown mMode == MODE_WARM_UP ? GLES10.GL_MODULATE : GLES10.GL_REPLACE); 2780449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 2799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR); 2800449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 2819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR); 2820449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 2839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE); 2840449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 2859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE); 2860449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); 2879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer); 2889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); 2899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // draw the red plane 2919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ar); 2929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glColorMask(true, false, false, true); 2939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); 2949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 2959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // draw the green plane 2969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag); 2979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glColorMask(false, true, false, true); 2989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); 2999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // draw the blue plane 3019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown setVStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ab); 3029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glColorMask(false, false, true, true); 3039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); 3049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // clean up after drawing planes 3060449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glDisable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); 3079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); 3089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glColorMask(true, true, true, true); 3099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // draw the white highlight (we use the last vertices) 3118b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown if (mMode == MODE_COOL_DOWN) { 3129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glColor4f(ag, ag, ag, 1.0f); 3139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); 3149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // clean up 3179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY); 3189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDisable(GLES10.GL_BLEND); 3199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 3229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Draws a frame where the electron beam has been stretched out into 32397f0aa6f8a8b7c1ed41786404423b9c9fcf789b8Mathias Agopian * a thin white horizontal line that fades as it collapses inwards. 3249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * 32597f0aa6f8a8b7c1ed41786404423b9c9fcf789b8Mathias Agopian * @param stretch The stretch factor. 0.0 is maximum stretch / no fade, 32697f0aa6f8a8b7c1ed41786404423b9c9fcf789b8Mathias Agopian * 1.0 is collapsed / maximum fade. 3279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 3289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private void drawHStretch(float stretch) { 3299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // compute interpolation scale factor 3309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float ag = scurve(stretch, 8.0f); 3319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 3329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "drawHStretch: stretch=" + stretch + ", ag=" + ag); 3339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (stretch < 1.0f) { 3369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // bind vertex buffer 3379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer); 3389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY); 3399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // draw narrow fading white line 3419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown setHStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag); 34297f0aa6f8a8b7c1ed41786404423b9c9fcf789b8Mathias Agopian GLES10.glColor4f(1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f); 3439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); 3449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // clean up 3469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDisableClientState(GLES10.GL_VERTEX_ARRAY); 3479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static void setVStretchQuad(FloatBuffer vtx, float dw, float dh, float a) { 3519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float w = dw + (dw * a); 3529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float h = dh - (dh * a); 3539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float x = (dw - w) * 0.5f; 3549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float y = (dh - h) * 0.5f; 3559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown setQuad(vtx, x, y, w, h); 3569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static void setHStretchQuad(FloatBuffer vtx, float dw, float dh, float a) { 35997f0aa6f8a8b7c1ed41786404423b9c9fcf789b8Mathias Agopian final float w = 2 * dw * (1.0f - a); 3609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float h = 1.0f; 3619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float x = (dw - w) * 0.5f; 3629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float y = (dh - h) * 0.5f; 3639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown setQuad(vtx, x, y, w, h); 3649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static void setQuad(FloatBuffer vtx, float x, float y, float w, float h) { 3679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (DEBUG) { 3689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.d(TAG, "setQuad: x=" + x + ", y=" + y + ", w=" + w + ", h=" + h); 3699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(0, x); 3719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(1, y); 3729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(2, x); 3739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(3, y + h); 3749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(4, x + w); 3759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(5, y + h); 3769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(6, x + w); 3779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown vtx.put(7, y); 3789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 3809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean captureScreenshotTextureAndSetViewport() { 3810449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian if (!attachEglContext()) { 3829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 3839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 3850449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian if (!mTexNamesGenerated) { 3860449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glGenTextures(1, mTexNames, 0); 3870449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian if (checkGlErrors("glGenTextures")) { 3889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 3899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3900449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian mTexNamesGenerated = true; 3919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 3920449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian 39321ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey final SurfaceTexture st = new SurfaceTexture(mTexNames[0]); 39421ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey final Surface s = new Surface(st); 39521ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey try { 39621ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay( 39721ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s); 39821ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey } finally { 39921ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey s.release(); 40021ef9647e8bd9997ed63f891b13bc3cc0f566b52Jeff Sharkey } 4010449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian 4020449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian st.updateTexImage(); 4030449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian st.getTransformMatrix(mTexMatrix); 4040449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian 4050449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian // Set up texture coordinates for a quad. 4060449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian // We might need to change this if the texture ends up being 4070449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian // a different size from the display for some reason. 4080449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, 0f); 4090449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 1f); 4100449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian mTexCoordBuffer.put(4, 1f); mTexCoordBuffer.put(5, 1f); 4110449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f); 4120449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian 4130449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian // Set up our viewport. 4140449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight); 4150449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glMatrixMode(GLES10.GL_PROJECTION); 4160449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glLoadIdentity(); 4170449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1); 4180449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glMatrixMode(GLES10.GL_MODELVIEW); 4190449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glLoadIdentity(); 4200449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glMatrixMode(GLES10.GL_TEXTURE); 4210449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glLoadIdentity(); 4220449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian GLES10.glLoadMatrixf(mTexMatrix, 0); 4239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } finally { 4240449a40586b45ee05f760802020dc2f8a6e0506bMathias Agopian detachEglContext(); 4259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 4279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 4299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private void destroyScreenshotTexture() { 4309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mTexNamesGenerated) { 4319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mTexNamesGenerated = false; 4329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (attachEglContext()) { 4339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 4349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown GLES10.glDeleteTextures(1, mTexNames, 0); 4359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown checkGlErrors("glDeleteTextures"); 4369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } finally { 4379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown detachEglContext(); 4389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 4439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean createEglContext() { 4449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglDisplay == null) { 4459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); 4469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { 4479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglGetDisplay"); 4489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 4499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 4519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown int[] version = new int[2]; 4529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)) { 4539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglDisplay = null; 4549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglInitialize"); 4559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 4569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 4599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglConfig == null) { 4609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown int[] eglConfigAttribList = new int[] { 4619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_RED_SIZE, 8, 4629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_GREEN_SIZE, 8, 4639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_BLUE_SIZE, 8, 4649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_ALPHA_SIZE, 8, 4659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_NONE 4669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 4679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown int[] numEglConfigs = new int[1]; 4689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGLConfig[] eglConfigs = new EGLConfig[1]; 4699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (!EGL14.eglChooseConfig(mEglDisplay, eglConfigAttribList, 0, 4709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown eglConfigs, 0, eglConfigs.length, numEglConfigs, 0)) { 4719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglChooseConfig"); 4729630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 4739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglConfig = eglConfigs[0]; 4759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 4779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglContext == null) { 4789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown int[] eglContextAttribList = new int[] { 4799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_NONE 4809630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 4819630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglContext = EGL14.eglCreateContext(mEglDisplay, mEglConfig, 4829630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_NO_CONTEXT, eglContextAttribList, 0); 4839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglContext == null) { 4849630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglCreateContext"); 4859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 4869630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4889630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 4899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 4919630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /* not used because it is too expensive to create / destroy contexts all of the time 4929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private void destroyEglContext() { 4939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglContext != null) { 4949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (!EGL14.eglDestroyContext(mEglDisplay, mEglContext)) { 4959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglDestroyContext"); 4969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglContext = null; 4989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 4999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }*/ 5009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5018b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private boolean createSurface() { 5029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mSurfaceSession == null) { 5039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mSurfaceSession = new SurfaceSession(); 5049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5063866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.openTransaction(); 5079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 5083866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian if (mSurfaceControl == null) { 5099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 5108b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown int flags; 511252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown if (mMode == MODE_FADE) { 5123866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian flags = SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN; 5138b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } else { 5143866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN; 5158b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 5163866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl = new SurfaceControl(mSurfaceSession, 51764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown "ElectronBeam", mDisplayWidth, mDisplayHeight, 5188b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown PixelFormat.OPAQUE, flags); 519a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin } catch (OutOfResourcesException ex) { 5209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.e(TAG, "Unable to create surface.", ex); 5219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 5229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5253866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl.setLayerStack(mDisplayLayerStack); 5263866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight); 52786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian mSurface = new Surface(); 5283866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurface.copyFrom(mSurfaceControl); 529a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 5303866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurfaceControl); 5317f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mSurfaceLayout.onDisplayTransaction(); 5329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } finally { 5333866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.closeTransaction(); 5349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5358b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown return true; 5368b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 5379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5388b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private boolean createEglSurface() { 5399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglSurface == null) { 5409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown int[] eglSurfaceAttribList = new int[] { 5419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_NONE 5429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown }; 5433866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian // turn our SurfaceControl into a Surface 5449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, 5459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown eglSurfaceAttribList, 0); 5469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglSurface == null) { 5479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglCreateWindowSurface"); 5489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 5499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 5529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private void destroyEglSurface() { 5559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglSurface != null) { 5569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (!EGL14.eglDestroySurface(mEglDisplay, mEglSurface)) { 5579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglDestroySurface"); 5589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mEglSurface = null; 5609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5618b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown } 5629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5638b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private void destroySurface() { 5643866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian if (mSurfaceControl != null) { 5657f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mSurfaceLayout.dispose(); 5667f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mSurfaceLayout = null; 5673866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.openTransaction(); 5689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 5693866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl.destroy(); 5703866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurface.release(); 5719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } finally { 5723866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.closeTransaction(); 5739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5743866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl = null; 5759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mSurfaceVisible = false; 576252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown mSurfaceAlpha = 0f; 5779630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5799630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5808b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown private boolean showSurface(float alpha) { 581252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown if (!mSurfaceVisible || mSurfaceAlpha != alpha) { 5823866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.openTransaction(); 5839630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown try { 5843866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl.setLayer(ELECTRON_BEAM_LAYER); 5853866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl.setAlpha(alpha); 5863866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian mSurfaceControl.show(); 5879630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } finally { 5883866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.closeTransaction(); 5899630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5909630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown mSurfaceVisible = true; 591252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown mSurfaceAlpha = alpha; 5929630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5939630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 5949630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 5959630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 5969630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private boolean attachEglContext() { 5979630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglSurface == null) { 5989630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 5999630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6009630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (!EGL14.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 6019630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown logEglError("eglMakeCurrent"); 6029630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return false; 6039630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6049630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return true; 6059630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6069630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6079630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private void detachEglContext() { 6089630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (mEglDisplay != null) { 6099630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.eglMakeCurrent(mEglDisplay, 6109630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT); 6119630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6129630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6139630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6149630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown /** 6159630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * Interpolates a value in the range 0 .. 1 along a sigmoid curve 6169630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * yielding a result in the range 0 .. 1 scaled such that: 6179630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown * scurve(0) == 0, scurve(0.5) == 0.5, scurve(1) == 1. 6189630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown */ 6199630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static float scurve(float value, float s) { 6209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // A basic sigmoid has the form y = 1.0f / FloatMap.exp(-x * s). 6219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Here we take the input datum and shift it by 0.5 so that the 6229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // domain spans the range -0.5 .. 0.5 instead of 0 .. 1. 6239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float x = value - 0.5f; 6249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // Next apply the sigmoid function to the scaled value 6269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // which produces a value in the range 0 .. 1 so we subtract 6279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // 0.5 to get a value in the range -0.5 .. 0.5 instead. 6289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float y = sigmoid(x, s) - 0.5f; 6299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // To obtain the desired boundary conditions we need to scale 6319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // the result so that it fills a range of -1 .. 1. 6329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown final float v = sigmoid(0.5f, s) - 0.5f; 6339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6349630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown // And finally remap the value back to a range of 0 .. 1. 6359630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return y / v * 0.5f + 0.5f; 6369630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6379630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6389630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static float sigmoid(float x, float s) { 6399630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return 1.0f / (1.0f + FloatMath.exp(-x * s)); 6409630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6419630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6429630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static FloatBuffer createNativeFloatBuffer(int size) { 6439630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown ByteBuffer bb = ByteBuffer.allocateDirect(size * 4); 6449630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown bb.order(ByteOrder.nativeOrder()); 6459630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return bb.asFloatBuffer(); 6469630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6479630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6489630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static void logEglError(String func) { 6499630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.e(TAG, func + " failed: error " + EGL14.eglGetError(), new Throwable()); 6509630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6519630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6529630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static boolean checkGlErrors(String func) { 6539630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return checkGlErrors(func, true); 6549630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6559630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6569630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown private static boolean checkGlErrors(String func, boolean log) { 6579630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown boolean hadError = false; 6589630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown int error; 6599630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown while ((error = GLES10.glGetError()) != GLES10.GL_NO_ERROR) { 6609630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown if (log) { 6619630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown Slog.e(TAG, func + " failed: error " + error, new Throwable()); 6629630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6639630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown hadError = true; 6649630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6659630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown return hadError; 6669630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6679630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown 6689630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown public void dump(PrintWriter pw) { 6699630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(); 6709630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println("Electron Beam State:"); 6719630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mPrepared=" + mPrepared); 6728b9cf1c8000eb581457713a5c0ce41c59f90c353Jeff Brown pw.println(" mMode=" + mMode); 6739630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mDisplayLayerStack=" + mDisplayLayerStack); 6749630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mDisplayWidth=" + mDisplayWidth); 6759630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mDisplayHeight=" + mDisplayHeight); 6769630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown pw.println(" mSurfaceVisible=" + mSurfaceVisible); 677252c206984299d7ce91c27536cafe1bb2fb9628dJeff Brown pw.println(" mSurfaceAlpha=" + mSurfaceAlpha); 6789630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown } 6797f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown 6807f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown /** 6817f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown * Keeps a surface aligned with the natural orientation of the device. 6827f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown * Updates the position and transformation of the matrix whenever the display 6837f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown * is rotated. This is a little tricky because the display transaction 6847f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown * callback can be invoked on any thread, not necessarily the thread that 6857f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown * owns the electron beam. 6867f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown */ 6877f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown private static final class NaturalSurfaceLayout implements DisplayTransactionListener { 6887f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown private final DisplayManagerService mDisplayManager; 68929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian private SurfaceControl mSurfaceControl; 6907f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown 69129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian public NaturalSurfaceLayout(DisplayManagerService displayManager, SurfaceControl surfaceControl) { 6927f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayManager = displayManager; 69329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl = surfaceControl; 6947f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayManager.registerDisplayTransactionListener(this); 6957f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 6967f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown 6977f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown public void dispose() { 6987f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown synchronized (this) { 69929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl = null; 7007f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7017f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown mDisplayManager.unregisterDisplayTransactionListener(this); 7027f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7037f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown 7047f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown @Override 7057f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown public void onDisplayTransaction() { 7067f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown synchronized (this) { 70729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian if (mSurfaceControl == null) { 7087f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown return; 7097f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7107f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown 7117f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); 7127f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown switch (displayInfo.rotation) { 7137f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown case Surface.ROTATION_0: 71429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setPosition(0, 0); 71529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setMatrix(1, 0, 0, 1); 7167f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown break; 7177f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown case Surface.ROTATION_90: 71829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setPosition(0, displayInfo.logicalHeight); 71929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setMatrix(0, -1, 1, 0); 7207f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown break; 7217f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown case Surface.ROTATION_180: 72229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight); 72329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setMatrix(-1, 0, 0, -1); 7247f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown break; 7257f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown case Surface.ROTATION_270: 72629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setPosition(displayInfo.logicalWidth, 0); 72729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian mSurfaceControl.setMatrix(0, 1, -1, 0); 7287f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown break; 7297f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7307f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7317f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7327f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown } 7339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown} 734