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 19407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.app.ActivityManager; 204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.app.WallpaperManager; 21407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.content.BroadcastReceiver; 22c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haaseimport android.content.ComponentCallbacks2; 23407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.content.Context; 24407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.content.Intent; 25407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.graphics.Bitmap; 264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.graphics.Canvas; 27759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackbornimport android.graphics.Rect; 28e2d034c9014919a45ddd717d4e564e73771b2fefMathias Agopianimport android.graphics.Region.Op; 29407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.opengl.GLUtils; 30043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guyimport android.os.SystemProperties; 31407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.renderscript.Matrix4f; 324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.WallpaperService; 33c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackbornimport android.util.Log; 342f20081f9fd734e466147bf1091d06cc7331458cChet Haaseimport android.view.Display; 358df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackbornimport android.view.MotionEvent; 364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.SurfaceHolder; 372f20081f9fd734e466147bf1091d06cc7331458cChet Haaseimport android.view.WindowManager; 38407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 39407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport javax.microedition.khronos.egl.EGL10; 40407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport javax.microedition.khronos.egl.EGLConfig; 41407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport javax.microedition.khronos.egl.EGLContext; 42407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport javax.microedition.khronos.egl.EGLDisplay; 43407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport javax.microedition.khronos.egl.EGLSurface; 44407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport javax.microedition.khronos.opengles.GL; 45407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.io.IOException; 46407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.nio.ByteBuffer; 47407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.nio.ByteOrder; 48407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport java.nio.FloatBuffer; 49407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 50407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport static android.opengl.GLES20.*; 51407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport static javax.microedition.khronos.egl.EGL10.*; 524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn/** 544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Default built-in wallpaper that simply shows a static image. 554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn */ 56407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy@SuppressWarnings({"UnusedDeclaration"}) 574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornpublic class ImageWallpaper extends WallpaperService { 58fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown private static final String TAG = "ImageWallpaper"; 59407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final String GL_LOG_TAG = "ImageWallpaperGL"; 60fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown private static final boolean DEBUG = false; 61043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu"; 62fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 63ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn static final boolean FIXED_SIZED_SURFACE = true; 64881fb2092b41f4447e708da2f341d2ca5602c0d4Erik Gilling static final boolean USE_OPENGL = true; 65ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn 66ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy WallpaperManager mWallpaperManager; 67407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 68c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase DrawableEngine mEngine; 69c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase 70407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy boolean mIsHwAccelerated; 71ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 72ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy @Override 73ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy public void onCreate() { 74ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy super.onCreate(); 75ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); 76407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 77407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy //noinspection PointlessBooleanExpression,ConstantConditions 78407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (FIXED_SIZED_SURFACE && USE_OPENGL) { 79043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy if (!isEmulator()) { 8098365d7663cbd82979a5700faf0050220b01084dJeff Brown mIsHwAccelerated = ActivityManager.isHighEndGfx(); 81043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy } 82407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 83ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 84ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 85c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase @Override 86c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase public void onTrimMemory(int level) { 87c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase if (mEngine != null) { 88c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mEngine.trimMemory(level); 89c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 90c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 91c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase 92043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy private static boolean isEmulator() { 93043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy return "1".equals(SystemProperties.get(PROPERTY_KERNEL_QEMU, "0")); 94043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy } 95043a6b1e5709c46cb8094766c792ec57d3fd97dfRomain Guy 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 private final Object mLock = new Object[0]; 106407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 107407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // TODO: Not currently used, keeping around until we know we don't need it 108407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy @SuppressWarnings({"UnusedDeclaration"}) 109284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn private WallpaperObserver mReceiver; 110407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 111407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Bitmap mBackground; 1125f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; 1132f20081f9fd734e466147bf1091d06cc7331458cChet Haase int mLastRotation = -1; 1147341d7a104b47996445d069a695e155a07184606Dianne Hackborn float mXOffset; 1157341d7a104b47996445d069a695e155a07184606Dianne Hackborn float mYOffset; 116759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn 117fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown boolean mVisible = true; 118fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown boolean mRedrawNeeded; 119fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown boolean mOffsetsChanged; 120fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown int mLastXTranslation; 121fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown int mLastYTranslation; 122fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 123407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGL10 mEgl; 124407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLDisplay mEglDisplay; 125407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLConfig mEglConfig; 126407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLContext mEglContext; 127407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLSurface mEglSurface; 128407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private GL mGL; 129407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 130407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final String sSimpleVS = 131407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "attribute vec4 position;\n" + 132407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "attribute vec2 texCoords;\n" + 133407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "varying vec2 outTexCoords;\n" + 134407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "uniform mat4 projection;\n" + 135407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "\nvoid main(void) {\n" + 136407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy " outTexCoords = texCoords;\n" + 137407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy " gl_Position = projection * position;\n" + 138407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "}\n\n"; 139407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final String sSimpleFS = 140407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "precision mediump float;\n\n" + 141407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "varying vec2 outTexCoords;\n" + 142407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "uniform sampler2D texture;\n" + 143407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "\nvoid main(void) {\n" + 144407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy " gl_FragColor = texture2D(texture, outTexCoords);\n" + 145407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy "}\n\n"; 146407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 147407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int FLOAT_SIZE_BYTES = 4; 148407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 149407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 150407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 151407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 152284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn class WallpaperObserver extends BroadcastReceiver { 153284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn public void onReceive(Context context, Intent intent) { 15430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 15530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onReceive"); 15630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 15730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 158fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown synchronized (mLock) { 1595f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = mLastSurfaceHeight = -1; 160ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn mBackground = null; 161ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn mRedrawNeeded = true; 1622f20081f9fd734e466147bf1091d06cc7331458cChet Haase drawFrameLocked(); 163fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 164284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn } 165284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn } 166284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn 16735be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey public DrawableEngine() { 16835be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey super(); 16935be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey setFixedSizeAllowed(true); 17035be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey } 17135be7560300a97fc3675bdd325910f28827d9508Jeff Sharkey 172c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase public void trimMemory(int level) { 173c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW && 174c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground != null && mIsHwAccelerated) { 1755f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (DEBUG) { 1765f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "trimMemory"); 1775f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 178c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground.recycle(); 179c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground = null; 180c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mWallpaperManager.forgetLoadedWallpaper(); 181c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 182c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 183c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase 1844c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn @Override 185759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn public void onCreate(SurfaceHolder surfaceHolder) { 18630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 18730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onCreate"); 18830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 18930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 190759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn super.onCreate(surfaceHolder); 1919ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn 192407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // TODO: Don't need this currently because the wallpaper service 1939ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn // will restart the image wallpaper whenever the image changes. 1949ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn //IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED); 1959ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn //mReceiver = new WallpaperObserver(); 1969ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn //registerReceiver(mReceiver, filter, null, mHandler); 197fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 198ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn updateSurfaceSize(surfaceHolder); 199a8e5a2bcd6a0d35893187c6df42425c03be005daChet Haase 200a8e5a2bcd6a0d35893187c6df42425c03be005daChet Haase setOffsetNotificationsEnabled(false); 2014c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 2024c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 2034c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn @Override 204284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn public void onDestroy() { 205284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn super.onDestroy(); 2069ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn if (mReceiver != null) { 2079ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn unregisterReceiver(mReceiver); 2089ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn } 209284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn } 210284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn 211284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn @Override 212ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { 213912d9d13698693709991b76f83a8d64179e97e83Dianne Hackborn super.onDesiredSizeChanged(desiredWidth, desiredHeight); 214ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn SurfaceHolder surfaceHolder = getSurfaceHolder(); 215ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn if (surfaceHolder != null) { 216ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn updateSurfaceSize(surfaceHolder); 217ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn } 218ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn } 219ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn 220ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn void updateSurfaceSize(SurfaceHolder surfaceHolder) { 221ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn if (FIXED_SIZED_SURFACE) { 222ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn // Used a fixed size surface, because we are special. We can do 223ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn // this because we know the current design of window animations doesn't 224ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn // cause this to break. 225ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn surfaceHolder.setFixedSize(getDesiredMinimumWidth(), getDesiredMinimumHeight()); 226ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn } else { 227ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn surfaceHolder.setSizeFromLayout(); 228ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn } 229ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn } 230ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn 231ac1471a4fff660710f88afc679c4119fdf8dc417Dianne Hackborn @Override 232759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn public void onVisibilityChanged(boolean visible) { 23330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 2342f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible); 23530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 23630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 237fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown synchronized (mLock) { 23830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (mVisible != visible) { 23930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 24030bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "Visibility changed to visible=" + visible); 24130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 24230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown mVisible = visible; 2432f20081f9fd734e466147bf1091d06cc7331458cChet Haase drawFrameLocked(); 24430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 245fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 246759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn } 247fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 248759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn @Override 2498df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn public void onTouchEvent(MotionEvent event) { 2508df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn super.onTouchEvent(event); 2518df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn } 2528df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn 2538df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn @Override 25472c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn public void onOffsetsChanged(float xOffset, float yOffset, 255bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen float xOffsetStep, float yOffsetStep, 25672c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn int xPixels, int yPixels) { 25730bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 25830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset 25930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown + ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep 26030bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown + ", xPixels=" + xPixels + ", yPixels=" + yPixels); 26130bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 26230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown 263fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown synchronized (mLock) { 264fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown if (mXOffset != xOffset || mYOffset != yOffset) { 265fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown if (DEBUG) { 266fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ")."); 267fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 268fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown mXOffset = xOffset; 269fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown mYOffset = yOffset; 27030bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown mOffsetsChanged = true; 271fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 2722f20081f9fd734e466147bf1091d06cc7331458cChet Haase drawFrameLocked(); 273fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 27472c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn } 27572c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn 27672c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn @Override 2774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { 27830bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown if (DEBUG) { 27930bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height); 280fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 2814c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 28230bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown super.onSurfaceChanged(holder, format, width, height); 2834c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 28430bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown synchronized (mLock) { 2852f20081f9fd734e466147bf1091d06cc7331458cChet Haase drawFrameLocked(); 28630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown } 2874c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 288fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown 289fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner @Override 2902f20081f9fd734e466147bf1091d06cc7331458cChet Haase public void onSurfaceDestroyed(SurfaceHolder holder) { 2912f20081f9fd734e466147bf1091d06cc7331458cChet Haase super.onSurfaceDestroyed(holder); 2925f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = mLastSurfaceHeight = -1; 2932f20081f9fd734e466147bf1091d06cc7331458cChet Haase } 2942f20081f9fd734e466147bf1091d06cc7331458cChet Haase 2952f20081f9fd734e466147bf1091d06cc7331458cChet Haase @Override 2962f20081f9fd734e466147bf1091d06cc7331458cChet Haase public void onSurfaceCreated(SurfaceHolder holder) { 2972f20081f9fd734e466147bf1091d06cc7331458cChet Haase super.onSurfaceCreated(holder); 2985f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = mLastSurfaceHeight = -1; 2992f20081f9fd734e466147bf1091d06cc7331458cChet Haase } 3002f20081f9fd734e466147bf1091d06cc7331458cChet Haase 3012f20081f9fd734e466147bf1091d06cc7331458cChet Haase @Override 302fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner public void onSurfaceRedrawNeeded(SurfaceHolder holder) { 303fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner if (DEBUG) { 3042f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "onSurfaceRedrawNeeded"); 305fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner } 306fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner super.onSurfaceRedrawNeeded(holder); 307fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner 308fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner synchronized (mLock) { 3092f20081f9fd734e466147bf1091d06cc7331458cChet Haase drawFrameLocked(); 310fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner } 311fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner } 312fb729c7b4420eacbc65a958beb53511ff59ba3e6Craig Mautner 3132f20081f9fd734e466147bf1091d06cc7331458cChet Haase void drawFrameLocked() { 3142f20081f9fd734e466147bf1091d06cc7331458cChet Haase SurfaceHolder sh = getSurfaceHolder(); 3152f20081f9fd734e466147bf1091d06cc7331458cChet Haase final Rect frame = sh.getSurfaceFrame(); 3162f20081f9fd734e466147bf1091d06cc7331458cChet Haase final int dw = frame.width(); 3172f20081f9fd734e466147bf1091d06cc7331458cChet Haase final int dh = frame.height(); 3182f20081f9fd734e466147bf1091d06cc7331458cChet Haase int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)). 3192f20081f9fd734e466147bf1091d06cc7331458cChet Haase getDefaultDisplay().getRotation(); 3205f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth || dh != mLastSurfaceHeight; 3212f20081f9fd734e466147bf1091d06cc7331458cChet Haase 3225f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation; 3232f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (!redrawNeeded && !mOffsetsChanged) { 3242f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (DEBUG) { 3252f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "Suppressed drawFrame since redraw is not needed " 3262f20081f9fd734e466147bf1091d06cc7331458cChet Haase + "and offsets have not changed."); 327fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 3282f20081f9fd734e466147bf1091d06cc7331458cChet Haase return; 329fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 3302f20081f9fd734e466147bf1091d06cc7331458cChet Haase mLastRotation = newRotation; 331321357b6066a34cc12a0528b7b835c7664db2e08Michael Jurka 3322f20081f9fd734e466147bf1091d06cc7331458cChet Haase // Load bitmap if it is not yet loaded or if it was loaded at a different size 3335f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (mBackground == null || surfaceDimensionsChanged) { 3342f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (DEBUG) { 3355f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " + 3365f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mBackground + ", " + 3375f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase ((mBackground == null) ? 0 : mBackground.getWidth()) + ", " + 3385f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase ((mBackground == null) ? 0 : mBackground.getHeight()) + ", " + 3395f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase dw + ", " + dh); 3402f20081f9fd734e466147bf1091d06cc7331458cChet Haase } 341ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn updateWallpaperLocked(); 3425f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (mBackground == null) { 3435f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (DEBUG) { 3445f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "Unable to load bitmap"); 3455f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3465f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase return; 3475f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3485f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (DEBUG) { 3495f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) { 3505f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " + 3515f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase dw + ", " + dh + ", " + mBackground.getWidth() + ", " + 3525f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mBackground.getHeight()); 3535f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3545f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 355ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn } 356ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn 3575f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final int availw = dw - mBackground.getWidth(); 3585f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final int availh = dh - mBackground.getHeight(); 359033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2); 360033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2); 361033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown 362033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown mOffsetsChanged = false; 3632f20081f9fd734e466147bf1091d06cc7331458cChet Haase mRedrawNeeded = false; 3645f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase if (surfaceDimensionsChanged) { 3655f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceWidth = dw; 3665f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mLastSurfaceHeight = dh; 3675f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase } 3682f20081f9fd734e466147bf1091d06cc7331458cChet Haase mLastXTranslation = xPixels; 3692f20081f9fd734e466147bf1091d06cc7331458cChet Haase mLastYTranslation = yPixels; 3702f20081f9fd734e466147bf1091d06cc7331458cChet Haase if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { 371033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown if (DEBUG) { 372033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown Log.d(TAG, "Suppressed drawFrame since the image has not " 373033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown + "actually moved an integral number of pixels."); 374033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown } 375033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown return; 376033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown } 377033f63a1a5e8f768a72a11561fe70957eb44fa3eJeff Brown 378c92f150af0fb93b677a4ec6e2aca1b9a9bdd8760Craig Mautner if (DEBUG) { 3792f20081f9fd734e466147bf1091d06cc7331458cChet Haase Log.d(TAG, "Redrawing wallpaper"); 380c92f150af0fb93b677a4ec6e2aca1b9a9bdd8760Craig Mautner } 381407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mIsHwAccelerated) { 382f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { 383f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); 384f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy } 385407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } else { 386407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); 387c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase if (FIXED_SIZED_SURFACE) { 388c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // If the surface is fixed-size, we should only need to 389c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // draw it once and then we'll let the window manager 390c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // position it appropriately. As such, we no longer needed 391c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // the loaded bitmap. Yay! 392c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase // hw-accelerated path retains bitmap for faster rotation 393c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mBackground = null; 394c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase mWallpaperManager.forgetLoadedWallpaper(); 395c61d70ec46bc44344a419a0a15ccbecd1f8f1a2dChet Haase } 396759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn } 397ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn 398759a39e8d2a8b27ef07e102394629dce68aa186bDianne Hackborn } 399ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy 4005f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase private void updateWallpaperLocked() { 401fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Throwable exception = null; 402fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown try { 4035f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase mWallpaperManager.forgetLoadedWallpaper(); // force reload 404589a6af173c10738d2a83c69a9dda36579cc739dChet Haase mBackground = null; 405407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mBackground = mWallpaperManager.getBitmap(); 406fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } catch (RuntimeException e) { 407fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown exception = e; 408fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } catch (OutOfMemoryError e) { 409fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown exception = e; 410fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } 411407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 412fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown if (exception != null) { 413fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown mBackground = null; 414fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // Note that if we do fail at this, and the default wallpaper can't 415fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // be loaded, we will go into a cycle. Don't do a build where the 416fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // default wallpaper can't be loaded. 417fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Log.w(TAG, "Unable to load wallpaper!", exception); 418c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn try { 419fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown mWallpaperManager.clear(); 420fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown } catch (IOException ex) { 421fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown // now we're really screwed. 422fa2e504087362989e5dd7fe6e65b6481cef59495Jeff Brown Log.w(TAG, "Unable reset to default wallpaper!", ex); 423c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn } 424ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 425407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 426407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 427407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int x, int y) { 428407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Canvas c = sh.lockCanvas(); 429407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (c != null) { 430407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy try { 431407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (DEBUG) { 432407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.d(TAG, "Redrawing: x=" + x + ", y=" + y); 433407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 434407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 435407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.translate(x, y); 436407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (w < 0 || h < 0) { 437407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.save(Canvas.CLIP_SAVE_FLAG); 4385f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase c.clipRect(0, 0, mBackground.getWidth(), mBackground.getHeight(), 4395f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase Op.DIFFERENCE); 440407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.drawColor(0xff000000); 441407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.restore(); 442407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 443407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mBackground != null) { 444407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy c.drawBitmap(mBackground, 0, 0, null); 445407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 446407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } finally { 447407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy sh.unlockCanvasAndPost(c); 448407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 449407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 450407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 451407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 452f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) { 453f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy if (!initGL(sh)) return false; 454407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 4555f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final float right = left + mBackground.getWidth(); 4565f0d976b37b919b74509b6f22e4ad3fa56422f6cChet Haase final float bottom = top + mBackground.getHeight(); 457407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 458407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final Rect frame = sh.getSurfaceFrame(); 459407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final Matrix4f ortho = new Matrix4f(); 460407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f); 461407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 462407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final FloatBuffer triangleVertices = createMesh(left, top, right, bottom); 463407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 464407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int texture = loadTexture(mBackground); 465407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int program = buildProgram(sSimpleVS, sSimpleFS); 4662f20081f9fd734e466147bf1091d06cc7331458cChet Haase 467407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int attribPosition = glGetAttribLocation(program, "position"); 468407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int attribTexCoords = glGetAttribLocation(program, "texCoords"); 469407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int uniformTexture = glGetUniformLocation(program, "texture"); 470407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int uniformProjection = glGetUniformLocation(program, "projection"); 471407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 472407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 473407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 474407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glViewport(0, 0, frame.width(), frame.height()); 475407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glBindTexture(GL_TEXTURE_2D, texture); 476407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 477407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glUseProgram(program); 478407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glEnableVertexAttribArray(attribPosition); 479407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glEnableVertexAttribArray(attribTexCoords); 480407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glUniform1i(uniformTexture, 0); 481407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0); 482407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 483407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 484407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 485407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (w < 0 || h < 0) { 486407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 487407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glClear(GL_COLOR_BUFFER_BIT); 488407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 4892f20081f9fd734e466147bf1091d06cc7331458cChet Haase 490407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // drawQuad 491407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 492407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, 493407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 494407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 495407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 496407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, 497407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); 498407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 499407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 5002f20081f9fd734e466147bf1091d06cc7331458cChet Haase 501407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { 502407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("Cannot swap buffers"); 503407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 504407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkEglError(); 5052f20081f9fd734e466147bf1091d06cc7331458cChet Haase 506407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy finishGL(); 507f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy 508f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy return true; 509407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 510407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 511407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private FloatBuffer createMesh(int left, int top, float right, float bottom) { 512407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final float[] verticesData = { 513407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy // X, Y, Z, U, V 514407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy left, bottom, 0.0f, 0.0f, 1.0f, 515407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy right, bottom, 0.0f, 1.0f, 1.0f, 516407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy left, top, 0.0f, 0.0f, 0.0f, 517407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy right, top, 0.0f, 1.0f, 0.0f, 518407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy }; 519407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 520407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final int bytes = verticesData.length * FLOAT_SIZE_BYTES; 521407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order( 522407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy ByteOrder.nativeOrder()).asFloatBuffer(); 523407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy triangleVertices.put(verticesData).position(0); 524407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return triangleVertices; 525407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 526407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 527407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int loadTexture(Bitmap bitmap) { 528407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] textures = new int[1]; 529407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 530407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glActiveTexture(GL_TEXTURE0); 531407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glGenTextures(1, textures, 0); 532407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 533407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 534407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int texture = textures[0]; 535407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glBindTexture(GL_TEXTURE_2D, texture); 536407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 537407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 538407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 539407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 540407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 541407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 542407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 543407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 544407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0); 545407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 546407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 547407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return texture; 548407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 549407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 550407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int buildProgram(String vertex, String fragment) { 551407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 552407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (vertexShader == 0) return 0; 553407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 554407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 555407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (fragmentShader == 0) return 0; 556407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 557407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int program = glCreateProgram(); 558407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glAttachShader(program, vertexShader); 559407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 560407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 561407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glAttachShader(program, fragmentShader); 562407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 563407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 564407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glLinkProgram(program); 565407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 566407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 567407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] status = new int[1]; 568407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glGetProgramiv(program, GL_LINK_STATUS, status, 0); 569407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (status[0] != GL_TRUE) { 570407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy String error = glGetProgramInfoLog(program); 571407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.d(GL_LOG_TAG, "Error while linking program:\n" + error); 572407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteShader(vertexShader); 573407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteShader(fragmentShader); 574407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteProgram(program); 575407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return 0; 576407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 577407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 578407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return program; 579407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 580407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 581407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int buildShader(String source, int type) { 582407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int shader = glCreateShader(type); 583407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 584407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glShaderSource(shader, source); 585407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 586407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 587407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glCompileShader(shader); 588407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy checkGlError(); 589407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 590407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] status = new int[1]; 591407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0); 592407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (status[0] != GL_TRUE) { 593407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy String error = glGetShaderInfoLog(shader); 594407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error); 595407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy glDeleteShader(shader); 596407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return 0; 597407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 598407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 599407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return shader; 600407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 601407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 602407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void checkEglError() { 603407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int error = mEgl.eglGetError(); 604407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (error != EGL_SUCCESS) { 605407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error)); 606407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 607407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 608407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 609407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void checkGlError() { 610407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int error = glGetError(); 611407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (error != GL_NO_ERROR) { 612407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable()); 613407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 614407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 615407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 616407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private void finishGL() { 617f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 618407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEgl.eglDestroySurface(mEglDisplay, mEglSurface); 619f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy mEgl.eglDestroyContext(mEglDisplay, mEglContext); 620407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 621407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 622f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy private boolean initGL(SurfaceHolder surfaceHolder) { 623407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEgl = (EGL10) EGLContext.getEGL(); 624407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 625407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglDisplay = mEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY); 626407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mEglDisplay == EGL_NO_DISPLAY) { 627407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglGetDisplay failed " + 628407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 629407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 630407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 631407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] version = new int[2]; 632407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglInitialize(mEglDisplay, version)) { 633407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglInitialize failed " + 634407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 635407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 636407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 637407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglConfig = chooseEglConfig(); 638407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mEglConfig == null) { 639407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglConfig not initialized"); 640407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 641407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 642407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); 643407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 644407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null); 645407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 646407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) { 647407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int error = mEgl.eglGetError(); 648407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (error == EGL_BAD_NATIVE_WINDOW) { 649407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy Log.e(GL_LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); 650f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy return false; 651407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 652407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("createWindowSurface failed " + 653407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(error)); 654407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 655407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 656407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 657407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new RuntimeException("eglMakeCurrent failed " + 658407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 659407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 660407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 661407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy mGL = mEglContext.getGL(); 662f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy 663f929629e74fe84b986f76db448b9c95d72b2903eRomain Guy return true; 664407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 665407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 666407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 667407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { 668407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 669407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list); 670407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 671407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 672407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private EGLConfig chooseEglConfig() { 673407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] configsCount = new int[1]; 674407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGLConfig[] configs = new EGLConfig[1]; 675407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy int[] configSpec = getConfig(); 676407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { 677407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy throw new IllegalArgumentException("eglChooseConfig failed " + 678407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(mEgl.eglGetError())); 679407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } else if (configsCount[0] > 0) { 680407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return configs[0]; 681407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 682407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return null; 683407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy } 684407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy 685407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy private int[] getConfig() { 686407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy return new int[] { 687407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 688407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_RED_SIZE, 8, 689407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_GREEN_SIZE, 8, 690407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_BLUE_SIZE, 8, 691407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_ALPHA_SIZE, 0, 692407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_DEPTH_SIZE, 0, 693407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_STENCIL_SIZE, 0, 6948efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy EGL_CONFIG_CAVEAT, EGL_NONE, 695407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy EGL_NONE 696407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy }; 697ef654bdd5bd957574abd4194d7b0585f3fc3fd34Romain Guy } 6984c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 6994c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn} 700