Merge "Fix issue #2461567: Home screen redraw messed up"
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 9808832..0279d84 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -210,9 +210,16 @@
status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
+ void dispatch_setUsage(va_list args);
+ int dispatch_connect(va_list args);
+ int dispatch_disconnect(va_list args);
void setUsage(uint32_t reqUsage);
+ int connect(int api);
+ int disconnect(int api);
+
uint32_t getUsage() const;
+ int getConnectedApi() const;
// constants
sp<SurfaceComposerClient> mClient;
@@ -227,6 +234,7 @@
// protected by mSurfaceLock
Rect mSwapRectangle;
uint32_t mUsage;
+ int mConnected;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 3740db5..773fd93 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -69,7 +69,14 @@
/* valid operations for the (*perform)() hook */
enum {
- NATIVE_WINDOW_SET_USAGE = 0
+ NATIVE_WINDOW_SET_USAGE = 0,
+ NATIVE_WINDOW_CONNECT = 1,
+ NATIVE_WINDOW_DISCONNECT = 2
+};
+
+/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
+enum {
+ NATIVE_WINDOW_API_EGL = 1
};
typedef struct android_native_window_t
@@ -157,8 +164,13 @@
* This hook should not be called directly, instead use the helper functions
* defined below.
*
+ * (*perform)() returns -ENOENT if the 'what' parameter is not supported
+ * by the surface's implementation.
+ *
* The valid operations are:
* NATIVE_WINDOW_SET_USAGE
+ * NATIVE_WINDOW_CONNECT
+ * NATIVE_WINDOW_DISCONNECT
*
*/
@@ -185,6 +197,30 @@
return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
}
+/*
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
+ * by EGL when the window is made current.
+ * Returns -EINVAL if for some reason the window cannot be connected, which
+ * can happen if it's connected to some other API.
+ */
+static inline int native_window_connect(
+ android_native_window_t* window, int api)
+{
+ return window->perform(window, NATIVE_WINDOW_CONNECT, api);
+}
+
+/*
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
+ * by EGL when the window is made not current.
+ * An error is returned if for instance the window wasn't connected in the
+ * first place.
+ */
+static inline int native_window_disconnect(
+ android_native_window_t* window, int api)
+{
+ return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
+}
+
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index fdf6627..140f10c 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -54,7 +54,7 @@
mOrientation(0),
mLeft(0), mTop(0),
mTransactionFlags(0),
- mPremultipliedAlpha(true),
+ mPremultipliedAlpha(true), mDebug(false),
mInvalidate(0)
{
const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
@@ -65,6 +65,14 @@
{
}
+void LayerBase::setName(const String8& name) {
+ mName = name;
+}
+
+String8 LayerBase::getName() const {
+ return mName;
+}
+
const GraphicPlane& LayerBase::graphicPlane(int dpy) const
{
return mFlinger->graphicPlane(dpy);
@@ -698,8 +706,7 @@
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i)
- : LayerBase(flinger, display), lcblk(NULL), client(client),
- mDebug(false), mIndex(i),
+ : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
{
lcblk = new SharedBufferServer(
@@ -724,14 +731,6 @@
delete lcblk;
}
-void LayerBaseClient::setName(const String8& name) {
- mName = name;
-}
-
-String8 LayerBaseClient::getName() const {
- return mName;
-}
-
int32_t LayerBaseClient::serverIndex() const
{
sp<Client> client(this->client.promote());
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 852b9f9..a6e5644 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -101,6 +101,9 @@
Region transparentRegion;
};
+ void setName(const String8& name);
+ String8 getName() const;
+
// modify current state
bool setPosition(int32_t x, int32_t y);
bool setLayer(uint32_t z);
@@ -121,7 +124,7 @@
void drawRegion(const Region& reg) const;
void invalidate();
-
+
/**
* draw - performs some global clipping optimizations
* and calls onDraw().
@@ -287,6 +290,9 @@
// don't change, don't need a lock
bool mPremultipliedAlpha;
+ String8 mName;
+ mutable bool mDebug;
+
// atomic
volatile int32_t mInvalidate;
@@ -320,8 +326,6 @@
const sp<Client>& client, int32_t i);
virtual ~LayerBaseClient();
virtual void onFirstRef();
- void setName(const String8& name);
- String8 getName() const;
const wp<Client> client;
@@ -369,15 +373,11 @@
friend class Surface;
-protected:
- mutable bool mDebug;
-
private:
int32_t mIndex;
mutable Mutex mLock;
mutable wp<Surface> mClientSurface;
// only read
- String8 mName;
const uint32_t mIdentity;
static int32_t sIdentity;
};
diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
index b2d5856..175f989 100644
--- a/libs/surfaceflinger/Transform.cpp
+++ b/libs/surfaceflinger/Transform.cpp
@@ -65,17 +65,14 @@
Transform::~Transform() {
}
-
-bool Transform::absIsOne(float f) {
- return fabs(f) == 1.0f;
-}
+static const float EPSILON = 0.0f;
bool Transform::isZero(float f) {
- return fabs(f) == 0.0f;
+ return fabs(f) <= EPSILON;
}
-bool Transform::absEqual(float a, float b) {
- return fabs(a) == fabs(b);
+bool Transform::absIsOne(float f) {
+ return isZero(fabs(f) - 1.0f);
}
Transform Transform::operator * (const Transform& rhs) const
@@ -154,8 +151,14 @@
mType = UNKNOWN_TYPE;
}
-void Transform::set(uint32_t flags, float w, float h)
+status_t Transform::set(uint32_t flags, float w, float h)
{
+ if (flags & ROT_INVALID) {
+ // that's not allowed!
+ reset();
+ return BAD_VALUE;
+ }
+
mType = flags << 8;
float sx = (flags & FLIP_H) ? -1 : 1;
float sy = (flags & FLIP_V) ? -1 : 1;
@@ -205,6 +208,8 @@
M[0][0] = a; M[1][0] = b; M[2][0] = x;
M[0][1] = c; M[1][1] = d; M[2][1] = y;
M[0][2] = 0; M[1][2] = 0; M[2][2] = 1;
+
+ return NO_ERROR;
}
Transform::vec2 Transform::transform(const vec2& v) const {
@@ -295,25 +300,17 @@
bool scale = false;
uint32_t flags = ROT_0;
if (isZero(b) && isZero(c)) {
- if (absEqual(a, d)) {
- if (a<0) flags |= FLIP_H;
- if (d<0) flags |= FLIP_V;
- if (!absIsOne(a) || !absIsOne(d)) {
- scale = true;
- }
- } else {
- flags = ROT_INVALID;
+ if (a<0) flags |= FLIP_H;
+ if (d<0) flags |= FLIP_V;
+ if (!absIsOne(a) || !absIsOne(d)) {
+ scale = true;
}
} else if (isZero(a) && isZero(d)) {
- if (absEqual(b, c)) {
- flags |= ROT_90;
- if (b>0) flags |= FLIP_H;
- if (c<0) flags |= FLIP_V;
- if (!absIsOne(b) || !absIsOne(c)) {
- scale = true;
- }
- } else {
- flags = ROT_INVALID;
+ flags |= ROT_90;
+ if (b>0) flags |= FLIP_H;
+ if (c<0) flags |= FLIP_V;
+ if (!absIsOne(b) || !absIsOne(c)) {
+ scale = true;
}
} else {
flags = ROT_INVALID;
@@ -361,15 +358,22 @@
const mat33& m(mMatrix);
uint32_t orient = mType >> 8;
- if (orient&ROT_INVALID)
+ if (orient&ROT_INVALID) {
flags.append("ROT_INVALID ");
- if (orient&ROT_90)
- flags.append("ROT_90 ");
- if (orient&FLIP_V)
- flags.append("FLIP_V ");
- if (orient&FLIP_H)
- flags.append("FLIP_H ");
+ } else {
+ if (orient&ROT_90) {
+ flags.append("ROT_90 ");
+ } else {
+ flags.append("ROT_0 ");
+ }
+ if (orient&FLIP_V)
+ flags.append("FLIP_V ");
+ if (orient&FLIP_H)
+ flags.append("FLIP_H ");
+ }
+ if (!(mType&(SCALE|ROTATE|TRANSLATE)))
+ type.append("IDENTITY ");
if (mType&SCALE)
type.append("SCALE ");
if (mType&ROTATE)
@@ -377,10 +381,10 @@
if (mType&TRANSLATE)
type.append("TRANSLATE ");
- LOGD("%s (%s, %s)", name, flags.string(), type.string());
- LOGD("%.2f %.2f %.2f", m[0][0], m[1][0], m[2][0]);
- LOGD("%.2f %.2f %.2f", m[0][1], m[1][1], m[2][1]);
- LOGD("%.2f %.2f %.2f", m[0][2], m[1][2], m[2][2]);
+ LOGD("%s 0x%08x (%s, %s)", name, mType, flags.string(), type.string());
+ LOGD("%.4f %.4f %.4f", m[0][0], m[1][0], m[2][0]);
+ LOGD("%.4f %.4f %.4f", m[0][1], m[1][1], m[2][1]);
+ LOGD("%.4f %.4f %.4f", m[0][2], m[1][2], m[2][2]);
}
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
index 51d3e3f..2e5b893 100644
--- a/libs/surfaceflinger/Transform.h
+++ b/libs/surfaceflinger/Transform.h
@@ -69,10 +69,10 @@
int ty() const;
// modify the transform
- void reset();
- void set(float tx, float ty);
- void set(float a, float b, float c, float d);
- void set(uint32_t flags, float w, float h);
+ void reset();
+ void set(float tx, float ty);
+ void set(float a, float b, float c, float d);
+ status_t set(uint32_t flags, float w, float h);
// transform data
Rect makeBounds(int w, int h) const;
@@ -80,6 +80,9 @@
Region transform(const Region& reg) const;
Transform operator * (const Transform& rhs) const;
+ // for debugging
+ void dump(const char* name) const;
+
private:
struct vec3 {
float v[3];
@@ -113,11 +116,8 @@
Rect transform(const Rect& bounds) const;
uint32_t type() const;
static bool absIsOne(float f);
- static bool absEqual(float a, float b);
static bool isZero(float f);
- void dump(const char* name) const;
-
mat33 mMatrix;
mutable uint32_t mType;
};
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index eb3457b..5dd75c3 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -353,6 +353,7 @@
const_cast<uint32_t&>(android_native_window_t::flags) = 0;
// be default we request a hardware surface
mUsage = GRALLOC_USAGE_HW_RENDER;
+ mConnected = 0;
mNeedFullUpdate = false;
}
@@ -579,28 +580,93 @@
{
int res = NO_ERROR;
switch (operation) {
- case NATIVE_WINDOW_SET_USAGE:
- setUsage( va_arg(args, int) );
- break;
- default:
- res = NAME_NOT_FOUND;
- break;
+ case NATIVE_WINDOW_SET_USAGE:
+ dispatch_setUsage( args );
+ break;
+ case NATIVE_WINDOW_CONNECT:
+ res = dispatch_connect( args );
+ break;
+ case NATIVE_WINDOW_DISCONNECT:
+ res = dispatch_disconnect( args );
+ break;
+ default:
+ res = NAME_NOT_FOUND;
+ break;
}
return res;
}
+void Surface::dispatch_setUsage(va_list args) {
+ int usage = va_arg(args, int);
+ setUsage( usage );
+}
+int Surface::dispatch_connect(va_list args) {
+ int api = va_arg(args, int);
+ return connect( api );
+}
+int Surface::dispatch_disconnect(va_list args) {
+ int api = va_arg(args, int);
+ return disconnect( api );
+}
+
+
void Surface::setUsage(uint32_t reqUsage)
{
Mutex::Autolock _l(mSurfaceLock);
mUsage = reqUsage;
}
+int Surface::connect(int api)
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ int err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ if (mConnected) {
+ err = -EINVAL;
+ } else {
+ mConnected = api;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+int Surface::disconnect(int api)
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ int err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ if (mConnected == api) {
+ mConnected = 0;
+ } else {
+ err = -EINVAL;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
uint32_t Surface::getUsage() const
{
Mutex::Autolock _l(mSurfaceLock);
return mUsage;
}
+int Surface::getConnectedApi() const
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ return mConnected;
+}
+
+
// ----------------------------------------------------------------------------
status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -609,11 +675,20 @@
status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
{
+ if (getConnectedApi()) {
+ LOGE("Surface::lock(%p) failed. Already connected to another API",
+ (android_native_window_t*)this);
+ CallStack stack;
+ stack.update();
+ stack.dump("");
+ return INVALID_OPERATION;
+ }
+
if (mApiLock.tryLock() != NO_ERROR) {
LOGE("calling Surface::lock from different threads!");
CallStack stack;
stack.update();
- stack.dump("Surface::lock called from different threads");
+ stack.dump("");
return WOULD_BLOCK;
}
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 1fa2c68..52380a0 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -250,6 +250,8 @@
{
switch (operation) {
case NATIVE_WINDOW_SET_USAGE:
+ case NATIVE_WINDOW_CONNECT:
+ case NATIVE_WINDOW_DISCONNECT:
break;
default:
return NAME_NOT_FOUND;