3131import android .renderscript .Matrix4f ;
3232import android .service .wallpaper .WallpaperService ;
3333import android .util .Log ;
34+ import android .view .Display ;
3435import android .view .MotionEvent ;
3536import android .view .SurfaceHolder ;
37+ import android .view .WindowManager ;
3638
3739import javax .microedition .khronos .egl .EGL10 ;
3840import javax .microedition .khronos .egl .EGLConfig ;
@@ -108,6 +110,7 @@ class DrawableEngine extends Engine {
108110
109111 Bitmap mBackground ;
110112 int mBackgroundWidth = -1 , mBackgroundHeight = -1 ;
113+ int mLastRotation = -1 ;
111114 float mXOffset ;
112115 float mYOffset ;
113116
@@ -156,7 +159,7 @@ public void onReceive(Context context, Intent intent) {
156159 mBackgroundWidth = mBackgroundHeight = -1 ;
157160 mBackground = null ;
158161 mRedrawNeeded = true ;
159- drawFrameLocked (false );
162+ drawFrameLocked ();
160163 }
161164 }
162165 }
@@ -225,7 +228,7 @@ void updateSurfaceSize(SurfaceHolder surfaceHolder) {
225228 @ Override
226229 public void onVisibilityChanged (boolean visible ) {
227230 if (DEBUG ) {
228- Log .d (TAG , "onVisibilityChanged: visible=" + visible );
231+ Log .d (TAG , "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible );
229232 }
230233
231234 synchronized (mLock ) {
@@ -234,7 +237,7 @@ public void onVisibilityChanged(boolean visible) {
234237 Log .d (TAG , "Visibility changed to visible=" + visible );
235238 }
236239 mVisible = visible ;
237- drawFrameLocked (false );
240+ drawFrameLocked ();
238241 }
239242 }
240243 }
@@ -263,7 +266,7 @@ public void onOffsetsChanged(float xOffset, float yOffset,
263266 mYOffset = yOffset ;
264267 mOffsetsChanged = true ;
265268 }
266- drawFrameLocked (false );
269+ drawFrameLocked ();
267270 }
268271 }
269272
@@ -276,80 +279,81 @@ public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int he
276279 super .onSurfaceChanged (holder , format , width , height );
277280
278281 synchronized (mLock ) {
279- mRedrawNeeded = true ;
280- mBackgroundWidth = mBackgroundHeight = -1 ;
281- drawFrameLocked (true );
282+ drawFrameLocked ();
282283 }
283284 }
284285
286+ @ Override
287+ public void onSurfaceDestroyed (SurfaceHolder holder ) {
288+ super .onSurfaceDestroyed (holder );
289+ mBackgroundWidth = mBackgroundHeight = -1 ;
290+ }
291+
292+ @ Override
293+ public void onSurfaceCreated (SurfaceHolder holder ) {
294+ super .onSurfaceCreated (holder );
295+ mBackgroundWidth = mBackgroundHeight = -1 ;
296+ }
297+
285298 @ Override
286299 public void onSurfaceRedrawNeeded (SurfaceHolder holder ) {
287300 if (DEBUG ) {
288- Log .d (TAG , "onSurfaceRedrawNeeded: " );
301+ Log .d (TAG , "onSurfaceRedrawNeeded" );
289302 }
290303 super .onSurfaceRedrawNeeded (holder );
291304
292305 synchronized (mLock ) {
293- mRedrawNeeded = true ;
294- drawFrameLocked (false );
306+ drawFrameLocked ();
295307 }
296308 }
297309
298- void drawFrameLocked (boolean force ) {
299- if (! force ) {
300- if (! mVisible ) {
301- if ( DEBUG ) {
302- Log . d ( TAG , "Suppressed drawFrame since wallpaper is not visible." );
303- }
304- return ;
305- }
306- if (! mRedrawNeeded && ! mOffsetsChanged ) {
307- if ( DEBUG ) {
308- Log . d ( TAG , "Suppressed drawFrame since redraw is not needed "
309- + "and offsets have not changed." );
310- }
311- return ;
310+ void drawFrameLocked () {
311+ SurfaceHolder sh = getSurfaceHolder ();
312+ final Rect frame = sh . getSurfaceFrame ();
313+ final int dw = frame . width ();
314+ final int dh = frame . height ( );
315+ int newRotation = (( WindowManager ) getSystemService ( WINDOW_SERVICE )).
316+ getDefaultDisplay (). getRotation () ;
317+
318+ boolean redrawNeeded = dw != mBackgroundWidth || dh != mBackgroundHeight ||
319+ newRotation != mLastRotation ;
320+ if (! redrawNeeded && ! mOffsetsChanged ) {
321+ if ( DEBUG ) {
322+ Log . d ( TAG , "Suppressed drawFrame since redraw is not needed "
323+ + "and offsets have not changed." ) ;
312324 }
325+ return ;
313326 }
314- // If we don't yet know the size of the wallpaper bitmap,
315- // we need to get it now.
316- boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ;
317-
318- // If we somehow got to this point after we have last flushed
319- // the wallpaper, well we really need it to draw again. So
320- // seems like we need to reload it. Ouch.
321- updateWallpaper = updateWallpaper || mBackground == null ;
327+ mLastRotation = newRotation ;
322328
323- if (updateWallpaper ) {
329+ // Load bitmap if it is not yet loaded or if it was loaded at a different size
330+ if (mBackground == null || dw != mBackgroundWidth || dw != mBackgroundHeight ) {
331+ if (DEBUG ) {
332+ Log .d (TAG , "Reloading bitmap" );
333+ }
334+ mWallpaperManager .forgetLoadedWallpaper ();
324335 updateWallpaperLocked ();
325336 }
326337
327- SurfaceHolder sh = getSurfaceHolder ();
328- final Rect frame = sh .getSurfaceFrame ();
329- final int dw = frame .width ();
330- final int dh = frame .height ();
331338 final int availw = dw - mBackgroundWidth ;
332339 final int availh = dh - mBackgroundHeight ;
333340 int xPixels = availw < 0 ? (int )(availw * mXOffset + .5f ) : (availw / 2 );
334341 int yPixels = availh < 0 ? (int )(availh * mYOffset + .5f ) : (availh / 2 );
335342
336343 mOffsetsChanged = false ;
337- if (!force && !mRedrawNeeded
338- && xPixels == mLastXTranslation && yPixels == mLastYTranslation ) {
344+ mRedrawNeeded = false ;
345+ mLastXTranslation = xPixels ;
346+ mLastYTranslation = yPixels ;
347+ if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation ) {
339348 if (DEBUG ) {
340349 Log .d (TAG , "Suppressed drawFrame since the image has not "
341350 + "actually moved an integral number of pixels." );
342351 }
343352 return ;
344353 }
345- mRedrawNeeded = false ;
346- mLastXTranslation = xPixels ;
347- mLastYTranslation = yPixels ;
348354
349355 if (DEBUG ) {
350- Log .d (TAG , "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x"
351- + mBackgroundHeight + " SurfaceFrame=" + frame .toShortString ()
352- + " X,YOffset=" + mXOffset + "," + mYOffset );
356+ Log .d (TAG , "Redrawing wallpaper" );
353357 }
354358 if (mIsHwAccelerated ) {
355359 if (!drawWallpaperWithOpenGL (sh , availw , availh , xPixels , yPixels )) {
@@ -429,15 +433,14 @@ private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left
429433 final float bottom = top + mBackgroundHeight ;
430434
431435 final Rect frame = sh .getSurfaceFrame ();
432-
433436 final Matrix4f ortho = new Matrix4f ();
434437 ortho .loadOrtho (0.0f , frame .width (), frame .height (), 0.0f , -1.0f , 1.0f );
435438
436439 final FloatBuffer triangleVertices = createMesh (left , top , right , bottom );
437440
438441 final int texture = loadTexture (mBackground );
439442 final int program = buildProgram (sSimpleVS , sSimpleFS );
440-
443+
441444 final int attribPosition = glGetAttribLocation (program , "position" );
442445 final int attribTexCoords = glGetAttribLocation (program , "texCoords" );
443446 final int uniformTexture = glGetUniformLocation (program , "texture" );
@@ -460,7 +463,7 @@ private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left
460463 glClearColor (0.0f , 0.0f , 0.0f , 0.0f );
461464 glClear (GL_COLOR_BUFFER_BIT );
462465 }
463-
466+
464467 // drawQuad
465468 triangleVertices .position (TRIANGLE_VERTICES_DATA_POS_OFFSET );
466469 glVertexAttribPointer (attribPosition , 3 , GL_FLOAT , false ,
@@ -471,12 +474,12 @@ private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left
471474 TRIANGLE_VERTICES_DATA_STRIDE_BYTES , triangleVertices );
472475
473476 glDrawArrays (GL_TRIANGLE_STRIP , 0 , 4 );
474-
477+
475478 if (!mEgl .eglSwapBuffers (mEglDisplay , mEglSurface )) {
476479 throw new RuntimeException ("Cannot swap buffers" );
477480 }
478481 checkEglError ();
479-
482+
480483 finishGL ();
481484
482485 return true ;
0 commit comments