am b867b1f6: Merge "Avoid unnecessarily redrawing the wallpaper." into honeycomb
* commit 'b867b1f6a2854e271223bddb2e39d594bdb493b6': Avoid unnecessarily redrawing the wallpaper.
This commit is contained in:
@@ -41,6 +41,9 @@ import android.content.BroadcastReceiver;
|
|||||||
* Default built-in wallpaper that simply shows a static image.
|
* Default built-in wallpaper that simply shows a static image.
|
||||||
*/
|
*/
|
||||||
public class ImageWallpaper extends WallpaperService {
|
public class ImageWallpaper extends WallpaperService {
|
||||||
|
private static final String TAG = "ImageWallpaper";
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
WallpaperManager mWallpaperManager;
|
WallpaperManager mWallpaperManager;
|
||||||
private HandlerThread mThread;
|
private HandlerThread mThread;
|
||||||
|
|
||||||
@@ -77,10 +80,19 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
float mXOffset;
|
float mXOffset;
|
||||||
float mYOffset;
|
float mYOffset;
|
||||||
|
|
||||||
|
boolean mVisible = true;
|
||||||
|
boolean mRedrawNeeded;
|
||||||
|
boolean mOffsetsChanged;
|
||||||
|
int mLastXTranslation;
|
||||||
|
int mLastYTranslation;
|
||||||
|
|
||||||
class WallpaperObserver extends BroadcastReceiver {
|
class WallpaperObserver extends BroadcastReceiver {
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
updateWallpaper();
|
synchronized (mLock) {
|
||||||
drawFrame();
|
updateWallpaperLocked();
|
||||||
|
drawFrameLocked(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Assume we are the only one using the wallpaper in this
|
// Assume we are the only one using the wallpaper in this
|
||||||
// process, and force a GC now to release the old wallpaper.
|
// process, and force a GC now to release the old wallpaper.
|
||||||
System.gc();
|
System.gc();
|
||||||
@@ -93,7 +105,10 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
|
IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
|
||||||
mReceiver = new WallpaperObserver();
|
mReceiver = new WallpaperObserver();
|
||||||
registerReceiver(mReceiver, filter);
|
registerReceiver(mReceiver, filter);
|
||||||
updateWallpaper();
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
updateWallpaperLocked();
|
||||||
|
}
|
||||||
surfaceHolder.setSizeFromLayout();
|
surfaceHolder.setSizeFromLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,9 +120,12 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onVisibilityChanged(boolean visible) {
|
public void onVisibilityChanged(boolean visible) {
|
||||||
drawFrame();
|
synchronized (mLock) {
|
||||||
|
mVisible = visible;
|
||||||
|
drawFrameLocked(false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public void onTouchEvent(MotionEvent event) {
|
||||||
super.onTouchEvent(event);
|
super.onTouchEvent(event);
|
||||||
@@ -117,15 +135,27 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
public void onOffsetsChanged(float xOffset, float yOffset,
|
public void onOffsetsChanged(float xOffset, float yOffset,
|
||||||
float xOffsetStep, float yOffsetStep,
|
float xOffsetStep, float yOffsetStep,
|
||||||
int xPixels, int yPixels) {
|
int xPixels, int yPixels) {
|
||||||
mXOffset = xOffset;
|
synchronized (mLock) {
|
||||||
mYOffset = yOffset;
|
if (mXOffset != xOffset || mYOffset != yOffset) {
|
||||||
drawFrame();
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ").");
|
||||||
|
}
|
||||||
|
mXOffset = xOffset;
|
||||||
|
mYOffset = yOffset;
|
||||||
|
drawFrameLocked(false, true);
|
||||||
|
} else {
|
||||||
|
drawFrameLocked(false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
super.onSurfaceChanged(holder, format, width, height);
|
super.onSurfaceChanged(holder, format, width, height);
|
||||||
drawFrame();
|
|
||||||
|
synchronized (mLock) {
|
||||||
|
drawFrameLocked(true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,13 +167,30 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
public void onSurfaceDestroyed(SurfaceHolder holder) {
|
public void onSurfaceDestroyed(SurfaceHolder holder) {
|
||||||
super.onSurfaceDestroyed(holder);
|
super.onSurfaceDestroyed(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFrame() {
|
void drawFrameLocked(boolean redrawNeeded, boolean offsetsChanged) {
|
||||||
|
mRedrawNeeded |= redrawNeeded;
|
||||||
|
mOffsetsChanged |= offsetsChanged;
|
||||||
|
|
||||||
|
if (!mVisible) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!mRedrawNeeded && !mOffsetsChanged) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
|
||||||
|
+ "and offsets have not changed.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceHolder sh = getSurfaceHolder();
|
SurfaceHolder sh = getSurfaceHolder();
|
||||||
Canvas c = sh.lockCanvas();
|
Canvas c = sh.lockCanvas();
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
final Rect frame = sh.getSurfaceFrame();
|
try {
|
||||||
synchronized (mLock) {
|
final Rect frame = sh.getSurfaceFrame();
|
||||||
final Drawable background = mBackground;
|
final Drawable background = mBackground;
|
||||||
final int dw = frame.width();
|
final int dw = frame.width();
|
||||||
final int dh = frame.height();
|
final int dh = frame.height();
|
||||||
@@ -154,8 +201,22 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
int xPixels = availw < 0 ? (int)(availw*mXOffset+.5f) : (availw/2);
|
int xPixels = availw < 0 ? (int)(availw*mXOffset+.5f) : (availw/2);
|
||||||
int yPixels = availh < 0 ? (int)(availh*mYOffset+.5f) : (availh/2);
|
int yPixels = availh < 0 ? (int)(availh*mYOffset+.5f) : (availh/2);
|
||||||
|
|
||||||
|
mOffsetsChanged = false;
|
||||||
|
if (!mRedrawNeeded) {
|
||||||
|
if (xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Suppressed drawFrame since the image has not "
|
||||||
|
+ "actually moved an integral number of pixels.");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mRedrawNeeded = false;
|
||||||
|
mLastXTranslation = xPixels;
|
||||||
|
mLastYTranslation = yPixels;
|
||||||
|
|
||||||
c.translate(xPixels, yPixels);
|
c.translate(xPixels, yPixels);
|
||||||
if (availw<0 || availh<0) {
|
if (availw < 0 || availh < 0) {
|
||||||
c.save(Canvas.CLIP_SAVE_FLAG);
|
c.save(Canvas.CLIP_SAVE_FLAG);
|
||||||
c.clipRect(0, 0, bw, bh, Op.DIFFERENCE);
|
c.clipRect(0, 0, bw, bh, Op.DIFFERENCE);
|
||||||
c.drawColor(0xff000000);
|
c.drawColor(0xff000000);
|
||||||
@@ -164,35 +225,35 @@ public class ImageWallpaper extends WallpaperService {
|
|||||||
if (background != null) {
|
if (background != null) {
|
||||||
background.draw(c);
|
background.draw(c);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
sh.unlockCanvasAndPost(c);
|
||||||
}
|
}
|
||||||
sh.unlockCanvasAndPost(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateWallpaper() {
|
void updateWallpaperLocked() {
|
||||||
synchronized (mLock) {
|
Throwable exception = null;
|
||||||
Throwable exception = null;
|
try {
|
||||||
|
mBackground = mWallpaperManager.getFastDrawable();
|
||||||
|
} 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
|
||||||
|
// be loaded, we will go into a cycle. Don't do a build where the
|
||||||
|
// default wallpaper can't be loaded.
|
||||||
|
Log.w(TAG, "Unable to load wallpaper!", exception);
|
||||||
try {
|
try {
|
||||||
mBackground = mWallpaperManager.getFastDrawable();
|
mWallpaperManager.clear();
|
||||||
} catch (RuntimeException e) {
|
} catch (IOException ex) {
|
||||||
exception = e;
|
// now we're really screwed.
|
||||||
} catch (OutOfMemoryError e) {
|
Log.w(TAG, "Unable reset to default wallpaper!", ex);
|
||||||
exception = e;
|
|
||||||
}
|
|
||||||
if (exception != null) {
|
|
||||||
mBackground = null;
|
|
||||||
// Note that if we do fail at this, and the default wallpaper can't
|
|
||||||
// be loaded, we will go into a cycle. Don't do a build where the
|
|
||||||
// default wallpaper can't be loaded.
|
|
||||||
Log.w("ImageWallpaper", "Unable to load wallpaper!", exception);
|
|
||||||
try {
|
|
||||||
mWallpaperManager.clear();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// now we're really screwed.
|
|
||||||
Log.w("ImageWallpaper", "Unable reset to default wallpaper!", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mRedrawNeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user