summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/WallpaperManager.java66
-rw-r--r--core/java/android/view/HardwareRenderer.java60
-rw-r--r--opengl/java/android/opengl/GLUtils.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java393
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java2
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java52
7 files changed, 454 insertions, 169 deletions
diff --git a/api/current.txt b/api/current.txt
index 8a643fd..e432436 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13947,6 +13947,7 @@ package android.opengl {
}
public final class GLUtils {
+ method public static java.lang.String getEGLErrorString(int);
method public static int getInternalFormat(android.graphics.Bitmap);
method public static int getType(android.graphics.Bitmap);
method public static void texImage2D(int, int, int, android.graphics.Bitmap, int);
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index ff04757..f81ea81 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -107,19 +107,22 @@ public class WallpaperManager {
private final int mHeight;
private int mDrawLeft;
private int mDrawTop;
+ private final Paint mPaint;
private FastBitmapDrawable(Bitmap bitmap) {
mBitmap = bitmap;
mWidth = bitmap.getWidth();
mHeight = bitmap.getHeight();
+
setBounds(0, 0, mWidth, mHeight);
+
+ mPaint = new Paint();
+ mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
}
@Override
public void draw(Canvas canvas) {
- Paint paint = new Paint();
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, paint);
+ canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, mPaint);
}
@Override
@@ -134,33 +137,23 @@ public class WallpaperManager {
}
@Override
- public void setBounds(Rect bounds) {
- // TODO Auto-generated method stub
- super.setBounds(bounds);
- }
-
- @Override
public void setAlpha(int alpha) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
public void setColorFilter(ColorFilter cf) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
public void setDither(boolean dither) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
public void setFilterBitmap(boolean filter) {
- throw new UnsupportedOperationException(
- "Not supported with this drawable");
+ throw new UnsupportedOperationException("Not supported with this drawable");
}
@Override
@@ -230,7 +223,7 @@ public class WallpaperManager {
}
mWallpaper = null;
try {
- mWallpaper = getCurrentWallpaperLocked(context);
+ mWallpaper = getCurrentWallpaperLocked();
} catch (OutOfMemoryError 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 {
Bundle params = new Bundle();
ParcelFileDescriptor fd = mService.getWallpaper(this, params);
@@ -265,17 +258,19 @@ public class WallpaperManager {
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, options);
- return generateBitmap(context, bm, width, height);
+ return generateBitmap(bm, width, height);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode file", e);
} finally {
try {
fd.close();
} catch (IOException e) {
+ // Ignore
}
}
}
} catch (RemoteException e) {
+ // Ignore
}
return null;
}
@@ -291,27 +286,29 @@ public class WallpaperManager {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeStream(is, null, options);
- return generateBitmap(context, bm, width, height);
+ return generateBitmap(bm, width, height);
} catch (OutOfMemoryError e) {
Log.w(TAG, "Can't decode stream", e);
} finally {
try {
is.close();
} catch (IOException e) {
+ // Ignore
}
}
}
} catch (RemoteException e) {
+ // Ignore
}
return null;
}
}
- private static Object mSync = new Object();
+ private static final Object sSync = new Object[0];
private static Globals sGlobals;
static void initGlobals(Looper looper) {
- synchronized (mSync) {
+ synchronized (sSync) {
if (sGlobals == null) {
sGlobals = new Globals(looper);
}
@@ -390,8 +387,7 @@ public class WallpaperManager {
public Drawable getFastDrawable() {
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
if (bm != null) {
- Drawable dr = new FastBitmapDrawable(bm);
- return dr;
+ return new FastBitmapDrawable(bm);
}
return null;
}
@@ -406,13 +402,21 @@ public class WallpaperManager {
public Drawable peekFastDrawable() {
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
if (bm != null) {
- Drawable dr = new FastBitmapDrawable(bm);
- return dr;
+ return new FastBitmapDrawable(bm);
}
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
* for apps that want to reduce memory usage when they only temporarily
* need to have the wallpaper. After calling, the next request for the
@@ -464,6 +468,7 @@ public class WallpaperManager {
}
}
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -493,6 +498,7 @@ public class WallpaperManager {
}
}
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -524,6 +530,7 @@ public class WallpaperManager {
}
}
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -594,6 +601,7 @@ public class WallpaperManager {
try {
sGlobals.mService.setDimensionHints(minimumWidth, minimumHeight);
} catch (RemoteException e) {
+ // Ignore
}
}
@@ -690,7 +698,7 @@ public class WallpaperManager {
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) {
return null;
}
@@ -717,7 +725,7 @@ public class WallpaperManager {
if (deltaw > 0 || deltah > 0) {
// We need to scale up so it covers the entire area.
- float scale = 1.0f;
+ float scale;
if (deltaw > deltah) {
scale = width / (float)targetRect.right;
} else {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index a05637d..926d424 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -21,6 +21,7 @@ import android.content.ComponentCallbacks2;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
+import android.opengl.GLUtils;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
@@ -402,51 +403,6 @@ public abstract class HardwareRenderer {
}
/**
- * 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)}
* is invoked and the requested flag is turned off. The error code is
* also logged as a warning.
@@ -458,7 +414,7 @@ public abstract class HardwareRenderer {
// something bad has happened revert to
// normal rendering.
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) {
throw new RuntimeException("eglGetDisplay failed "
- + getEGLErrorString(sEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
// We can now initialize EGL for that display
int[] version = new int[2];
if (!sEgl.eglInitialize(sEglDisplay, version)) {
throw new RuntimeException("eglInitialize failed " +
- getEGLErrorString(sEgl.eglGetError()));
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
sEglConfig = chooseEglConfig();
@@ -579,7 +535,7 @@ public abstract class HardwareRenderer {
if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
throw new IllegalArgumentException("eglChooseConfig failed " +
- getEGLErrorString(sEgl.eglGetError()));
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
} else if (configsCount[0] > 0) {
if ("choice".equalsIgnoreCase(debug)) {
printConfig(configs[0]);
@@ -647,7 +603,7 @@ public abstract class HardwareRenderer {
*/
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
throw new Surface.OutOfResourcesException("eglMakeCurrent failed "
- + getEGLErrorString(sEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
// If mDirtyRegions is set, this means we have an EGL configuration
@@ -734,7 +690,7 @@ public abstract class HardwareRenderer {
return false;
}
throw new RuntimeException("createWindowSurface failed "
- + getEGLErrorString(error));
+ + GLUtils.getEGLErrorString(error));
}
return true;
}
@@ -856,7 +812,7 @@ public abstract class HardwareRenderer {
if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
fallback(true);
Log.e(LOG_TAG, "eglMakeCurrent failed " +
- getEGLErrorString(sEgl.eglGetError()));
+ GLUtils.getEGLErrorString(sEgl.eglGetError()));
return SURFACE_STATE_ERROR;
} else {
return SURFACE_STATE_UPDATED;
diff --git a/opengl/java/android/opengl/GLUtils.java b/opengl/java/android/opengl/GLUtils.java
index f30a4cd..125c56e 100644
--- a/opengl/java/android/opengl/GLUtils.java
+++ b/opengl/java/android/opengl/GLUtils.java
@@ -16,9 +16,11 @@
package android.opengl;
-import javax.microedition.khronos.opengles.GL10;
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.
@@ -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 int native_getInternalFormat(Bitmap bitmap);
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index e1231a5..5a3850d 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -16,41 +16,65 @@
package com.android.systemui;
-import java.io.IOException;
-
+import android.app.ActivityManager;
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.Rect;
import android.graphics.Region.Op;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
+import android.opengl.GLUtils;
+import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
-import android.util.Slog;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.content.Intent;
-import android.content.BroadcastReceiver;
+import android.view.WindowManager;
+
+import javax.microedition.khronos.egl.EGL10;
+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.
*/
+@SuppressWarnings({"UnusedDeclaration"})
public class ImageWallpaper extends WallpaperService {
private static final String TAG = "ImageWallpaper";
+ private static final String GL_LOG_TAG = "ImageWallpaperGL";
private static final boolean DEBUG = false;
static final boolean FIXED_SIZED_SURFACE = true;
+ static final boolean USE_OPENGL = false;
WallpaperManager mWallpaperManager;
- private Handler mHandler;
+
+ boolean mIsHwAccelerated;
@Override
public void onCreate() {
super.onCreate();
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() {
@@ -58,9 +82,16 @@ public class ImageWallpaper extends WallpaperService {
}
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;
- Drawable mBackground;
+
+ Bitmap mBackground;
int mBackgroundWidth = -1, mBackgroundHeight = -1;
float mXOffset;
float mYOffset;
@@ -71,6 +102,35 @@ public class ImageWallpaper extends WallpaperService {
int mLastXTranslation;
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 {
public void onReceive(Context context, Intent intent) {
if (DEBUG) {
@@ -94,7 +154,7 @@ public class ImageWallpaper extends WallpaperService {
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.
//IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
//mReceiver = new WallpaperObserver();
@@ -221,8 +281,7 @@ public class ImageWallpaper extends WallpaperService {
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
mOffsetsChanged = false;
- if (!mRedrawNeeded
- && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
+ if (!mRedrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since the image has not "
+ "actually moved an integral number of pixels.");
@@ -240,27 +299,10 @@ public class ImageWallpaper extends WallpaperService {
updateWallpaperLocked();
}
- //Slog.i(TAG, "************** DRAWING WALLAPER ******************");
- Canvas c = sh.lockCanvas();
- if (c != null) {
- try {
- 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 (mIsHwAccelerated) {
+ drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels);
+ } else {
+ drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
}
if (FIXED_SIZED_SURFACE) {
@@ -274,15 +316,15 @@ public class ImageWallpaper extends WallpaperService {
}
void updateWallpaperLocked() {
- //Slog.i(TAG, "************** LOADING WALLAPER ******************");
Throwable exception = null;
try {
- mBackground = mWallpaperManager.getFastDrawable();
+ mBackground = mWallpaperManager.getBitmap();
} catch (RuntimeException e) {
exception = e;
} catch (OutOfMemoryError e) {
exception = e;
}
+
if (exception != null) {
mBackground = null;
// 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);
}
}
- 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
+ };
}
}
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 9765f2a..565063a 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -75,7 +75,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperService";
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
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
index e77178d..3232eed 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java
@@ -33,7 +33,6 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
@@ -207,7 +206,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
glEnableVertexAttribArray(attribTexCoords);
checkGlError();
- glUniform1i(texture, 0);
+ glUniform1i(uniformTexture, texture);
checkGlError();
while (!mFinished) {
@@ -350,7 +349,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
!mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
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);
if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
throw new RuntimeException("eglGetDisplay failed "
- + getEGLErrorString(mEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
int[] version = new int[2];
if (!mEgl.eglInitialize(mEglDisplay, version)) {
throw new RuntimeException("eglInitialize failed " +
- getEGLErrorString(mEgl.eglGetError()));
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
mEglConfig = chooseEglConfig();
@@ -386,12 +385,12 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
return;
}
throw new RuntimeException("createWindowSurface failed "
- + getEGLErrorString(error));
+ + GLUtils.getEGLErrorString(error));
}
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
throw new RuntimeException("eglMakeCurrent failed "
- + getEGLErrorString(mEgl.eglGetError()));
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
}
mGL = mEglContext.getGL();
@@ -409,7 +408,7 @@ public class GLTextureViewActivity extends Activity implements TextureView.Surfa
int[] configSpec = getConfig();
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
throw new IllegalArgumentException("eglChooseConfig failed " +
- getEGLErrorString(mEgl.eglGetError()));
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
} else if (configsCount[0] > 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() {
mFinished = true;
}