Skip to content

Commit e65beaa

Browse files
committed
Fix rotation displays frame N-1 briefly while rotating
The ScreenShot layer is now created hidden. The screenshot itself is aquired during the transaction when the layer is made visible. This guarantees the screenshot and the layer happen atomically with respect to screen updates. Bug: 5534521 Change-Id: Ida23e1f13d5716ec83b78a15712e0646d6cf8729
1 parent 515c6b4 commit e65beaa

File tree

5 files changed

+54
-10
lines changed

5 files changed

+54
-10
lines changed

services/java/com/android/server/wm/ScreenRotationAnimation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,14 @@ public ScreenRotationAnimation(Context context, SurfaceSession session,
8888
try {
8989
try {
9090
mSurface = new Surface(session, 0, "FreezeSurface",
91-
-1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT);
91+
-1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
9292
if (mSurface == null || !mSurface.isValid()) {
9393
// Screenshot failed, punt.
9494
mSurface = null;
9595
return;
9696
}
9797
mSurface.setLayer(FREEZE_LAYER + 1);
98+
mSurface.show();
9899
} catch (Surface.OutOfResourcesException e) {
99100
Slog.w(TAG, "Unable to allocate freeze surface", e);
100101
}

services/surfaceflinger/LayerScreenshot.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "SurfaceFlinger.h"
2828
#include "DisplayHardware/DisplayHardware.h"
2929

30+
3031
namespace android {
3132
// ---------------------------------------------------------------------------
3233

@@ -45,23 +46,64 @@ LayerScreenshot::~LayerScreenshot()
4546
}
4647
}
4748

49+
status_t LayerScreenshot::captureLocked() {
50+
GLfloat u, v;
51+
status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v);
52+
if (result != NO_ERROR) {
53+
return result;
54+
}
55+
initTexture(u, v);
56+
return NO_ERROR;
57+
}
58+
4859
status_t LayerScreenshot::capture() {
4960
GLfloat u, v;
5061
status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
5162
if (result != NO_ERROR) {
5263
return result;
5364
}
65+
initTexture(u, v);
66+
return NO_ERROR;
67+
}
5468

69+
void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
5570
glBindTexture(GL_TEXTURE_2D, mTextureName);
5671
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5772
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
58-
5973
mTexCoords[0] = 0; mTexCoords[1] = v;
6074
mTexCoords[2] = 0; mTexCoords[3] = 0;
6175
mTexCoords[4] = u; mTexCoords[5] = 0;
6276
mTexCoords[6] = u; mTexCoords[7] = v;
77+
}
6378

64-
return NO_ERROR;
79+
void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
80+
LayerBaseClient::initStates(w, h, flags);
81+
if (!(flags & ISurfaceComposer::eHidden)) {
82+
capture();
83+
}
84+
}
85+
86+
uint32_t LayerScreenshot::doTransaction(uint32_t flags)
87+
{
88+
const Layer::State& draw(drawingState());
89+
const Layer::State& curr(currentState());
90+
91+
if (draw.flags & ISurfaceComposer::eLayerHidden) {
92+
if (!(curr.flags & ISurfaceComposer::eLayerHidden)) {
93+
// we're going from hidden to visible
94+
status_t err = captureLocked();
95+
if (err != NO_ERROR) {
96+
LOGW("createScreenshotSurface failed (%s)", strerror(-err));
97+
}
98+
}
99+
} else if (curr.flags & ISurfaceComposer::eLayerHidden) {
100+
// we're going from visible to hidden
101+
if (mTextureName) {
102+
glDeleteTextures(1, &mTextureName);
103+
mTextureName = 0;
104+
}
105+
}
106+
return LayerBaseClient::doTransaction(flags);
65107
}
66108

67109
void LayerScreenshot::onDraw(const Region& clip) const

services/surfaceflinger/LayerScreenshot.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,18 @@ class LayerScreenshot : public LayerBaseClient
4141

4242
status_t capture();
4343

44+
virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
45+
virtual uint32_t doTransaction(uint32_t flags);
4446
virtual void onDraw(const Region& clip) const;
4547
virtual bool isOpaque() const { return false; }
4648
virtual bool isSecure() const { return false; }
4749
virtual bool isProtectedByApp() const { return false; }
4850
virtual bool isProtectedByDRM() const { return false; }
4951
virtual const char* getTypeId() const { return "LayerScreenshot"; }
52+
53+
private:
54+
status_t captureLocked();
55+
void initTexture(GLfloat u, GLfloat v);
5056
};
5157

5258
// ---------------------------------------------------------------------------

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,11 +1360,6 @@ sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
13601360
uint32_t w, uint32_t h, uint32_t flags)
13611361
{
13621362
sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
1363-
status_t err = layer->capture();
1364-
if (err != NO_ERROR) {
1365-
layer.clear();
1366-
LOGW("createScreenshotSurface failed (%s)", strerror(-err));
1367-
}
13681363
return layer;
13691364
}
13701365

services/surfaceflinger/SurfaceFlinger.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class SurfaceFlinger :
186186

187187
status_t renderScreenToTexture(DisplayID dpy,
188188
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
189+
status_t renderScreenToTextureLocked(DisplayID dpy,
190+
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
189191

190192
status_t postMessageAsync(const sp<MessageBase>& msg,
191193
nsecs_t reltime=0, uint32_t flags = 0);
@@ -328,8 +330,6 @@ class SurfaceFlinger :
328330
status_t turnElectronBeamOnImplLocked(int32_t mode);
329331
status_t electronBeamOffAnimationImplLocked();
330332
status_t electronBeamOnAnimationImplLocked();
331-
status_t renderScreenToTextureLocked(DisplayID dpy,
332-
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
333333

334334
void debugFlashRegions();
335335
void debugShowFPS() const;

0 commit comments

Comments
 (0)