Loading core/java/android/view/SurfaceControl.java +69 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import dalvik.system.CloseGuard; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.Region; import android.view.Surface; import android.os.IBinder; import android.os.SystemProperties; import android.util.Log; Loading @@ -39,6 +40,8 @@ public class SurfaceControl { private static native Bitmap nativeScreenshot(IBinder displayToken, int width, int height, int minLayer, int maxLayer, boolean allLayers); private static native void nativeScreenshot(IBinder displayToken, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean allLayers); private static native void nativeOpenTransaction(); private static native void nativeCloseTransaction(); Loading Loading @@ -525,9 +528,59 @@ public class SurfaceControl { } /** * Copy the current screen contents into the provided {@link Surface} * * @param display The display to take the screenshot of. * @param consumer The {@link Surface} to take the screenshot into. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw * screen will be scaled down to this size. * @param minLayer The lowest (bottom-most Z order) surface layer to * include in the screenshot. * @param maxLayer The highest (top-most Z order) surface layer to * include in the screenshot. */ public static void screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer) { screenshot(display, consumer, width, height, minLayer, maxLayer, false); } /** * Copy the current screen contents into the provided {@link Surface} * * @param display The display to take the screenshot of. * @param consumer The {@link Surface} to take the screenshot into. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw * screen will be scaled down to this size. */ public static void screenshot(IBinder display, Surface consumer, int width, int height) { screenshot(display, consumer, width, height, 0, 0, true); } /** * Copy the current screen contents into the provided {@link Surface} * * @param display The display to take the screenshot of. * @param consumer The {@link Surface} to take the screenshot into. */ public static void screenshot(IBinder display, Surface consumer) { screenshot(display, consumer, 0, 0, 0, 0, true); } /** * Copy the current screen contents into a bitmap and return it. * * CAVEAT: Versions of screenshot that return a {@link Bitmap} can * be extremely slow; avoid use unless absolutely necessary; prefer * the versions that use a {@link Surface} instead, such as * {@link SurfaceControl#screenshot(IBinder, Surface)}. * * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw Loading @@ -538,25 +591,36 @@ public class SurfaceControl { * include in the screenshot. * @return Returns a Bitmap containing the screen contents, or null * if an error occurs. * */ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false); } /** * Like {@link SurfaceControl#screenshot(int, int, int, int)} but includes all * Surfaces in the screenshot. * */ public static Bitmap screenshot(int width, int height) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, 0, 0, true); } private static void screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean allLayers) { if (display == null) { throw new IllegalArgumentException("displayToken must not be null"); } if (consumer == null) { throw new IllegalArgumentException("consumer must not be null"); } nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers); } private static void checkHeadless() { if (HEADLESS) { throw new UnsupportedOperationException("Device is headless"); Loading core/jni/android_view_SurfaceControl.cpp +22 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "android/graphics/Region.h" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_view_SurfaceSession.h> #include <gui/Surface.h> Loading Loading @@ -161,7 +162,7 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { } } static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { Loading Loading @@ -199,6 +200,24 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenO return GraphicsJNI::createBitmap(env, bitmap, false, NULL); } static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken != NULL) { sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); if (consumer != NULL) { if (allLayers) { minLayer = 0; maxLayer = -1; } ScreenshotClient::capture( displayToken, consumer->getIGraphicBufferProducer(), width, height, uint32_t(minLayer), uint32_t(maxLayer)); } } } static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { SurfaceComposerClient::openGlobalTransaction(); } Loading Loading @@ -393,6 +412,8 @@ static JNINativeMethod sSurfaceControlMethods[] = { {"nativeDestroy", "(I)V", (void*)nativeDestroy }, {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZ)V", (void*)nativeScreenshot }, {"nativeOpenTransaction", "()V", (void*)nativeOpenTransaction }, Loading services/java/com/android/server/power/ElectronBeam.java +54 −87 Original line number Diff line number Diff line Loading @@ -16,18 +16,20 @@ package com.android.server.power; import com.android.server.display.DisplayManagerService; import com.android.server.display.DisplayTransactionListener; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.graphics.SurfaceTexture; import android.opengl.EGL14; import android.opengl.EGLConfig; import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLSurface; import android.opengl.GLES10; import android.opengl.GLUtils; import android.opengl.GLES11Ext; import android.os.Looper; import android.util.FloatMath; import android.util.Slog; Loading @@ -37,10 +39,8 @@ import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import com.android.server.display.DisplayManagerService; import com.android.server.display.DisplayTransactionListener; /** * Bzzzoooop! *crackle* Loading Loading @@ -94,6 +94,7 @@ final class ElectronBeam { // Texture names. We only use one texture, which contains the screenshot. private final int[] mTexNames = new int[1]; private boolean mTexNamesGenerated; private float mTexMatrix[] = new float[16]; // Vertex and corresponding texture coordinates. // We have 4 2D vertices, so 8 elements. The vertices form a quad. Loading @@ -115,6 +116,7 @@ final class ElectronBeam { */ public static final int MODE_FADE = 2; public ElectronBeam(DisplayManagerService displayManager) { mDisplayManager = displayManager; } Loading Loading @@ -264,19 +266,23 @@ final class ElectronBeam { GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer); GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY); // set-up texturing GLES10.glDisable(GLES10.GL_TEXTURE_2D); GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); // bind texture and set blending for drawing planes GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]); GLES10.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]); GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE, mMode == MODE_WARM_UP ? GLES10.GL_MODULATE : GLES10.GL_REPLACE); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE); GLES10.glEnable(GLES10.GL_TEXTURE_2D); GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer); GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); Loading @@ -296,7 +302,7 @@ final class ElectronBeam { GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); // clean up after drawing planes GLES10.glDisable(GLES10.GL_TEXTURE_2D); GLES10.glDisable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); GLES10.glColorMask(true, true, true, true); Loading Loading @@ -371,14 +377,6 @@ final class ElectronBeam { } private boolean captureScreenshotTextureAndSetViewport() { // TODO: Use a SurfaceTexture to avoid the extra texture upload. Bitmap bitmap = SurfaceControl.screenshot(mDisplayWidth, mDisplayHeight, 0, ELECTRON_BEAM_LAYER - 1); if (bitmap == null) { Slog.e(TAG, "Could not take a screenshot!"); return false; } try { if (!attachEglContext()) { return false; } Loading @@ -391,46 +389,21 @@ final class ElectronBeam { mTexNamesGenerated = true; } GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]); if (checkGlErrors("glBindTexture")) { return false; } float u = 1.0f; float v = 1.0f; GLUtils.texImage2D(GLES10.GL_TEXTURE_2D, 0, bitmap, 0); if (checkGlErrors("glTexImage2D, first try", false)) { // Try a power of two size texture instead. int tw = nextPowerOfTwo(mDisplayWidth); int th = nextPowerOfTwo(mDisplayHeight); int format = GLUtils.getInternalFormat(bitmap); GLES10.glTexImage2D(GLES10.GL_TEXTURE_2D, 0, format, tw, th, 0, format, GLES10.GL_UNSIGNED_BYTE, null); if (checkGlErrors("glTexImage2D, second try")) { return false; } GLUtils.texSubImage2D(GLES10.GL_TEXTURE_2D, 0, 0, 0, bitmap); if (checkGlErrors("glTexSubImage2D")) { return false; } SurfaceTexture st = new SurfaceTexture(mTexNames[0]); SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), new Surface(st)); u = (float)mDisplayWidth / tw; v = (float)mDisplayHeight / th; } st.updateTexImage(); st.getTransformMatrix(mTexMatrix); // Set up texture coordinates for a quad. // We might need to change this if the texture ends up being // a different size from the display for some reason. mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, v); mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 0f); mTexCoordBuffer.put(4, u); mTexCoordBuffer.put(5, 0f); mTexCoordBuffer.put(6, u); mTexCoordBuffer.put(7, v); mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, 0f); mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 1f); mTexCoordBuffer.put(4, 1f); mTexCoordBuffer.put(5, 1f); mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f); // Set up our viewport. GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight); Loading @@ -441,12 +414,10 @@ final class ElectronBeam { GLES10.glLoadIdentity(); GLES10.glMatrixMode(GLES10.GL_TEXTURE); GLES10.glLoadIdentity(); GLES10.glLoadMatrixf(mTexMatrix, 0); } finally { detachEglContext(); } } finally { bitmap.recycle(); } return true; } Loading Loading @@ -662,10 +633,6 @@ final class ElectronBeam { return 1.0f / (1.0f + FloatMath.exp(-x * s)); } private static int nextPowerOfTwo(int value) { return 1 << (32 - Integer.numberOfLeadingZeros(value)); } private static FloatBuffer createNativeFloatBuffer(int size) { ByteBuffer bb = ByteBuffer.allocateDirect(size * 4); bb.order(ByteOrder.nativeOrder()); Loading Loading
core/java/android/view/SurfaceControl.java +69 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import dalvik.system.CloseGuard; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.Region; import android.view.Surface; import android.os.IBinder; import android.os.SystemProperties; import android.util.Log; Loading @@ -39,6 +40,8 @@ public class SurfaceControl { private static native Bitmap nativeScreenshot(IBinder displayToken, int width, int height, int minLayer, int maxLayer, boolean allLayers); private static native void nativeScreenshot(IBinder displayToken, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean allLayers); private static native void nativeOpenTransaction(); private static native void nativeCloseTransaction(); Loading Loading @@ -525,9 +528,59 @@ public class SurfaceControl { } /** * Copy the current screen contents into the provided {@link Surface} * * @param display The display to take the screenshot of. * @param consumer The {@link Surface} to take the screenshot into. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw * screen will be scaled down to this size. * @param minLayer The lowest (bottom-most Z order) surface layer to * include in the screenshot. * @param maxLayer The highest (top-most Z order) surface layer to * include in the screenshot. */ public static void screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer) { screenshot(display, consumer, width, height, minLayer, maxLayer, false); } /** * Copy the current screen contents into the provided {@link Surface} * * @param display The display to take the screenshot of. * @param consumer The {@link Surface} to take the screenshot into. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw * screen will be scaled down to this size. */ public static void screenshot(IBinder display, Surface consumer, int width, int height) { screenshot(display, consumer, width, height, 0, 0, true); } /** * Copy the current screen contents into the provided {@link Surface} * * @param display The display to take the screenshot of. * @param consumer The {@link Surface} to take the screenshot into. */ public static void screenshot(IBinder display, Surface consumer) { screenshot(display, consumer, 0, 0, 0, 0, true); } /** * Copy the current screen contents into a bitmap and return it. * * CAVEAT: Versions of screenshot that return a {@link Bitmap} can * be extremely slow; avoid use unless absolutely necessary; prefer * the versions that use a {@link Surface} instead, such as * {@link SurfaceControl#screenshot(IBinder, Surface)}. * * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw Loading @@ -538,25 +591,36 @@ public class SurfaceControl { * include in the screenshot. * @return Returns a Bitmap containing the screen contents, or null * if an error occurs. * */ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false); } /** * Like {@link SurfaceControl#screenshot(int, int, int, int)} but includes all * Surfaces in the screenshot. * */ public static Bitmap screenshot(int width, int height) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, 0, 0, true); } private static void screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean allLayers) { if (display == null) { throw new IllegalArgumentException("displayToken must not be null"); } if (consumer == null) { throw new IllegalArgumentException("consumer must not be null"); } nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers); } private static void checkHeadless() { if (HEADLESS) { throw new UnsupportedOperationException("Device is headless"); Loading
core/jni/android_view_SurfaceControl.cpp +22 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "android/graphics/Region.h" #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_view_SurfaceSession.h> #include <gui/Surface.h> Loading Loading @@ -161,7 +162,7 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { } } static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { Loading Loading @@ -199,6 +200,24 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenO return GraphicsJNI::createBitmap(env, bitmap, false, NULL); } static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken != NULL) { sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); if (consumer != NULL) { if (allLayers) { minLayer = 0; maxLayer = -1; } ScreenshotClient::capture( displayToken, consumer->getIGraphicBufferProducer(), width, height, uint32_t(minLayer), uint32_t(maxLayer)); } } } static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { SurfaceComposerClient::openGlobalTransaction(); } Loading Loading @@ -393,6 +412,8 @@ static JNINativeMethod sSurfaceControlMethods[] = { {"nativeDestroy", "(I)V", (void*)nativeDestroy }, {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZ)V", (void*)nativeScreenshot }, {"nativeOpenTransaction", "()V", (void*)nativeOpenTransaction }, Loading
services/java/com/android/server/power/ElectronBeam.java +54 −87 Original line number Diff line number Diff line Loading @@ -16,18 +16,20 @@ package com.android.server.power; import com.android.server.display.DisplayManagerService; import com.android.server.display.DisplayTransactionListener; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.graphics.SurfaceTexture; import android.opengl.EGL14; import android.opengl.EGLConfig; import android.opengl.EGLContext; import android.opengl.EGLDisplay; import android.opengl.EGLSurface; import android.opengl.GLES10; import android.opengl.GLUtils; import android.opengl.GLES11Ext; import android.os.Looper; import android.util.FloatMath; import android.util.Slog; Loading @@ -37,10 +39,8 @@ import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import com.android.server.display.DisplayManagerService; import com.android.server.display.DisplayTransactionListener; /** * Bzzzoooop! *crackle* Loading Loading @@ -94,6 +94,7 @@ final class ElectronBeam { // Texture names. We only use one texture, which contains the screenshot. private final int[] mTexNames = new int[1]; private boolean mTexNamesGenerated; private float mTexMatrix[] = new float[16]; // Vertex and corresponding texture coordinates. // We have 4 2D vertices, so 8 elements. The vertices form a quad. Loading @@ -115,6 +116,7 @@ final class ElectronBeam { */ public static final int MODE_FADE = 2; public ElectronBeam(DisplayManagerService displayManager) { mDisplayManager = displayManager; } Loading Loading @@ -264,19 +266,23 @@ final class ElectronBeam { GLES10.glVertexPointer(2, GLES10.GL_FLOAT, 0, mVertexBuffer); GLES10.glEnableClientState(GLES10.GL_VERTEX_ARRAY); // set-up texturing GLES10.glDisable(GLES10.GL_TEXTURE_2D); GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); // bind texture and set blending for drawing planes GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]); GLES10.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTexNames[0]); GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE, mMode == MODE_WARM_UP ? GLES10.GL_MODULATE : GLES10.GL_REPLACE); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE); GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D, GLES10.glTexParameterx(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE); GLES10.glEnable(GLES10.GL_TEXTURE_2D); GLES10.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, mTexCoordBuffer); GLES10.glEnableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); Loading @@ -296,7 +302,7 @@ final class ElectronBeam { GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4); // clean up after drawing planes GLES10.glDisable(GLES10.GL_TEXTURE_2D); GLES10.glDisable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); GLES10.glDisableClientState(GLES10.GL_TEXTURE_COORD_ARRAY); GLES10.glColorMask(true, true, true, true); Loading Loading @@ -371,14 +377,6 @@ final class ElectronBeam { } private boolean captureScreenshotTextureAndSetViewport() { // TODO: Use a SurfaceTexture to avoid the extra texture upload. Bitmap bitmap = SurfaceControl.screenshot(mDisplayWidth, mDisplayHeight, 0, ELECTRON_BEAM_LAYER - 1); if (bitmap == null) { Slog.e(TAG, "Could not take a screenshot!"); return false; } try { if (!attachEglContext()) { return false; } Loading @@ -391,46 +389,21 @@ final class ElectronBeam { mTexNamesGenerated = true; } GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]); if (checkGlErrors("glBindTexture")) { return false; } float u = 1.0f; float v = 1.0f; GLUtils.texImage2D(GLES10.GL_TEXTURE_2D, 0, bitmap, 0); if (checkGlErrors("glTexImage2D, first try", false)) { // Try a power of two size texture instead. int tw = nextPowerOfTwo(mDisplayWidth); int th = nextPowerOfTwo(mDisplayHeight); int format = GLUtils.getInternalFormat(bitmap); GLES10.glTexImage2D(GLES10.GL_TEXTURE_2D, 0, format, tw, th, 0, format, GLES10.GL_UNSIGNED_BYTE, null); if (checkGlErrors("glTexImage2D, second try")) { return false; } GLUtils.texSubImage2D(GLES10.GL_TEXTURE_2D, 0, 0, 0, bitmap); if (checkGlErrors("glTexSubImage2D")) { return false; } SurfaceTexture st = new SurfaceTexture(mTexNames[0]); SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), new Surface(st)); u = (float)mDisplayWidth / tw; v = (float)mDisplayHeight / th; } st.updateTexImage(); st.getTransformMatrix(mTexMatrix); // Set up texture coordinates for a quad. // We might need to change this if the texture ends up being // a different size from the display for some reason. mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, v); mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 0f); mTexCoordBuffer.put(4, u); mTexCoordBuffer.put(5, 0f); mTexCoordBuffer.put(6, u); mTexCoordBuffer.put(7, v); mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, 0f); mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 1f); mTexCoordBuffer.put(4, 1f); mTexCoordBuffer.put(5, 1f); mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f); // Set up our viewport. GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight); Loading @@ -441,12 +414,10 @@ final class ElectronBeam { GLES10.glLoadIdentity(); GLES10.glMatrixMode(GLES10.GL_TEXTURE); GLES10.glLoadIdentity(); GLES10.glLoadMatrixf(mTexMatrix, 0); } finally { detachEglContext(); } } finally { bitmap.recycle(); } return true; } Loading Loading @@ -662,10 +633,6 @@ final class ElectronBeam { return 1.0f / (1.0f + FloatMath.exp(-x * s)); } private static int nextPowerOfTwo(int value) { return 1 << (32 - Integer.numberOfLeadingZeros(value)); } private static FloatBuffer createNativeFloatBuffer(int size) { ByteBuffer bb = ByteBuffer.allocateDirect(size * 4); bb.order(ByteOrder.nativeOrder()); Loading