summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathias Agopian <mathias@google.com> 2011-11-01 14:39:06 -0700
committer Mathias Agopian <mathias@google.com> 2011-11-04 15:15:32 -0700
commite65beaabe4be554683417839594dd41b6c979cbb (patch)
treebc792e170282d06c470f56d311fc085b9296dc10
parent515c6b44d57b829792267594a355cd2831582197 (diff)
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
-rw-r--r--services/java/com/android/server/wm/ScreenRotationAnimation.java3
-rw-r--r--services/surfaceflinger/LayerScreenshot.cpp46
-rw-r--r--services/surfaceflinger/LayerScreenshot.h6
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h4
5 files changed, 54 insertions, 10 deletions
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 131f11c19fbd..8fc9a70faad9 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -88,13 +88,14 @@ class ScreenRotationAnimation {
try {
try {
mSurface = new Surface(session, 0, "FreezeSurface",
- -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT);
+ -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
if (mSurface == null || !mSurface.isValid()) {
// Screenshot failed, punt.
mSurface = null;
return;
}
mSurface.setLayer(FREEZE_LAYER + 1);
+ mSurface.show();
} catch (Surface.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);
}
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index e30ccbf6bfbb..68e66606ed1f 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -27,6 +27,7 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
+
namespace android {
// ---------------------------------------------------------------------------
@@ -45,23 +46,64 @@ LayerScreenshot::~LayerScreenshot()
}
}
+status_t LayerScreenshot::captureLocked() {
+ GLfloat u, v;
+ status_t result = mFlinger->renderScreenToTextureLocked(0, &mTextureName, &u, &v);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ initTexture(u, v);
+ return NO_ERROR;
+}
+
status_t LayerScreenshot::capture() {
GLfloat u, v;
status_t result = mFlinger->renderScreenToTexture(0, &mTextureName, &u, &v);
if (result != NO_ERROR) {
return result;
}
+ initTexture(u, v);
+ return NO_ERROR;
+}
+void LayerScreenshot::initTexture(GLfloat u, GLfloat v) {
glBindTexture(GL_TEXTURE_2D, mTextureName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
mTexCoords[0] = 0; mTexCoords[1] = v;
mTexCoords[2] = 0; mTexCoords[3] = 0;
mTexCoords[4] = u; mTexCoords[5] = 0;
mTexCoords[6] = u; mTexCoords[7] = v;
+}
- return NO_ERROR;
+void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) {
+ LayerBaseClient::initStates(w, h, flags);
+ if (!(flags & ISurfaceComposer::eHidden)) {
+ capture();
+ }
+}
+
+uint32_t LayerScreenshot::doTransaction(uint32_t flags)
+{
+ const Layer::State& draw(drawingState());
+ const Layer::State& curr(currentState());
+
+ if (draw.flags & ISurfaceComposer::eLayerHidden) {
+ if (!(curr.flags & ISurfaceComposer::eLayerHidden)) {
+ // we're going from hidden to visible
+ status_t err = captureLocked();
+ if (err != NO_ERROR) {
+ LOGW("createScreenshotSurface failed (%s)", strerror(-err));
+ }
+ }
+ } else if (curr.flags & ISurfaceComposer::eLayerHidden) {
+ // we're going from visible to hidden
+ if (mTextureName) {
+ glDeleteTextures(1, &mTextureName);
+ mTextureName = 0;
+ }
+ }
+ return LayerBaseClient::doTransaction(flags);
}
void LayerScreenshot::onDraw(const Region& clip) const
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
index e3a2b1975215..ab9004741fca 100644
--- a/services/surfaceflinger/LayerScreenshot.h
+++ b/services/surfaceflinger/LayerScreenshot.h
@@ -41,12 +41,18 @@ public:
status_t capture();
+ virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+ virtual uint32_t doTransaction(uint32_t flags);
virtual void onDraw(const Region& clip) const;
virtual bool isOpaque() const { return false; }
virtual bool isSecure() const { return false; }
virtual bool isProtectedByApp() const { return false; }
virtual bool isProtectedByDRM() const { return false; }
virtual const char* getTypeId() const { return "LayerScreenshot"; }
+
+private:
+ status_t captureLocked();
+ void initTexture(GLfloat u, GLfloat v);
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a6d4147c1952..8f4fdb8fed5c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1360,11 +1360,6 @@ sp<LayerScreenshot> SurfaceFlinger::createScreenshotSurface(
uint32_t w, uint32_t h, uint32_t flags)
{
sp<LayerScreenshot> layer = new LayerScreenshot(this, display, client);
- status_t err = layer->capture();
- if (err != NO_ERROR) {
- layer.clear();
- LOGW("createScreenshotSurface failed (%s)", strerror(-err));
- }
return layer;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ea5bfa718f32..17028dbb64fa 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -186,6 +186,8 @@ public:
status_t renderScreenToTexture(DisplayID dpy,
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
+ status_t renderScreenToTextureLocked(DisplayID dpy,
+ GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
status_t postMessageAsync(const sp<MessageBase>& msg,
nsecs_t reltime=0, uint32_t flags = 0);
@@ -328,8 +330,6 @@ private:
status_t turnElectronBeamOnImplLocked(int32_t mode);
status_t electronBeamOffAnimationImplLocked();
status_t electronBeamOnAnimationImplLocked();
- status_t renderScreenToTextureLocked(DisplayID dpy,
- GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
void debugFlashRegions();
void debugShowFPS() const;