Merge "Add OpenGL backend to ImageWallpaper Bug #5204874"
This commit is contained in:
@@ -13974,6 +13974,7 @@ package android.opengl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class GLUtils {
|
public final class GLUtils {
|
||||||
|
method public static java.lang.String getEGLErrorString(int);
|
||||||
method public static int getInternalFormat(android.graphics.Bitmap);
|
method public static int getInternalFormat(android.graphics.Bitmap);
|
||||||
method public static int getType(android.graphics.Bitmap);
|
method public static int getType(android.graphics.Bitmap);
|
||||||
method public static void texImage2D(int, int, int, android.graphics.Bitmap, int);
|
method public static void texImage2D(int, int, int, android.graphics.Bitmap, int);
|
||||||
|
|||||||
@@ -107,19 +107,22 @@ public class WallpaperManager {
|
|||||||
private final int mHeight;
|
private final int mHeight;
|
||||||
private int mDrawLeft;
|
private int mDrawLeft;
|
||||||
private int mDrawTop;
|
private int mDrawTop;
|
||||||
|
private final Paint mPaint;
|
||||||
|
|
||||||
private FastBitmapDrawable(Bitmap bitmap) {
|
private FastBitmapDrawable(Bitmap bitmap) {
|
||||||
mBitmap = bitmap;
|
mBitmap = bitmap;
|
||||||
mWidth = bitmap.getWidth();
|
mWidth = bitmap.getWidth();
|
||||||
mHeight = bitmap.getHeight();
|
mHeight = bitmap.getHeight();
|
||||||
|
|
||||||
setBounds(0, 0, mWidth, mHeight);
|
setBounds(0, 0, mWidth, mHeight);
|
||||||
|
|
||||||
|
mPaint = new Paint();
|
||||||
|
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
Paint paint = new Paint();
|
canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, mPaint);
|
||||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
|
|
||||||
canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, paint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -133,34 +136,24 @@ public class WallpaperManager {
|
|||||||
mDrawTop = top + (bottom-top - mHeight) / 2;
|
mDrawTop = top + (bottom-top - mHeight) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBounds(Rect bounds) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
super.setBounds(bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAlpha(int alpha) {
|
public void setAlpha(int alpha) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException("Not supported with this drawable");
|
||||||
"Not supported with this drawable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setColorFilter(ColorFilter cf) {
|
public void setColorFilter(ColorFilter cf) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException("Not supported with this drawable");
|
||||||
"Not supported with this drawable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDither(boolean dither) {
|
public void setDither(boolean dither) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException("Not supported with this drawable");
|
||||||
"Not supported with this drawable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFilterBitmap(boolean filter) {
|
public void setFilterBitmap(boolean filter) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException("Not supported with this drawable");
|
||||||
"Not supported with this drawable");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -230,7 +223,7 @@ public class WallpaperManager {
|
|||||||
}
|
}
|
||||||
mWallpaper = null;
|
mWallpaper = null;
|
||||||
try {
|
try {
|
||||||
mWallpaper = getCurrentWallpaperLocked(context);
|
mWallpaper = getCurrentWallpaperLocked();
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
Log.w(TAG, "No memory load current wallpaper", e);
|
Log.w(TAG, "No memory load current wallpaper", e);
|
||||||
}
|
}
|
||||||
@@ -253,7 +246,7 @@ public class WallpaperManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap getCurrentWallpaperLocked(Context context) {
|
private Bitmap getCurrentWallpaperLocked() {
|
||||||
try {
|
try {
|
||||||
Bundle params = new Bundle();
|
Bundle params = new Bundle();
|
||||||
ParcelFileDescriptor fd = mService.getWallpaper(this, params);
|
ParcelFileDescriptor fd = mService.getWallpaper(this, params);
|
||||||
@@ -265,17 +258,19 @@ public class WallpaperManager {
|
|||||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
Bitmap bm = BitmapFactory.decodeFileDescriptor(
|
Bitmap bm = BitmapFactory.decodeFileDescriptor(
|
||||||
fd.getFileDescriptor(), null, options);
|
fd.getFileDescriptor(), null, options);
|
||||||
return generateBitmap(context, bm, width, height);
|
return generateBitmap(bm, width, height);
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
Log.w(TAG, "Can't decode file", e);
|
Log.w(TAG, "Can't decode file", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
fd.close();
|
fd.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -291,27 +286,29 @@ public class WallpaperManager {
|
|||||||
try {
|
try {
|
||||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
Bitmap bm = BitmapFactory.decodeStream(is, null, options);
|
Bitmap bm = BitmapFactory.decodeStream(is, null, options);
|
||||||
return generateBitmap(context, bm, width, height);
|
return generateBitmap(bm, width, height);
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
Log.w(TAG, "Can't decode stream", e);
|
Log.w(TAG, "Can't decode stream", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
is.close();
|
is.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object mSync = new Object();
|
private static final Object sSync = new Object[0];
|
||||||
private static Globals sGlobals;
|
private static Globals sGlobals;
|
||||||
|
|
||||||
static void initGlobals(Looper looper) {
|
static void initGlobals(Looper looper) {
|
||||||
synchronized (mSync) {
|
synchronized (sSync) {
|
||||||
if (sGlobals == null) {
|
if (sGlobals == null) {
|
||||||
sGlobals = new Globals(looper);
|
sGlobals = new Globals(looper);
|
||||||
}
|
}
|
||||||
@@ -390,8 +387,7 @@ public class WallpaperManager {
|
|||||||
public Drawable getFastDrawable() {
|
public Drawable getFastDrawable() {
|
||||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
|
||||||
if (bm != null) {
|
if (bm != null) {
|
||||||
Drawable dr = new FastBitmapDrawable(bm);
|
return new FastBitmapDrawable(bm);
|
||||||
return dr;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -406,12 +402,20 @@ public class WallpaperManager {
|
|||||||
public Drawable peekFastDrawable() {
|
public Drawable peekFastDrawable() {
|
||||||
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
|
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
|
||||||
if (bm != null) {
|
if (bm != null) {
|
||||||
Drawable dr = new FastBitmapDrawable(bm);
|
return new FastBitmapDrawable(bm);
|
||||||
return dr;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like {@link #getDrawable()} but returns a Bitmap.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public Bitmap getBitmap() {
|
||||||
|
return sGlobals.peekWallpaperBitmap(mContext, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all internal references to the last loaded wallpaper. Useful
|
* Remove all internal references to the last loaded wallpaper. Useful
|
||||||
* for apps that want to reduce memory usage when they only temporarily
|
* for apps that want to reduce memory usage when they only temporarily
|
||||||
@@ -464,6 +468,7 @@ public class WallpaperManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,6 +498,7 @@ public class WallpaperManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,6 +530,7 @@ public class WallpaperManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,6 +601,7 @@ public class WallpaperManager {
|
|||||||
try {
|
try {
|
||||||
sGlobals.mService.setDimensionHints(minimumWidth, minimumHeight);
|
sGlobals.mService.setDimensionHints(minimumWidth, minimumHeight);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -690,7 +698,7 @@ public class WallpaperManager {
|
|||||||
setResource(com.android.internal.R.drawable.default_wallpaper);
|
setResource(com.android.internal.R.drawable.default_wallpaper);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitmap generateBitmap(Context context, Bitmap bm, int width, int height) {
|
static Bitmap generateBitmap(Bitmap bm, int width, int height) {
|
||||||
if (bm == null) {
|
if (bm == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -717,7 +725,7 @@ public class WallpaperManager {
|
|||||||
|
|
||||||
if (deltaw > 0 || deltah > 0) {
|
if (deltaw > 0 || deltah > 0) {
|
||||||
// We need to scale up so it covers the entire area.
|
// We need to scale up so it covers the entire area.
|
||||||
float scale = 1.0f;
|
float scale;
|
||||||
if (deltaw > deltah) {
|
if (deltaw > deltah) {
|
||||||
scale = width / (float)targetRect.right;
|
scale = width / (float)targetRect.right;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.content.ComponentCallbacks2;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
|
import android.opengl.GLUtils;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -401,51 +402,6 @@ public abstract class HardwareRenderer {
|
|||||||
return mDirtyRegionsEnabled;
|
return mDirtyRegionsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a string for the EGL error code, or the hex representation
|
|
||||||
* if the error is unknown.
|
|
||||||
*
|
|
||||||
* @param error The EGL error to convert into a String.
|
|
||||||
*
|
|
||||||
* @return An error string correponding to the EGL error code.
|
|
||||||
*/
|
|
||||||
static String getEGLErrorString(int error) {
|
|
||||||
switch (error) {
|
|
||||||
case EGL_SUCCESS:
|
|
||||||
return "EGL_SUCCESS";
|
|
||||||
case EGL_NOT_INITIALIZED:
|
|
||||||
return "EGL_NOT_INITIALIZED";
|
|
||||||
case EGL_BAD_ACCESS:
|
|
||||||
return "EGL_BAD_ACCESS";
|
|
||||||
case EGL_BAD_ALLOC:
|
|
||||||
return "EGL_BAD_ALLOC";
|
|
||||||
case EGL_BAD_ATTRIBUTE:
|
|
||||||
return "EGL_BAD_ATTRIBUTE";
|
|
||||||
case EGL_BAD_CONFIG:
|
|
||||||
return "EGL_BAD_CONFIG";
|
|
||||||
case EGL_BAD_CONTEXT:
|
|
||||||
return "EGL_BAD_CONTEXT";
|
|
||||||
case EGL_BAD_CURRENT_SURFACE:
|
|
||||||
return "EGL_BAD_CURRENT_SURFACE";
|
|
||||||
case EGL_BAD_DISPLAY:
|
|
||||||
return "EGL_BAD_DISPLAY";
|
|
||||||
case EGL_BAD_MATCH:
|
|
||||||
return "EGL_BAD_MATCH";
|
|
||||||
case EGL_BAD_NATIVE_PIXMAP:
|
|
||||||
return "EGL_BAD_NATIVE_PIXMAP";
|
|
||||||
case EGL_BAD_NATIVE_WINDOW:
|
|
||||||
return "EGL_BAD_NATIVE_WINDOW";
|
|
||||||
case EGL_BAD_PARAMETER:
|
|
||||||
return "EGL_BAD_PARAMETER";
|
|
||||||
case EGL_BAD_SURFACE:
|
|
||||||
return "EGL_BAD_SURFACE";
|
|
||||||
case EGL11.EGL_CONTEXT_LOST:
|
|
||||||
return "EGL_CONTEXT_LOST";
|
|
||||||
default:
|
|
||||||
return "0x" + Integer.toHexString(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
|
* Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
|
||||||
* is invoked and the requested flag is turned off. The error code is
|
* is invoked and the requested flag is turned off. The error code is
|
||||||
@@ -458,7 +414,7 @@ public abstract class HardwareRenderer {
|
|||||||
// something bad has happened revert to
|
// something bad has happened revert to
|
||||||
// normal rendering.
|
// normal rendering.
|
||||||
fallback(error != EGL11.EGL_CONTEXT_LOST);
|
fallback(error != EGL11.EGL_CONTEXT_LOST);
|
||||||
Log.w(LOG_TAG, "EGL error: " + getEGLErrorString(error));
|
Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -523,14 +479,14 @@ public abstract class HardwareRenderer {
|
|||||||
|
|
||||||
if (sEglDisplay == EGL_NO_DISPLAY) {
|
if (sEglDisplay == EGL_NO_DISPLAY) {
|
||||||
throw new RuntimeException("eglGetDisplay failed "
|
throw new RuntimeException("eglGetDisplay failed "
|
||||||
+ getEGLErrorString(sEgl.eglGetError()));
|
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can now initialize EGL for that display
|
// We can now initialize EGL for that display
|
||||||
int[] version = new int[2];
|
int[] version = new int[2];
|
||||||
if (!sEgl.eglInitialize(sEglDisplay, version)) {
|
if (!sEgl.eglInitialize(sEglDisplay, version)) {
|
||||||
throw new RuntimeException("eglInitialize failed " +
|
throw new RuntimeException("eglInitialize failed " +
|
||||||
getEGLErrorString(sEgl.eglGetError()));
|
GLUtils.getEGLErrorString(sEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
sEglConfig = chooseEglConfig();
|
sEglConfig = chooseEglConfig();
|
||||||
@@ -579,7 +535,7 @@ public abstract class HardwareRenderer {
|
|||||||
|
|
||||||
if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
|
if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
|
||||||
throw new IllegalArgumentException("eglChooseConfig failed " +
|
throw new IllegalArgumentException("eglChooseConfig failed " +
|
||||||
getEGLErrorString(sEgl.eglGetError()));
|
GLUtils.getEGLErrorString(sEgl.eglGetError()));
|
||||||
} else if (configsCount[0] > 0) {
|
} else if (configsCount[0] > 0) {
|
||||||
if ("choice".equalsIgnoreCase(debug)) {
|
if ("choice".equalsIgnoreCase(debug)) {
|
||||||
printConfig(configs[0]);
|
printConfig(configs[0]);
|
||||||
@@ -647,7 +603,7 @@ public abstract class HardwareRenderer {
|
|||||||
*/
|
*/
|
||||||
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||||
throw new Surface.OutOfResourcesException("eglMakeCurrent failed "
|
throw new Surface.OutOfResourcesException("eglMakeCurrent failed "
|
||||||
+ getEGLErrorString(sEgl.eglGetError()));
|
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If mDirtyRegions is set, this means we have an EGL configuration
|
// If mDirtyRegions is set, this means we have an EGL configuration
|
||||||
@@ -734,7 +690,7 @@ public abstract class HardwareRenderer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("createWindowSurface failed "
|
throw new RuntimeException("createWindowSurface failed "
|
||||||
+ getEGLErrorString(error));
|
+ GLUtils.getEGLErrorString(error));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -856,7 +812,7 @@ public abstract class HardwareRenderer {
|
|||||||
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||||
fallback(true);
|
fallback(true);
|
||||||
Log.e(LOG_TAG, "eglMakeCurrent failed " +
|
Log.e(LOG_TAG, "eglMakeCurrent failed " +
|
||||||
getEGLErrorString(sEgl.eglGetError()));
|
GLUtils.getEGLErrorString(sEgl.eglGetError()));
|
||||||
return SURFACE_STATE_ERROR;
|
return SURFACE_STATE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
return SURFACE_STATE_UPDATED;
|
return SURFACE_STATE_UPDATED;
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package android.opengl;
|
package android.opengl;
|
||||||
|
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
|
import javax.microedition.khronos.egl.EGL11;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Utility class to help bridging OpenGL ES and Android APIs.
|
* Utility class to help bridging OpenGL ES and Android APIs.
|
||||||
@@ -222,6 +224,51 @@ public final class GLUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string for the EGL error code, or the hex representation
|
||||||
|
* if the error is unknown.
|
||||||
|
*
|
||||||
|
* @param error The EGL error to convert into a String.
|
||||||
|
*
|
||||||
|
* @return An error string corresponding to the EGL error code.
|
||||||
|
*/
|
||||||
|
public static String getEGLErrorString(int error) {
|
||||||
|
switch (error) {
|
||||||
|
case EGL10.EGL_SUCCESS:
|
||||||
|
return "EGL_SUCCESS";
|
||||||
|
case EGL10.EGL_NOT_INITIALIZED:
|
||||||
|
return "EGL_NOT_INITIALIZED";
|
||||||
|
case EGL10.EGL_BAD_ACCESS:
|
||||||
|
return "EGL_BAD_ACCESS";
|
||||||
|
case EGL10.EGL_BAD_ALLOC:
|
||||||
|
return "EGL_BAD_ALLOC";
|
||||||
|
case EGL10.EGL_BAD_ATTRIBUTE:
|
||||||
|
return "EGL_BAD_ATTRIBUTE";
|
||||||
|
case EGL10.EGL_BAD_CONFIG:
|
||||||
|
return "EGL_BAD_CONFIG";
|
||||||
|
case EGL10.EGL_BAD_CONTEXT:
|
||||||
|
return "EGL_BAD_CONTEXT";
|
||||||
|
case EGL10.EGL_BAD_CURRENT_SURFACE:
|
||||||
|
return "EGL_BAD_CURRENT_SURFACE";
|
||||||
|
case EGL10.EGL_BAD_DISPLAY:
|
||||||
|
return "EGL_BAD_DISPLAY";
|
||||||
|
case EGL10.EGL_BAD_MATCH:
|
||||||
|
return "EGL_BAD_MATCH";
|
||||||
|
case EGL10.EGL_BAD_NATIVE_PIXMAP:
|
||||||
|
return "EGL_BAD_NATIVE_PIXMAP";
|
||||||
|
case EGL10.EGL_BAD_NATIVE_WINDOW:
|
||||||
|
return "EGL_BAD_NATIVE_WINDOW";
|
||||||
|
case EGL10.EGL_BAD_PARAMETER:
|
||||||
|
return "EGL_BAD_PARAMETER";
|
||||||
|
case EGL10.EGL_BAD_SURFACE:
|
||||||
|
return "EGL_BAD_SURFACE";
|
||||||
|
case EGL11.EGL_CONTEXT_LOST:
|
||||||
|
return "EGL_CONTEXT_LOST";
|
||||||
|
default:
|
||||||
|
return "0x" + Integer.toHexString(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
native private static void nativeClassInit();
|
native private static void nativeClassInit();
|
||||||
|
|
||||||
native private static int native_getInternalFormat(Bitmap bitmap);
|
native private static int native_getInternalFormat(Bitmap bitmap);
|
||||||
|
|||||||
@@ -16,41 +16,65 @@
|
|||||||
|
|
||||||
package com.android.systemui;
|
package com.android.systemui;
|
||||||
|
|
||||||
import java.io.IOException;
|
import android.app.ActivityManager;
|
||||||
|
|
||||||
import android.app.WallpaperManager;
|
import android.app.WallpaperManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Region.Op;
|
import android.graphics.Region.Op;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.opengl.GLUtils;
|
||||||
import android.os.Handler;
|
import android.renderscript.Matrix4f;
|
||||||
import android.service.wallpaper.WallpaperService;
|
import android.service.wallpaper.WallpaperService;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.view.Display;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import android.content.Context;
|
import android.view.WindowManager;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.Intent;
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
import android.content.BroadcastReceiver;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
|
import javax.microedition.khronos.egl.EGLContext;
|
||||||
|
import javax.microedition.khronos.egl.EGLDisplay;
|
||||||
|
import javax.microedition.khronos.egl.EGLSurface;
|
||||||
|
import javax.microedition.khronos.opengles.GL;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
|
import static android.opengl.GLES20.*;
|
||||||
|
import static javax.microedition.khronos.egl.EGL10.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default built-in wallpaper that simply shows a static image.
|
* Default built-in wallpaper that simply shows a static image.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
public class ImageWallpaper extends WallpaperService {
|
public class ImageWallpaper extends WallpaperService {
|
||||||
private static final String TAG = "ImageWallpaper";
|
private static final String TAG = "ImageWallpaper";
|
||||||
|
private static final String GL_LOG_TAG = "ImageWallpaperGL";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
static final boolean FIXED_SIZED_SURFACE = true;
|
static final boolean FIXED_SIZED_SURFACE = true;
|
||||||
|
static final boolean USE_OPENGL = false;
|
||||||
|
|
||||||
WallpaperManager mWallpaperManager;
|
WallpaperManager mWallpaperManager;
|
||||||
private Handler mHandler;
|
|
||||||
|
boolean mIsHwAccelerated;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
|
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
|
||||||
mHandler = new Handler();
|
|
||||||
|
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||||
|
if (FIXED_SIZED_SURFACE && USE_OPENGL) {
|
||||||
|
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
|
||||||
|
Display display = windowManager.getDefaultDisplay();
|
||||||
|
mIsHwAccelerated = ActivityManager.isHighEndGfx(display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Engine onCreateEngine() {
|
public Engine onCreateEngine() {
|
||||||
@@ -58,9 +82,16 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DrawableEngine extends Engine {
|
class DrawableEngine extends Engine {
|
||||||
private final Object mLock = new Object();
|
static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||||
|
static final int EGL_OPENGL_ES2_BIT = 4;
|
||||||
|
|
||||||
|
private final Object mLock = new Object[0];
|
||||||
|
|
||||||
|
// TODO: Not currently used, keeping around until we know we don't need it
|
||||||
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
private WallpaperObserver mReceiver;
|
private WallpaperObserver mReceiver;
|
||||||
Drawable mBackground;
|
|
||||||
|
Bitmap mBackground;
|
||||||
int mBackgroundWidth = -1, mBackgroundHeight = -1;
|
int mBackgroundWidth = -1, mBackgroundHeight = -1;
|
||||||
float mXOffset;
|
float mXOffset;
|
||||||
float mYOffset;
|
float mYOffset;
|
||||||
@@ -71,6 +102,35 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
int mLastXTranslation;
|
int mLastXTranslation;
|
||||||
int mLastYTranslation;
|
int mLastYTranslation;
|
||||||
|
|
||||||
|
private EGL10 mEgl;
|
||||||
|
private EGLDisplay mEglDisplay;
|
||||||
|
private EGLConfig mEglConfig;
|
||||||
|
private EGLContext mEglContext;
|
||||||
|
private EGLSurface mEglSurface;
|
||||||
|
private GL mGL;
|
||||||
|
|
||||||
|
private static final String sSimpleVS =
|
||||||
|
"attribute vec4 position;\n" +
|
||||||
|
"attribute vec2 texCoords;\n" +
|
||||||
|
"varying vec2 outTexCoords;\n" +
|
||||||
|
"uniform mat4 projection;\n" +
|
||||||
|
"\nvoid main(void) {\n" +
|
||||||
|
" outTexCoords = texCoords;\n" +
|
||||||
|
" gl_Position = projection * position;\n" +
|
||||||
|
"}\n\n";
|
||||||
|
private static final String sSimpleFS =
|
||||||
|
"precision mediump float;\n\n" +
|
||||||
|
"varying vec2 outTexCoords;\n" +
|
||||||
|
"uniform sampler2D texture;\n" +
|
||||||
|
"\nvoid main(void) {\n" +
|
||||||
|
" gl_FragColor = texture2D(texture, outTexCoords);\n" +
|
||||||
|
"}\n\n";
|
||||||
|
|
||||||
|
private static final int FLOAT_SIZE_BYTES = 4;
|
||||||
|
private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
|
||||||
|
private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
|
||||||
|
private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
|
||||||
|
|
||||||
class WallpaperObserver extends BroadcastReceiver {
|
class WallpaperObserver extends BroadcastReceiver {
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -94,7 +154,7 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
|
|
||||||
super.onCreate(surfaceHolder);
|
super.onCreate(surfaceHolder);
|
||||||
|
|
||||||
// Don't need this currently because the wallpaper service
|
// TODO: Don't need this currently because the wallpaper service
|
||||||
// will restart the image wallpaper whenever the image changes.
|
// will restart the image wallpaper whenever the image changes.
|
||||||
//IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
|
//IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
|
||||||
//mReceiver = new WallpaperObserver();
|
//mReceiver = new WallpaperObserver();
|
||||||
@@ -221,8 +281,7 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
|
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
|
||||||
|
|
||||||
mOffsetsChanged = false;
|
mOffsetsChanged = false;
|
||||||
if (!mRedrawNeeded
|
if (!mRedrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
|
||||||
&& xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Suppressed drawFrame since the image has not "
|
Log.d(TAG, "Suppressed drawFrame since the image has not "
|
||||||
+ "actually moved an integral number of pixels.");
|
+ "actually moved an integral number of pixels.");
|
||||||
@@ -240,27 +299,10 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
updateWallpaperLocked();
|
updateWallpaperLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Slog.i(TAG, "************** DRAWING WALLAPER ******************");
|
if (mIsHwAccelerated) {
|
||||||
Canvas c = sh.lockCanvas();
|
drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels);
|
||||||
if (c != null) {
|
} else {
|
||||||
try {
|
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Redrawing: xPixels=" + xPixels + ", yPixels=" + yPixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
c.translate(xPixels, yPixels);
|
|
||||||
if (availw < 0 || availh < 0) {
|
|
||||||
c.save(Canvas.CLIP_SAVE_FLAG);
|
|
||||||
c.clipRect(0, 0, mBackgroundWidth, mBackgroundHeight, Op.DIFFERENCE);
|
|
||||||
c.drawColor(0xff000000);
|
|
||||||
c.restore();
|
|
||||||
}
|
|
||||||
if (mBackground != null) {
|
|
||||||
mBackground.draw(c);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
sh.unlockCanvasAndPost(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FIXED_SIZED_SURFACE) {
|
if (FIXED_SIZED_SURFACE) {
|
||||||
@@ -274,15 +316,15 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateWallpaperLocked() {
|
void updateWallpaperLocked() {
|
||||||
//Slog.i(TAG, "************** LOADING WALLAPER ******************");
|
|
||||||
Throwable exception = null;
|
Throwable exception = null;
|
||||||
try {
|
try {
|
||||||
mBackground = mWallpaperManager.getFastDrawable();
|
mBackground = mWallpaperManager.getBitmap();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
exception = e;
|
exception = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
mBackground = null;
|
mBackground = null;
|
||||||
// Note that if we do fail at this, and the default wallpaper can't
|
// Note that if we do fail at this, and the default wallpaper can't
|
||||||
@@ -296,8 +338,277 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
Log.w(TAG, "Unable reset to default wallpaper!", ex);
|
Log.w(TAG, "Unable reset to default wallpaper!", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mBackgroundWidth = mBackground != null ? mBackground.getIntrinsicWidth() : 0;
|
|
||||||
mBackgroundHeight = mBackground != null ? mBackground.getIntrinsicHeight() : 0;
|
mBackgroundWidth = mBackground != null ? mBackground.getWidth() : 0;
|
||||||
|
mBackgroundHeight = mBackground != null ? mBackground.getHeight() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int x, int y) {
|
||||||
|
Canvas c = sh.lockCanvas();
|
||||||
|
if (c != null) {
|
||||||
|
try {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Redrawing: x=" + x + ", y=" + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.translate(x, y);
|
||||||
|
if (w < 0 || h < 0) {
|
||||||
|
c.save(Canvas.CLIP_SAVE_FLAG);
|
||||||
|
c.clipRect(0, 0, mBackgroundWidth, mBackgroundHeight, Op.DIFFERENCE);
|
||||||
|
c.drawColor(0xff000000);
|
||||||
|
c.restore();
|
||||||
|
}
|
||||||
|
if (mBackground != null) {
|
||||||
|
c.drawBitmap(mBackground, 0, 0, null);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
sh.unlockCanvasAndPost(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) {
|
||||||
|
initGL(sh);
|
||||||
|
|
||||||
|
final float right = left + mBackgroundWidth;
|
||||||
|
final float bottom = top + mBackgroundHeight;
|
||||||
|
|
||||||
|
final Rect frame = sh.getSurfaceFrame();
|
||||||
|
|
||||||
|
final Matrix4f ortho = new Matrix4f();
|
||||||
|
ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
final FloatBuffer triangleVertices = createMesh(left, top, right, bottom);
|
||||||
|
|
||||||
|
final int texture = loadTexture(mBackground);
|
||||||
|
final int program = buildProgram(sSimpleVS, sSimpleFS);
|
||||||
|
|
||||||
|
final int attribPosition = glGetAttribLocation(program, "position");
|
||||||
|
final int attribTexCoords = glGetAttribLocation(program, "texCoords");
|
||||||
|
final int uniformTexture = glGetUniformLocation(program, "texture");
|
||||||
|
final int uniformProjection = glGetUniformLocation(program, "projection");
|
||||||
|
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
glViewport(0, 0, frame.width(), frame.height());
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
|
||||||
|
glUseProgram(program);
|
||||||
|
glEnableVertexAttribArray(attribPosition);
|
||||||
|
glEnableVertexAttribArray(attribTexCoords);
|
||||||
|
glUniform1i(uniformTexture, 0);
|
||||||
|
glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0);
|
||||||
|
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
if (w < 0 || h < 0) {
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// drawQuad
|
||||||
|
triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
|
||||||
|
glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false,
|
||||||
|
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
|
||||||
|
|
||||||
|
triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
|
||||||
|
glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false,
|
||||||
|
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
|
||||||
|
throw new RuntimeException("Cannot swap buffers");
|
||||||
|
}
|
||||||
|
checkEglError();
|
||||||
|
|
||||||
|
finishGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
private FloatBuffer createMesh(int left, int top, float right, float bottom) {
|
||||||
|
final float[] verticesData = {
|
||||||
|
// X, Y, Z, U, V
|
||||||
|
left, bottom, 0.0f, 0.0f, 1.0f,
|
||||||
|
right, bottom, 0.0f, 1.0f, 1.0f,
|
||||||
|
left, top, 0.0f, 0.0f, 0.0f,
|
||||||
|
right, top, 0.0f, 1.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
final int bytes = verticesData.length * FLOAT_SIZE_BYTES;
|
||||||
|
final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order(
|
||||||
|
ByteOrder.nativeOrder()).asFloatBuffer();
|
||||||
|
triangleVertices.put(verticesData).position(0);
|
||||||
|
return triangleVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int loadTexture(Bitmap bitmap) {
|
||||||
|
int[] textures = new int[1];
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glGenTextures(1, textures, 0);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
int texture = textures[0];
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
bitmap.recycle();
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int buildProgram(String vertex, String fragment) {
|
||||||
|
int vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
|
||||||
|
if (vertexShader == 0) return 0;
|
||||||
|
|
||||||
|
int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
|
||||||
|
if (fragmentShader == 0) return 0;
|
||||||
|
|
||||||
|
int program = glCreateProgram();
|
||||||
|
glAttachShader(program, vertexShader);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
glAttachShader(program, fragmentShader);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
glLinkProgram(program);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
int[] status = new int[1];
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, status, 0);
|
||||||
|
if (status[0] != GL_TRUE) {
|
||||||
|
String error = glGetProgramInfoLog(program);
|
||||||
|
Log.d(GL_LOG_TAG, "Error while linking program:\n" + error);
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
glDeleteProgram(program);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int buildShader(String source, int type) {
|
||||||
|
int shader = glCreateShader(type);
|
||||||
|
|
||||||
|
glShaderSource(shader, source);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
glCompileShader(shader);
|
||||||
|
checkGlError();
|
||||||
|
|
||||||
|
int[] status = new int[1];
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0);
|
||||||
|
if (status[0] != GL_TRUE) {
|
||||||
|
String error = glGetShaderInfoLog(shader);
|
||||||
|
Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error);
|
||||||
|
glDeleteShader(shader);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkEglError() {
|
||||||
|
int error = mEgl.eglGetError();
|
||||||
|
if (error != EGL_SUCCESS) {
|
||||||
|
Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkGlError() {
|
||||||
|
int error = glGetError();
|
||||||
|
if (error != GL_NO_ERROR) {
|
||||||
|
Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishGL() {
|
||||||
|
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
|
||||||
|
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initGL(SurfaceHolder surfaceHolder) {
|
||||||
|
mEgl = (EGL10) EGLContext.getEGL();
|
||||||
|
|
||||||
|
mEglDisplay = mEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
if (mEglDisplay == EGL_NO_DISPLAY) {
|
||||||
|
throw new RuntimeException("eglGetDisplay failed " +
|
||||||
|
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] version = new int[2];
|
||||||
|
if (!mEgl.eglInitialize(mEglDisplay, version)) {
|
||||||
|
throw new RuntimeException("eglInitialize failed " +
|
||||||
|
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mEglConfig = chooseEglConfig();
|
||||||
|
if (mEglConfig == null) {
|
||||||
|
throw new RuntimeException("eglConfig not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
|
||||||
|
|
||||||
|
mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null);
|
||||||
|
|
||||||
|
if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
|
||||||
|
int error = mEgl.eglGetError();
|
||||||
|
if (error == EGL_BAD_NATIVE_WINDOW) {
|
||||||
|
Log.e(GL_LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("createWindowSurface failed " +
|
||||||
|
GLUtils.getEGLErrorString(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||||
|
throw new RuntimeException("eglMakeCurrent failed " +
|
||||||
|
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
mGL = mEglContext.getGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
|
||||||
|
int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
|
||||||
|
return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EGLConfig chooseEglConfig() {
|
||||||
|
int[] configsCount = new int[1];
|
||||||
|
EGLConfig[] configs = new EGLConfig[1];
|
||||||
|
int[] configSpec = getConfig();
|
||||||
|
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
|
||||||
|
throw new IllegalArgumentException("eglChooseConfig failed " +
|
||||||
|
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
|
} else if (configsCount[0] > 0) {
|
||||||
|
return configs[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] getConfig() {
|
||||||
|
return new int[] {
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 0,
|
||||||
|
EGL_DEPTH_SIZE, 0,
|
||||||
|
EGL_STENCIL_SIZE, 0,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
|
|||||||
static final String TAG = "WallpaperService";
|
static final String TAG = "WallpaperService";
|
||||||
static final boolean DEBUG = false;
|
static final boolean DEBUG = false;
|
||||||
|
|
||||||
Object mLock = new Object();
|
final Object mLock = new Object[0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum time between crashes of a wallpaper service for us to consider
|
* Minimum time between crashes of a wallpaper service for us to consider
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import javax.microedition.khronos.egl.EGL10;
|
import javax.microedition.khronos.egl.EGL10;
|
||||||
import javax.microedition.khronos.egl.EGL11;
|
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.egl.EGLContext;
|
import javax.microedition.khronos.egl.EGLContext;
|
||||||
import javax.microedition.khronos.egl.EGLDisplay;
|
import javax.microedition.khronos.egl.EGLDisplay;
|
||||||
@@ -207,7 +206,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
|||||||
glEnableVertexAttribArray(attribTexCoords);
|
glEnableVertexAttribArray(attribTexCoords);
|
||||||
checkGlError();
|
checkGlError();
|
||||||
|
|
||||||
glUniform1i(texture, 0);
|
glUniform1i(uniformTexture, texture);
|
||||||
checkGlError();
|
checkGlError();
|
||||||
|
|
||||||
while (!mFinished) {
|
while (!mFinished) {
|
||||||
@@ -350,7 +349,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
|||||||
!mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
|
!mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
|
||||||
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||||
throw new RuntimeException("eglMakeCurrent failed "
|
throw new RuntimeException("eglMakeCurrent failed "
|
||||||
+ getEGLErrorString(mEgl.eglGetError()));
|
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,13 +360,13 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
|||||||
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||||
if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
|
if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
|
||||||
throw new RuntimeException("eglGetDisplay failed "
|
throw new RuntimeException("eglGetDisplay failed "
|
||||||
+ getEGLErrorString(mEgl.eglGetError()));
|
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] version = new int[2];
|
int[] version = new int[2];
|
||||||
if (!mEgl.eglInitialize(mEglDisplay, version)) {
|
if (!mEgl.eglInitialize(mEglDisplay, version)) {
|
||||||
throw new RuntimeException("eglInitialize failed " +
|
throw new RuntimeException("eglInitialize failed " +
|
||||||
getEGLErrorString(mEgl.eglGetError()));
|
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
mEglConfig = chooseEglConfig();
|
mEglConfig = chooseEglConfig();
|
||||||
@@ -386,12 +385,12 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("createWindowSurface failed "
|
throw new RuntimeException("createWindowSurface failed "
|
||||||
+ getEGLErrorString(error));
|
+ GLUtils.getEGLErrorString(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
|
||||||
throw new RuntimeException("eglMakeCurrent failed "
|
throw new RuntimeException("eglMakeCurrent failed "
|
||||||
+ getEGLErrorString(mEgl.eglGetError()));
|
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
mGL = mEglContext.getGL();
|
mGL = mEglContext.getGL();
|
||||||
@@ -409,7 +408,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
|||||||
int[] configSpec = getConfig();
|
int[] configSpec = getConfig();
|
||||||
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
|
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
|
||||||
throw new IllegalArgumentException("eglChooseConfig failed " +
|
throw new IllegalArgumentException("eglChooseConfig failed " +
|
||||||
getEGLErrorString(mEgl.eglGetError()));
|
GLUtils.getEGLErrorString(mEgl.eglGetError()));
|
||||||
} else if (configsCount[0] > 0) {
|
} else if (configsCount[0] > 0) {
|
||||||
return configs[0];
|
return configs[0];
|
||||||
}
|
}
|
||||||
@@ -429,43 +428,6 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getEGLErrorString(int error) {
|
|
||||||
switch (error) {
|
|
||||||
case EGL10.EGL_SUCCESS:
|
|
||||||
return "EGL_SUCCESS";
|
|
||||||
case EGL10.EGL_NOT_INITIALIZED:
|
|
||||||
return "EGL_NOT_INITIALIZED";
|
|
||||||
case EGL10.EGL_BAD_ACCESS:
|
|
||||||
return "EGL_BAD_ACCESS";
|
|
||||||
case EGL10.EGL_BAD_ALLOC:
|
|
||||||
return "EGL_BAD_ALLOC";
|
|
||||||
case EGL10.EGL_BAD_ATTRIBUTE:
|
|
||||||
return "EGL_BAD_ATTRIBUTE";
|
|
||||||
case EGL10.EGL_BAD_CONFIG:
|
|
||||||
return "EGL_BAD_CONFIG";
|
|
||||||
case EGL10.EGL_BAD_CONTEXT:
|
|
||||||
return "EGL_BAD_CONTEXT";
|
|
||||||
case EGL10.EGL_BAD_CURRENT_SURFACE:
|
|
||||||
return "EGL_BAD_CURRENT_SURFACE";
|
|
||||||
case EGL10.EGL_BAD_DISPLAY:
|
|
||||||
return "EGL_BAD_DISPLAY";
|
|
||||||
case EGL10.EGL_BAD_MATCH:
|
|
||||||
return "EGL_BAD_MATCH";
|
|
||||||
case EGL10.EGL_BAD_NATIVE_PIXMAP:
|
|
||||||
return "EGL_BAD_NATIVE_PIXMAP";
|
|
||||||
case EGL10.EGL_BAD_NATIVE_WINDOW:
|
|
||||||
return "EGL_BAD_NATIVE_WINDOW";
|
|
||||||
case EGL10.EGL_BAD_PARAMETER:
|
|
||||||
return "EGL_BAD_PARAMETER";
|
|
||||||
case EGL10.EGL_BAD_SURFACE:
|
|
||||||
return "EGL_BAD_SURFACE";
|
|
||||||
case EGL11.EGL_CONTEXT_LOST:
|
|
||||||
return "EGL_CONTEXT_LOST";
|
|
||||||
default:
|
|
||||||
return "0x" + Integer.toHexString(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
mFinished = true;
|
mFinished = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user