14c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn/* 24c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Copyright (C) 2009 The Android Open Source Project 34c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * 44c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 54c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * you may not use this file except in compliance with the License. 64c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * You may obtain a copy of the License at 74c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * 84c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 94c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * 104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * See the License for the specific language governing permissions and 144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * limitations under the License. 154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn */ 164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 17ba39839444532af0ed3766f736582413f6d7a40bDianne Hackbornpackage com.android.systemui; 184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 19de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport static android.opengl.GLES20.*; 20de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport static javax.microedition.khronos.egl.EGL10.*; 21de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlock 22407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.app.ActivityManager; 234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.app.WallpaperManager; 24407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.content.BroadcastReceiver; 25c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseimport android.content.ComponentCallbacks2; 26407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.content.Context; 27407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.content.Intent; 28407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.graphics.Bitmap; 294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.graphics.Canvas; 30759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackbornimport android.graphics.Rect; 31e2d034c9014919a45ddd717d4e564e73771b2fefMathias Agopianimport android.graphics.Region.Op; 32407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.opengl.GLUtils; 33043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guyimport android.os.SystemProperties; 34407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.renderscript.Matrix4f; 354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.WallpaperService; 36c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackbornimport android.util.Log; 378df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackbornimport android.view.MotionEvent; 384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.SurfaceHolder; 392f20081f9fd734e466147bf1091d06cc7331458cChet Haaseimport android.view.WindowManager; 40407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 41407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.io.IOException; 42407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.nio.ByteBuffer; 43407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.nio.ByteOrder; 44407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.nio.FloatBuffer; 45407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 46de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport javax.microedition.khronos.egl.EGL10; 47de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport javax.microedition.khronos.egl.EGLConfig; 48de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport javax.microedition.khronos.egl.EGLContext; 49de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport javax.microedition.khronos.egl.EGLDisplay; 50de84f0e77ea2bf713d15c290264059a413c2486aJohn Spurlockimport javax.microedition.khronos.egl.EGLSurface; 514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn/** 534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Default built-in wallpaper that simply shows a static image. 544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn */ 55407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy@SuppressWarnings({"UnusedDeclaration"}) 564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornpublic class ImageWallpaper extends WallpaperService { 57fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown private static final String TAG = "ImageWallpaper"; 58407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final String GL_LOG_TAG = "ImageWallpaperGL"; 59fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown private static final boolean DEBUG = false; 60043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu"; 61fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 62ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn static final boolean FIXED_SIZED_SURFACE = true; 63881fb2092b41f4447e708da2f341d2ca5602c0d4Erik Gilling static final boolean USE_OPENGL = true; 64ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn 65ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy WallpaperManager mWallpaperManager; 66407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 67c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase DrawableEngine mEngine; 68c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase 69407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy boolean mIsHwAccelerated; 70ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 71ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy @Override 72ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy public void onCreate() { 73ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy super.onCreate(); 74ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); 75407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 76407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy //noinspection PointlessBooleanExpression,ConstantConditions 77407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (FIXED_SIZED_SURFACE && USE_OPENGL) { 78043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy if (!isEmulator()) { 7998365d7663cbd82979a5700faf0050220b01084dJeff Brown mIsHwAccelerated = ActivityManager.isHighEndGfx(); 80043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy } 81407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 82ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 83ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 84c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase @Override 85c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase public void onTrimMemory(int level) { 86c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase if (mEngine != null) { 87c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mEngine.trimMemory(level); 88c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 89c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 90c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase 91043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy private static boolean isEmulator() { 92043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy return "1".equals(SystemProperties.get(PROPERTY_KERNEL_QEMU, "0")); 93043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy } 94043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy 95b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner @Override 96ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy public Engine onCreateEngine() { 97c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mEngine = new DrawableEngine(); 98c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase return mEngine; 99ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 100ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 101ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy class DrawableEngine extends Engine { 102407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 103407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy static final int EGL_OPENGL_ES2_BIT = 4; 104407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 105407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // TODO: Not currently used, keeping around until we know we don't need it 106407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy @SuppressWarnings({"UnusedDeclaration"}) 107284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn private WallpaperObserver mReceiver; 108407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 109407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Bitmap mBackground; 1105f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; 1112f20081f9fd734e466147bf1091d06cc7331458cChet Haase int mLastRotation = -1; 1127341d7a104b47996445d069a695e155a07184606Dianne Hackborn float mXOffset; 1137341d7a104b47996445d069a695e155a07184606Dianne Hackborn float mYOffset; 114759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn 115fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown boolean mVisible = true; 116fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown boolean mRedrawNeeded; 117fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown boolean mOffsetsChanged; 118fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown int mLastXTranslation; 119fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown int mLastYTranslation; 120fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 121407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGL10 mEgl; 122407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLDisplay mEglDisplay; 123407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLConfig mEglConfig; 124407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLContext mEglContext; 125407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLSurface mEglSurface; 126407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 127407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final String sSimpleVS = 128407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "attribute vec4 position;\n" + 129407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "attribute vec2 texCoords;\n" + 130407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "varying vec2 outTexCoords;\n" + 131407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "uniform mat4 projection;\n" + 132407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "\nvoid main(void) {\n" + 133407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy " outTexCoords = texCoords;\n" + 134407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy " gl_Position = projection * position;\n" + 135407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "}\n\n"; 136407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final String sSimpleFS = 137407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "precision mediump float;\n\n" + 138407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "varying vec2 outTexCoords;\n" + 139407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "uniform sampler2D texture;\n" + 140407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "\nvoid main(void) {\n" + 141407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy " gl_FragColor = texture2D(texture, outTexCoords);\n" + 142407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "}\n\n"; 143209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 144407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int FLOAT_SIZE_BYTES = 4; 145407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 146407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 147407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 148407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 149284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn class WallpaperObserver extends BroadcastReceiver { 150b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner @Override 151284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn public void onReceive(Context context, Intent intent) { 15230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 15330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onReceive"); 15430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 15530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 156b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mLastSurfaceWidth = mLastSurfaceHeight = -1; 157b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mBackground = null; 158b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mRedrawNeeded = true; 159b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner drawFrame(); 160284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn } 161284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn } 162284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn 16335be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey public DrawableEngine() { 16435be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey super(); 16535be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey setFixedSizeAllowed(true); 16635be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey } 16735be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey 168c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase public void trimMemory(int level) { 169c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW && 170c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground != null && mIsHwAccelerated) { 1715f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (DEBUG) { 1725f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "trimMemory"); 1735f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 174c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground.recycle(); 175c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground = null; 176c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mWallpaperManager.forgetLoadedWallpaper(); 177c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 178c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 179c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase 1804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn @Override 181759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn public void onCreate(SurfaceHolder surfaceHolder) { 18230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 18330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onCreate"); 18430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 18530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 186759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn super.onCreate(surfaceHolder); 187209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 188407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // TODO: Don't need this currently because the wallpaper service 1899ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn // will restart the image wallpaper whenever the image changes. 1909ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn //IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED); 1919ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn //mReceiver = new WallpaperObserver(); 1929ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn //registerReceiver(mReceiver, filter, null, mHandler); 193fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 194ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn updateSurfaceSize(surfaceHolder); 195a8e5a2bcd6a0d35893187c6df42425c03be005daChet Haase 196a8e5a2bcd6a0d35893187c6df42425c03be005daChet Haase setOffsetNotificationsEnabled(false); 1974c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1984c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 1994c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn @Override 200284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn public void onDestroy() { 201284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn super.onDestroy(); 2029ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn if (mReceiver != null) { 2039ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn unregisterReceiver(mReceiver); 2049ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn } 205284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn } 206284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn 207284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn @Override 208ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { 209912d9d13698693709991b76f83a8d64179e97e83Dianne Hackborn super.onDesiredSizeChanged(desiredWidth, desiredHeight); 210ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn SurfaceHolder surfaceHolder = getSurfaceHolder(); 211ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn if (surfaceHolder != null) { 212ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn updateSurfaceSize(surfaceHolder); 213ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn } 214ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn } 215ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn 216ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn void updateSurfaceSize(SurfaceHolder surfaceHolder) { 217ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn if (FIXED_SIZED_SURFACE) { 218ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn // Used a fixed size surface, because we are special. We can do 219ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn // this because we know the current design of window animations doesn't 220ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn // cause this to break. 221ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn surfaceHolder.setFixedSize(getDesiredMinimumWidth(), getDesiredMinimumHeight()); 222ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn } else { 223ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn surfaceHolder.setSizeFromLayout(); 224ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn } 225ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn } 226ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn 227ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn @Override 228759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn public void onVisibilityChanged(boolean visible) { 22930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 2302f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible); 23130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 23230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 233b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner if (mVisible != visible) { 234b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner if (DEBUG) { 235b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner Log.d(TAG, "Visibility changed to visible=" + visible); 23630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 237b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mVisible = visible; 238b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner drawFrame(); 239fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 240759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn } 241fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 242759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn @Override 2438df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn public void onTouchEvent(MotionEvent event) { 2448df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn super.onTouchEvent(event); 2458df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn } 2468df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn 2478df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn @Override 24872c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn public void onOffsetsChanged(float xOffset, float yOffset, 249bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen float xOffsetStep, float yOffsetStep, 25072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn int xPixels, int yPixels) { 25130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 25230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset 25330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown + ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep 25430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown + ", xPixels=" + xPixels + ", yPixels=" + yPixels); 25530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 25630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 257b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner if (mXOffset != xOffset || mYOffset != yOffset) { 258b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner if (DEBUG) { 259b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ")."); 260fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 261b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mXOffset = xOffset; 262b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mYOffset = yOffset; 263b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner mOffsetsChanged = true; 264fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 265b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner drawFrame(); 26672c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn } 26772c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn 26872c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn @Override 2694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { 27030bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 27130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height); 272fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 2734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 27430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown super.onSurfaceChanged(holder, format, width, height); 2754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 276b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner drawFrame(); 2774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 278fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 279fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner @Override 2802f20081f9fd734e466147bf1091d06cc7331458cChet Haase public void onSurfaceDestroyed(SurfaceHolder holder) { 2812f20081f9fd734e466147bf1091d06cc7331458cChet Haase super.onSurfaceDestroyed(holder); 2825f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = mLastSurfaceHeight = -1; 2832f20081f9fd734e466147bf1091d06cc7331458cChet Haase } 2842f20081f9fd734e466147bf1091d06cc7331458cChet Haase 2852f20081f9fd734e466147bf1091d06cc7331458cChet Haase @Override 2862f20081f9fd734e466147bf1091d06cc7331458cChet Haase public void onSurfaceCreated(SurfaceHolder holder) { 2872f20081f9fd734e466147bf1091d06cc7331458cChet Haase super.onSurfaceCreated(holder); 2885f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = mLastSurfaceHeight = -1; 2892f20081f9fd734e466147bf1091d06cc7331458cChet Haase } 2902f20081f9fd734e466147bf1091d06cc7331458cChet Haase 2912f20081f9fd734e466147bf1091d06cc7331458cChet Haase @Override 292fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner public void onSurfaceRedrawNeeded(SurfaceHolder holder) { 293fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner if (DEBUG) { 2942f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "onSurfaceRedrawNeeded"); 295fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner } 296fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner super.onSurfaceRedrawNeeded(holder); 297fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner 298b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner drawFrame(); 299fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner } 300fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner 301b1ef36965bf17e791afd16a9a34bcbb32f495f68Craig Mautner void drawFrame() { 3022f20081f9fd734e466147bf1091d06cc7331458cChet Haase SurfaceHolder sh = getSurfaceHolder(); 3032f20081f9fd734e466147bf1091d06cc7331458cChet Haase final Rect frame = sh.getSurfaceFrame(); 3042f20081f9fd734e466147bf1091d06cc7331458cChet Haase final int dw = frame.width(); 3052f20081f9fd734e466147bf1091d06cc7331458cChet Haase final int dh = frame.height(); 3062f20081f9fd734e466147bf1091d06cc7331458cChet Haase int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)). 3072f20081f9fd734e466147bf1091d06cc7331458cChet Haase getDefaultDisplay().getRotation(); 3085f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth || dh != mLastSurfaceHeight; 3092f20081f9fd734e466147bf1091d06cc7331458cChet Haase 3105f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation; 3112f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (!redrawNeeded && !mOffsetsChanged) { 3122f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (DEBUG) { 3132f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "Suppressed drawFrame since redraw is not needed " 3142f20081f9fd734e466147bf1091d06cc7331458cChet Haase + "and offsets have not changed."); 315fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 3162f20081f9fd734e466147bf1091d06cc7331458cChet Haase return; 317fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 3182f20081f9fd734e466147bf1091d06cc7331458cChet Haase mLastRotation = newRotation; 319321357b6066a34cc12a0528b7b835c7664db2e08Michael Jurka 3202f20081f9fd734e466147bf1091d06cc7331458cChet Haase // Load bitmap if it is not yet loaded or if it was loaded at a different size 3215f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (mBackground == null || surfaceDimensionsChanged) { 3222f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (DEBUG) { 3235f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " + 3245f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mBackground + ", " + 3255f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase ((mBackground == null) ? 0 : mBackground.getWidth()) + ", " + 3265f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase ((mBackground == null) ? 0 : mBackground.getHeight()) + ", " + 3275f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase dw + ", " + dh); 3282f20081f9fd734e466147bf1091d06cc7331458cChet Haase } 329b9fca9997100f209e98f0559c54c875b9e661e9fMichael Wright mWallpaperManager.forgetLoadedWallpaper(); 330ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn updateWallpaperLocked(); 3315f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (mBackground == null) { 3325f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (DEBUG) { 3335f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "Unable to load bitmap"); 3345f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3355f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase return; 3365f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3375f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (DEBUG) { 3385f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) { 3395f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " + 3405f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase dw + ", " + dh + ", " + mBackground.getWidth() + ", " + 3415f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mBackground.getHeight()); 3425f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3435f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 344ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn } 345ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn 3465f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final int availw = dw - mBackground.getWidth(); 3475f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final int availh = dh - mBackground.getHeight(); 348033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2); 349033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2); 350033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown 351033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown mOffsetsChanged = false; 3522f20081f9fd734e466147bf1091d06cc7331458cChet Haase mRedrawNeeded = false; 3535f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (surfaceDimensionsChanged) { 3545f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = dw; 3555f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceHeight = dh; 3565f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3572f20081f9fd734e466147bf1091d06cc7331458cChet Haase mLastXTranslation = xPixels; 3582f20081f9fd734e466147bf1091d06cc7331458cChet Haase mLastYTranslation = yPixels; 3592f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { 360033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown if (DEBUG) { 361033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown Log.d(TAG, "Suppressed drawFrame since the image has not " 362033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown + "actually moved an integral number of pixels."); 363033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown } 364033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown return; 365033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown } 366033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown 367c92f150af0fb93b677a4ec6e2aca1b9a9bdd8760Craig Mautner if (DEBUG) { 3682f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "Redrawing wallpaper"); 369c92f150af0fb93b677a4ec6e2aca1b9a9bdd8760Craig Mautner } 3709549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden 371407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mIsHwAccelerated) { 372f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { 373f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); 374f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy } 375407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } else { 376407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); 377c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase if (FIXED_SIZED_SURFACE) { 378c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // If the surface is fixed-size, we should only need to 379c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // draw it once and then we'll let the window manager 380c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // position it appropriately. As such, we no longer needed 381c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // the loaded bitmap. Yay! 382c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // hw-accelerated path retains bitmap for faster rotation 383c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground = null; 384c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mWallpaperManager.forgetLoadedWallpaper(); 385c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 386759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn } 387ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn 388759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn } 389ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 3905f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase private void updateWallpaperLocked() { 391fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Throwable exception = null; 392fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown try { 393589a6af173c10738d2a83c69a9dda36579cc739dChet Haase mBackground = null; 394407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mBackground = mWallpaperManager.getBitmap(); 395fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } catch (RuntimeException e) { 396fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown exception = e; 397fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } catch (OutOfMemoryError e) { 398fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown exception = e; 399fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 400407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 401fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown if (exception != null) { 402fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown mBackground = null; 403fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // Note that if we do fail at this, and the default wallpaper can't 404fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // be loaded, we will go into a cycle. Don't do a build where the 405fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // default wallpaper can't be loaded. 406fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Log.w(TAG, "Unable to load wallpaper!", exception); 407c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn try { 408fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown mWallpaperManager.clear(); 409fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } catch (IOException ex) { 410fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // now we're really screwed. 411fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Log.w(TAG, "Unable reset to default wallpaper!", ex); 412c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn } 413ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 414407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 415407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 416407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int x, int y) { 417407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Canvas c = sh.lockCanvas(); 418407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (c != null) { 419407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy try { 420407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (DEBUG) { 421407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.d(TAG, "Redrawing: x=" + x + ", y=" + y); 422407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 423407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 424407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.translate(x, y); 425407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (w < 0 || h < 0) { 426407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.save(Canvas.CLIP_SAVE_FLAG); 4275f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase c.clipRect(0, 0, mBackground.getWidth(), mBackground.getHeight(), 4285f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Op.DIFFERENCE); 429407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.drawColor(0xff000000); 430407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.restore(); 431407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 432407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mBackground != null) { 433407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.drawBitmap(mBackground, 0, 0, null); 434407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 435407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } finally { 436407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy sh.unlockCanvasAndPost(c); 437407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 438407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 439407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 440407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 441f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) { 442f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy if (!initGL(sh)) return false; 443407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 4445f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final float right = left + mBackground.getWidth(); 4455f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final float bottom = top + mBackground.getHeight(); 446407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 447407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final Rect frame = sh.getSurfaceFrame(); 448407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final Matrix4f ortho = new Matrix4f(); 449407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f); 450407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 451407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final FloatBuffer triangleVertices = createMesh(left, top, right, bottom); 452407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 453407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int texture = loadTexture(mBackground); 454407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int program = buildProgram(sSimpleVS, sSimpleFS); 4552f20081f9fd734e466147bf1091d06cc7331458cChet Haase 456407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int attribPosition = glGetAttribLocation(program, "position"); 457407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int attribTexCoords = glGetAttribLocation(program, "texCoords"); 458407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int uniformTexture = glGetUniformLocation(program, "texture"); 459407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int uniformProjection = glGetUniformLocation(program, "projection"); 460407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 461407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 462407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 463407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glViewport(0, 0, frame.width(), frame.height()); 464407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glBindTexture(GL_TEXTURE_2D, texture); 465407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 466407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glUseProgram(program); 467407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glEnableVertexAttribArray(attribPosition); 468407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glEnableVertexAttribArray(attribTexCoords); 469407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glUniform1i(uniformTexture, 0); 470407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0); 471407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 472407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 473407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 474407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (w < 0 || h < 0) { 475407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 476407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glClear(GL_COLOR_BUFFER_BIT); 477407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 4782f20081f9fd734e466147bf1091d06cc7331458cChet Haase 479407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // drawQuad 480407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 481407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, 482407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 483407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 484407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 485407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, 486407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 487407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 488407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 4892f20081f9fd734e466147bf1091d06cc7331458cChet Haase 490c8d983f7259b4e328abc10c27c3c2cec61ad0722Romain Guy boolean status = mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); 491407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkEglError(); 4922f20081f9fd734e466147bf1091d06cc7331458cChet Haase 493407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy finishGL(); 494f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy 495c8d983f7259b4e328abc10c27c3c2cec61ad0722Romain Guy return status; 496407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 497407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 498407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private FloatBuffer createMesh(int left, int top, float right, float bottom) { 499407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final float[] verticesData = { 500407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // X, Y, Z, U, V 501407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy left, bottom, 0.0f, 0.0f, 1.0f, 502407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy right, bottom, 0.0f, 1.0f, 1.0f, 503407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy left, top, 0.0f, 0.0f, 0.0f, 504407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy right, top, 0.0f, 1.0f, 0.0f, 505407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy }; 506407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 507407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int bytes = verticesData.length * FLOAT_SIZE_BYTES; 508407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order( 509407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy ByteOrder.nativeOrder()).asFloatBuffer(); 510407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy triangleVertices.put(verticesData).position(0); 511407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return triangleVertices; 512407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 513407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 514407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int loadTexture(Bitmap bitmap) { 515407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] textures = new int[1]; 516209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 517407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glActiveTexture(GL_TEXTURE0); 518407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glGenTextures(1, textures, 0); 519407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 520209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 521407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int texture = textures[0]; 522407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glBindTexture(GL_TEXTURE_2D, texture); 523407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 524209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 525407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 526407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 527209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 528407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 529407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 530209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 531407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0); 532407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 533407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 534407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return texture; 535407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 536209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 537407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int buildProgram(String vertex, String fragment) { 538407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 539407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (vertexShader == 0) return 0; 540209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 541407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 542407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (fragmentShader == 0) return 0; 543209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 544407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int program = glCreateProgram(); 545407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glAttachShader(program, vertexShader); 546407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 547209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 548407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glAttachShader(program, fragmentShader); 549407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 550209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 551407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glLinkProgram(program); 552407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 553209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 554407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] status = new int[1]; 555407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glGetProgramiv(program, GL_LINK_STATUS, status, 0); 556407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (status[0] != GL_TRUE) { 557407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy String error = glGetProgramInfoLog(program); 558407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.d(GL_LOG_TAG, "Error while linking program:\n" + error); 559407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteShader(vertexShader); 560407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteShader(fragmentShader); 561407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteProgram(program); 562407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return 0; 563407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 564209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 565407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return program; 566407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 5673696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy 568407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int buildShader(String source, int type) { 569407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int shader = glCreateShader(type); 570209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 571407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glShaderSource(shader, source); 572407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 573209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 574407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glCompileShader(shader); 575407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 576209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 577407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] status = new int[1]; 578407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0); 579407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (status[0] != GL_TRUE) { 580407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy String error = glGetShaderInfoLog(shader); 581407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error); 582407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteShader(shader); 583407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return 0; 584407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 585209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 586407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return shader; 587407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 5883696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy 589407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void checkEglError() { 590407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int error = mEgl.eglGetError(); 591407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (error != EGL_SUCCESS) { 592407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error)); 593407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 594407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 5953696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy 596407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void checkGlError() { 597407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int error = glGetError(); 598407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (error != GL_NO_ERROR) { 599407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable()); 600407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 601407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 6023696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy 603407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void finishGL() { 604f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 605407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 606f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy mEgl.eglDestroyContext(mEglDisplay, mEglContext); 6073696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy mEgl.eglTerminate(mEglDisplay); 608407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 6093696779bca4e5bc1b60c056db6f892e72e51a20fRomain Guy 610f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy private boolean initGL(SurfaceHolder surfaceHolder) { 611407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEgl = (EGL10) EGLContext.getEGL(); 612209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 613407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglDisplay = mEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY); 614407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mEglDisplay == EGL_NO_DISPLAY) { 615407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglGetDisplay failed " + 616407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 617407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 618209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 619407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] version = new int[2]; 620407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglInitialize(mEglDisplay, version)) { 621407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglInitialize failed " + 622407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 623407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 624209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 625407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglConfig = chooseEglConfig(); 626407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mEglConfig == null) { 627407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglConfig not initialized"); 628407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 629209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 630407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); 631187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase if (mEglContext == EGL_NO_CONTEXT) { 632187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase throw new RuntimeException("createContext failed " + 633187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase GLUtils.getEGLErrorString(mEgl.eglGetError())); 6349549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden } 635187e1e2fc7dfb4eabdcb2c8990774bc6020fb16bChet Haase 6362e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase int attribs[] = { 6372e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase EGL_WIDTH, 1, 6382e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase EGL_HEIGHT, 1, 6392e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase EGL_NONE 6402e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase }; 6412e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase EGLSurface tmpSurface = mEgl.eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); 6422e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase mEgl.eglMakeCurrent(mEglDisplay, tmpSurface, tmpSurface, mEglContext); 6432e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase 6442e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase int[] maxSize = new int[1]; 6452e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase Rect frame = surfaceHolder.getSurfaceFrame(); 6462e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxSize, 0); 6472e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase 6482e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 6492e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase mEgl.eglDestroySurface(mEglDisplay, tmpSurface); 6502e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase 6512e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase if(frame.width() > maxSize[0] || frame.height() > maxSize[0]) { 6522e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase mEgl.eglDestroyContext(mEglDisplay, mEglContext); 6532e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase mEgl.eglTerminate(mEglDisplay); 6542e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase Log.e(GL_LOG_TAG, "requested texture size " + 6552e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase frame.width() + "x" + frame.height() + " exceeds the support maximum of " + 6562e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase maxSize[0] + "x" + maxSize[0]); 6572e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase return false; 6582e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase } 6592e417be5c4d45ae041c0046570d117d7b0d71940Chet Haase 660407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null); 661407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) { 662407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int error = mEgl.eglGetError(); 6639549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden if (error == EGL_BAD_NATIVE_WINDOW || error == EGL_BAD_ALLOC) { 6649549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden Log.e(GL_LOG_TAG, "createWindowSurface returned " + 6659549c067d93bd87aa28d1d6d44fdb8d75b2fd276Wim Vander Schelden GLUtils.getEGLErrorString(error) + "."); 666f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy return false; 667407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 668407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("createWindowSurface failed " + 669407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(error)); 670407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 671209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 672407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 673407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglMakeCurrent failed " + 674407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 675407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 676f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy 677f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy return true; 678407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 679209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 680209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 681407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { 682407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 683209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list); 684407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 685209bede6b9edb9171e5bee4077b48e35004a37b4John Spurlock 686407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLConfig chooseEglConfig() { 687407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] configsCount = new int[1]; 688407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGLConfig[] configs = new EGLConfig[1]; 689407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] configSpec = getConfig(); 690407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { 691407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new IllegalArgumentException("eglChooseConfig failed " + 692407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 693407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } else if (configsCount[0] > 0) { 694407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return configs[0]; 695407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 696407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return null; 697407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 698407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 699407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int[] getConfig() { 700407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return new int[] { 701407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 702407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_RED_SIZE, 8, 703407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_GREEN_SIZE, 8, 704407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_BLUE_SIZE, 8, 705407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_ALPHA_SIZE, 0, 706407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_DEPTH_SIZE, 0, 707407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_STENCIL_SIZE, 0, 7088efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy EGL_CONFIG_CAVEAT, EGL_NONE, 709407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_NONE 710407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy }; 711ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 7124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 7134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn} 714