summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/dumpstate/dumpstate.c11
-rw-r--r--include/gui/SurfaceComposerClient.h1
-rw-r--r--include/private/gui/LayerState.h4
-rw-r--r--libs/gui/BufferQueueProducer.cpp4
-rw-r--r--libs/gui/LayerState.cpp4
-rw-r--r--libs/gui/Sensor.cpp136
-rw-r--r--libs/gui/SurfaceComposerClient.cpp14
-rw-r--r--opengl/libs/EGL/eglApi.cpp9
-rw-r--r--services/surfaceflinger/Android.mk2
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp34
-rw-r--r--services/surfaceflinger/DisplayDevice.h10
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplaySurface.h2
-rw-r--r--services/surfaceflinger/DisplayHardware/FramebufferSurface.h4
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp14
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp42
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h9
-rw-r--r--services/surfaceflinger/Layer.h5
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.cpp4
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp104
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
21 files changed, 293 insertions, 126 deletions
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index d2f99df..342dc89 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -205,9 +205,6 @@ static void dumpstate() {
dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
- dump_file("NETWORK ROUTES", "/proc/net/route");
- dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
-
if (!stat(PSTORE_LAST_KMSG, &st)) {
/* Also TODO: Make console-ramoops CAP_SYSLOG protected. */
dump_file("LAST KMSG", PSTORE_LAST_KMSG);
@@ -223,12 +220,18 @@ static void dumpstate() {
/* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
+
+ run_command("IPv4 ADDRESSES", 10, "ip", "-4", "addr", "show", NULL);
+ run_command("IPv6 ADDRESSES", 10, "ip", "-6", "addr", "show", NULL);
+
run_command("IP RULES", 10, "ip", "rule", "show", NULL);
run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
dump_route_tables();
- dump_file("ARP CACHE", "/proc/net/arp");
+ run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL);
+ run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL);
+
run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 65313df..c73ef70 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -146,6 +146,7 @@ public:
const sp<IGraphicBufferProducer>& bufferProducer);
static void setDisplayLayerStack(const sp<IBinder>& token,
uint32_t layerStack);
+ static void setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height);
/* setDisplayProjection() defines the projection of layer stacks
* to a given display.
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 5584fb1..2fa6ff9 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -113,7 +113,8 @@ struct DisplayState {
enum {
eSurfaceChanged = 0x01,
eLayerStackChanged = 0x02,
- eDisplayProjectionChanged = 0x04
+ eDisplayProjectionChanged = 0x04,
+ eDisplaySizeChanged = 0x08
};
uint32_t what;
@@ -123,6 +124,7 @@ struct DisplayState {
uint32_t orientation;
Rect viewport;
Rect frame;
+ uint32_t width, height;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index a53775f..cbca3ac 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -830,8 +830,8 @@ status_t BufferQueueProducer::disconnect(int api) {
mCore->mSidebandStream.clear();
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
- } else {
- BQ_LOGE("disconnect(P): connected to another API "
+ } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("disconnect(P): still connected to another API "
"(cur=%d req=%d)", mCore->mConnectedApi, api);
status = BAD_VALUE;
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index acdbd77..e95d8b6 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -81,6 +81,8 @@ status_t DisplayState::write(Parcel& output) const {
output.writeInt32(orientation);
output.write(viewport);
output.write(frame);
+ output.writeInt32(width);
+ output.writeInt32(height);
return NO_ERROR;
}
@@ -92,6 +94,8 @@ status_t DisplayState::read(const Parcel& input) {
orientation = input.readInt32();
input.read(viewport);
input.read(frame);
+ width = input.readInt32();
+ height = input.readInt32();
return NO_ERROR;
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 2103a95..bae05a8 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -80,6 +80,10 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
}
// Ensure existing sensors have correct string type, required permissions and reporting mode.
+ // Set reportingMode for all android defined sensor types, set wake-up flag only for proximity
+ // sensor, significant motion, tilt, pick_up gesture, wake gesture and glance gesture on older
+ // HALs. Newer HALs can define both wake-up and non wake-up proximity sensors.
+ // All the OEM defined defined sensors have flags set to whatever is provided by the HAL.
switch (mType) {
case SENSOR_TYPE_ACCELEROMETER:
mStringType = SENSOR_STRING_TYPE_ACCELEROMETER;
@@ -140,7 +144,10 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
break;
case SENSOR_TYPE_PROXIMITY:
mStringType = SENSOR_STRING_TYPE_PROXIMITY;
- mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
break;
case SENSOR_TYPE_RELATIVE_HUMIDITY:
mStringType = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
@@ -152,7 +159,10 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
break;
case SENSOR_TYPE_SIGNIFICANT_MOTION:
mStringType = SENSOR_STRING_TYPE_SIGNIFICANT_MOTION;
- mFlags |= (SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP);
+ mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
break;
case SENSOR_TYPE_STEP_COUNTER:
mStringType = SENSOR_STRING_TYPE_STEP_COUNTER;
@@ -166,94 +176,33 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
mStringType = SENSOR_STRING_TYPE_TEMPERATURE;
mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
- case SENSOR_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR:
- mStringType = SENSOR_STRING_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR;
- mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
- break;
- case SENSOR_TYPE_WAKE_UP_ACCELEROMETER:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_ACCELEROMETER;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_MAGNETIC_FIELD;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_ORIENTATION:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_ORIENTATION;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_GYROSCOPE:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_GYROSCOPE;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_LIGHT:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_LIGHT;
- mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_PRESSURE:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_PRESSURE;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_GRAVITY:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_GRAVITY;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_LINEAR_ACCELERATION:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_LINEAR_ACCELERATION;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_ROTATION_VECTOR:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_ROTATION_VECTOR;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_RELATIVE_HUMIDITY:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_RELATIVE_HUMIDITY;
- mFlags |= (SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_AMBIENT_TEMPERATURE:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_AMBIENT_TEMPERATURE;
- mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_GAME_ROTATION_VECTOR:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_GAME_ROTATION_VECTOR;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_STEP_DETECTOR:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_STEP_DETECTOR;
- mFlags |= (SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_STEP_COUNTER:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_STEP_COUNTER;
- mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR;
- mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_HEART_RATE:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_HEART_RATE;
- mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
- mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
- break;
- case SENSOR_TYPE_WAKE_UP_TILT_DETECTOR:
- mStringType = SENSOR_STRING_TYPE_WAKE_UP_TILT_DETECTOR;
- mFlags |= (SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP);
- break;
+ case SENSOR_TYPE_TILT_DETECTOR:
+ mStringType = SENSOR_STRING_TYPE_TILT_DETECTOR;
+ mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
+ break;
case SENSOR_TYPE_WAKE_GESTURE:
mStringType = SENSOR_STRING_TYPE_WAKE_GESTURE;
- mFlags |= (SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP);
+ mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
break;
case SENSOR_TYPE_GLANCE_GESTURE:
mStringType = SENSOR_STRING_TYPE_GLANCE_GESTURE;
- mFlags |= (SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP);
+ mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
+ break;
+ case SENSOR_TYPE_PICK_UP_GESTURE:
+ mStringType = SENSOR_STRING_TYPE_PICK_UP_GESTURE;
+ mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
break;
default:
// Only pipe the stringType, requiredPermission and flags for custom sensors.
@@ -279,6 +228,23 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
}
break;
}
+
+ // For the newer HALs log errors if reporting mask flags are set incorrectly.
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+ // Wake-up flag is set here.
+ mFlags |= (hwSensor->flags & SENSOR_FLAG_WAKE_UP);
+ if (mFlags != hwSensor->flags) {
+ int actualReportingMode =
+ (hwSensor->flags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
+ int expectedReportingMode = (mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT;
+ if (actualReportingMode != expectedReportingMode) {
+ ALOGE("Reporting Mode incorrect: sensor %s handle=%d type=%d "
+ "actual=%d expected=%d",
+ mName.string(), mHandle, mType, actualReportingMode, expectedReportingMode);
+ }
+
+ }
+ }
}
Sensor::~Sensor()
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 3bee3fc..6e13207 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -166,6 +166,7 @@ public:
uint32_t orientation,
const Rect& layerStackRect,
const Rect& displayRect);
+ void setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height);
static void setAnimationTransaction() {
Composer::getInstance().setAnimationTransactionImpl();
@@ -426,6 +427,14 @@ void Composer::setDisplayProjection(const sp<IBinder>& token,
mForceSynchronous = true; // TODO: do we actually still need this?
}
+void Composer::setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height) {
+ Mutex::Autolock _l(mLock);
+ DisplayState& s(getDisplayStateLocked(token));
+ s.width = width;
+ s.height = height;
+ s.what |= DisplayState::eDisplaySizeChanged;
+}
+
// ---------------------------------------------------------------------------
SurfaceComposerClient::SurfaceComposerClient()
@@ -621,6 +630,11 @@ void SurfaceComposerClient::setDisplayProjection(const sp<IBinder>& token,
layerStackRect, displayRect);
}
+void SurfaceComposerClient::setDisplaySize(const sp<IBinder>& token,
+ uint32_t width, uint32_t height) {
+ Composer::getInstance().setDisplaySize(token, width, height);
+}
+
// ----------------------------------------------------------------------------
status_t SurfaceComposerClient::getDisplayConfigs(
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 6e77e45..99c01b7 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -572,6 +572,15 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t * const s = get_surface(surface);
+ ANativeWindow* window = s->win.get();
+ if (window) {
+ int result = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+ if (result != OK) {
+ ALOGE("eglDestroySurface: native_window_api_disconnect (win=%p) "
+ "failed (%#x)",
+ window, result);
+ }
+ }
EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
if (result == EGL_TRUE) {
_s.terminate();
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index f279491..183478d 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -83,7 +83,7 @@ else
LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
endif
-LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
LOCAL_CFLAGS += -std=c++11
LOCAL_SHARED_LIBRARIES := \
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 71377ed..2213259 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -72,7 +72,8 @@ DisplayDevice::DisplayDevice(
mSecureLayerVisible(false),
mLayerStack(NO_LAYER_STACK),
mOrientation(),
- mPowerMode(HWC_POWER_MODE_OFF)
+ mPowerMode(HWC_POWER_MODE_OFF),
+ mActiveConfig(0)
{
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
@@ -101,6 +102,7 @@ DisplayDevice::DisplayDevice(
if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
window->setSwapInterval(window, 0);
+ mConfig = config;
mDisplay = display;
mSurface = surface;
mFormat = format;
@@ -336,6 +338,15 @@ bool DisplayDevice::isDisplayOn() const {
}
// ----------------------------------------------------------------------------
+void DisplayDevice::setActiveConfig(int mode) {
+ mActiveConfig = mode;
+}
+
+int DisplayDevice::getActiveConfig() const {
+ return mActiveConfig;
+}
+
+// ----------------------------------------------------------------------------
void DisplayDevice::setLayerStack(uint32_t stack) {
mLayerStack = stack;
@@ -387,6 +398,22 @@ status_t DisplayDevice::orientationToTransfrom(
return NO_ERROR;
}
+void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
+ dirtyRegion.set(getBounds());
+
+ mDisplaySurface->resizeBuffers(newWidth, newHeight);
+
+ ANativeWindow* const window = mNativeWindow.get();
+ mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
+ eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth);
+ eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
+
+ LOG_FATAL_IF(mDisplayWidth != newWidth,
+ "Unable to set new width to %d", newWidth);
+ LOG_FATAL_IF(mDisplayHeight != newHeight,
+ "Unable to set new height to %d", newHeight);
+}
+
void DisplayDevice::setProjection(int orientation,
const Rect& newViewport, const Rect& newFrame) {
Rect viewport(newViewport);
@@ -461,13 +488,14 @@ void DisplayDevice::dump(String8& result) const {
result.appendFormat(
"+ DisplayDevice: %s\n"
" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
- "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, numLayers=%zu\n"
+ "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
mDisplayName.string(), mType, mHwcDisplayId,
mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
mOrientation, tr.getType(), getPageFlipCount(),
- mIsSecure, mSecureLayerVisible, mPowerMode, mVisibleLayersSortedByZ.size(),
+ mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig,
+ mVisibleLayersSortedByZ.size(),
mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 4c8ef02..00e0918 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -109,6 +109,7 @@ public:
Region getDirtyRegion(bool repaintEverything) const;
void setLayerStack(uint32_t stack);
+ void setDisplaySize(const int newWidth, const int newHeight);
void setProjection(int orientation, const Rect& viewport, const Rect& frame);
int getOrientation() const { return mOrientation; }
@@ -153,6 +154,12 @@ public:
void setPowerMode(int mode);
bool isDisplayOn() const;
+ /* ------------------------------------------------------------------------
+ * Display active config management.
+ */
+ int getActiveConfig() const;
+ void setActiveConfig(int mode);
+
// release HWC resources (if any) for removable displays
void disconnect(HWComposer& hwc);
@@ -175,6 +182,7 @@ private:
sp<ANativeWindow> mNativeWindow;
sp<DisplaySurface> mDisplaySurface;
+ EGLConfig mConfig;
EGLDisplay mDisplay;
EGLSurface mSurface;
int mDisplayWidth;
@@ -215,6 +223,8 @@ private:
bool mNeedsFiltering;
// Current power mode
int mPowerMode;
+ // Current active config
+ int mActiveConfig;
};
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
index 1db3eb8..e60c4fb 100644
--- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -72,6 +72,8 @@ public:
virtual void dump(String8& result) const = 0;
+ virtual void resizeBuffers(const uint32_t w, const uint32_t h) = 0;
+
protected:
DisplaySurface() {}
virtual ~DisplaySurface() {}
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index ba72ce3..d0bf22b 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -49,6 +49,10 @@ public:
// has a non-virtual dump() with the same signature.
virtual void dump(String8& result) const;
+ // Cannot resize a buffers in a FramebufferSurface. Only works with virtual
+ // displays.
+ virtual void resizeBuffers(const uint32_t /*w*/, const uint32_t /*h*/) { };
+
private:
virtual ~FramebufferSurface() { }; // this class cannot be overloaded
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index a8fb5bd..6769031 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -288,7 +288,7 @@ void HWComposer::vsync(int disp, int64_t timestamp) {
// is a bug in the HWC implementation, but filter the extra events
// out here so they don't cause havoc downstream.
if (timestamp == mLastHwVSync[disp]) {
- ALOGW("Ignoring duplicate VSYNC event from HWC (t=%lld)",
+ ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
timestamp);
return;
}
@@ -631,7 +631,7 @@ status_t HWComposer::prepare() {
disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
}
if (!disp.connected && disp.list != NULL) {
- ALOGW("WARNING: disp %d: connected, non-null list, layers=%d",
+ ALOGW("WARNING: disp %zu: connected, non-null list, layers=%zu",
i, disp.list->numHwLayers);
}
mLists[i] = disp.list;
@@ -778,6 +778,16 @@ status_t HWComposer::setPowerMode(int disp, int mode) {
return NO_ERROR;
}
+status_t HWComposer::setActiveConfig(int disp, int mode) {
+ LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
+ if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
+ return (status_t)mHwc->setActiveConfig(mHwc, disp, mode);
+ } else {
+ LOG_FATAL_IF(mode != 0);
+ }
+ return NO_ERROR;
+}
+
void HWComposer::disconnectDisplay(int disp) {
LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
DisplayData& dd(mDisplayData[disp]);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 9bd99eb..5cb56a0 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -100,6 +100,9 @@ public:
// set power mode
status_t setPowerMode(int disp, int mode);
+ // set active config
+ status_t setActiveConfig(int disp, int mode);
+
// reset state when an external, non-virtual display is disconnected
void disconnectDisplay(int disp);
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index ad7cd25..c3d45ee 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -68,6 +68,8 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
int sinkWidth, sinkHeight;
sink->query(NATIVE_WINDOW_WIDTH, &sinkWidth);
sink->query(NATIVE_WINDOW_HEIGHT, &sinkHeight);
+ mSinkBufferWidth = sinkWidth;
+ mSinkBufferHeight = sinkHeight;
// Pick the buffer format to request from the sink when not rendering to it
// with GLES. If the consumer needs CPU access, use the default format
@@ -104,10 +106,6 @@ status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
"Unexpected beginFrame() in %s state", dbgStateStr());
mDbgState = DBG_STATE_BEGUN;
- uint32_t transformHint, numPendingBuffers;
- mQueueBufferOutput.deflate(&mSinkBufferWidth, &mSinkBufferHeight,
- &transformHint, &numPendingBuffers);
-
return refreshOutputBuffer();
}
@@ -259,8 +257,20 @@ void VirtualDisplaySurface::onFrameCommitted() {
void VirtualDisplaySurface::dump(String8& /* result */) const {
}
+void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) {
+ uint32_t tmpW, tmpH, transformHint, numPendingBuffers;
+ mQueueBufferOutput.deflate(&tmpW, &tmpH, &transformHint, &numPendingBuffers);
+ mQueueBufferOutput.inflate(w, h, transformHint, numPendingBuffers);
+
+ mSinkBufferWidth = w;
+ mSinkBufferHeight = h;
+}
+
status_t VirtualDisplaySurface::requestBuffer(int pslot,
sp<GraphicBuffer>* outBuf) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
"Unexpected requestBuffer pslot=%d in %s state",
pslot, dbgStateStr());
@@ -275,6 +285,7 @@ status_t VirtualDisplaySurface::setBufferCount(int bufferCount) {
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
uint32_t format, uint32_t usage, int* sslot, sp<Fence>* fence) {
+ LOG_FATAL_IF(mDisplayId < 0, "mDisplayId=%d but should not be < 0.", mDisplayId);
// Don't let a slow consumer block us
bool async = (source == SOURCE_SINK);
@@ -319,6 +330,9 @@ status_t VirtualDisplaySurface::dequeueBuffer(Source source,
status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool async,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, async, w, h, format, usage);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED,
"Unexpected dequeueBuffer() in %s state", dbgStateStr());
mDbgState = DBG_STATE_GLES;
@@ -399,6 +413,9 @@ status_t VirtualDisplaySurface::attachBuffer(int* /* outSlot */,
status_t VirtualDisplaySurface::queueBuffer(int pslot,
const QueueBufferInput& input, QueueBufferOutput* output) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
"Unexpected queueBuffer(pslot=%d) in %s state", pslot,
dbgStateStr());
@@ -452,6 +469,9 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot,
}
void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) {
+ if (mDisplayId < 0)
+ return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
+
VDS_LOGW_IF(mDbgState != DBG_STATE_GLES,
"Unexpected cancelBuffer(pslot=%d) in %s state", pslot,
dbgStateStr());
@@ -462,7 +482,17 @@ void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) {
}
int VirtualDisplaySurface::query(int what, int* value) {
- return mSource[SOURCE_SINK]->query(what, value);
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ *value = mSinkBufferWidth;
+ break;
+ case NATIVE_WINDOW_HEIGHT:
+ *value = mSinkBufferHeight;
+ break;
+ default:
+ return mSource[SOURCE_SINK]->query(what, value);
+ }
+ return NO_ERROR;
}
status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener,
@@ -501,8 +531,6 @@ void VirtualDisplaySurface::updateQueueBufferOutput(
void VirtualDisplaySurface::resetPerFrameState() {
mCompositionType = COMPOSITION_UNKNOWN;
- mSinkBufferWidth = 0;
- mSinkBufferHeight = 0;
mFbFence = Fence::NO_FENCE;
mOutputFence = Fence::NO_FENCE;
mOutputProducerSlot = -1;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 5c00ab4..363dce2 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -87,6 +87,7 @@ public:
virtual status_t advanceFrame();
virtual void onFrameCommitted();
virtual void dump(String8& result) const;
+ virtual void resizeBuffers(const uint32_t w, const uint32_t h);
private:
enum Source {SOURCE_SINK = 0, SOURCE_SCRATCH = 1};
@@ -168,6 +169,10 @@ private:
// to the sink, we have to return the previous version.
QueueBufferOutput mQueueBufferOutput;
+ // Details of the current sink buffer. These become valid when a buffer is
+ // dequeued from the sink, and are used when queueing the buffer.
+ uint32_t mSinkBufferWidth, mSinkBufferHeight;
+
//
// Intra-frame state
//
@@ -176,10 +181,6 @@ private:
// Valid after prepareFrame(), cleared in onFrameCommitted.
CompositionType mCompositionType;
- // Details of the current sink buffer. These become valid when a buffer is
- // dequeued from the sink, and are used when queueing the buffer.
- uint32_t mSinkBufferWidth, mSinkBufferHeight;
-
// mFbFence is the fence HWC should wait for before reading the framebuffer
// target buffer.
sp<Fence> mFbFence;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e21dd36..e712523 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -281,6 +281,11 @@ public:
*/
Rect getContentCrop() const;
+ /*
+ * Returns if a frame is queued.
+ */
+ bool hasQueuedFrame() const { return mQueuedFrames > 0; }
+
// -----------------------------------------------------------------------
void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 2871ce9..d5d5da8 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -139,8 +139,8 @@ RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
ALOGI("renderer : %s", extensions.getRenderer());
ALOGI("version : %s", extensions.getVersion());
ALOGI("extensions: %s", extensions.getExtension());
- ALOGI("GL_MAX_TEXTURE_SIZE = %d", engine->getMaxTextureSize());
- ALOGI("GL_MAX_VIEWPORT_DIMS = %d", engine->getMaxViewportDims());
+ ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());
+ ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(display, dummy);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 53b0dc4..bbe2aa1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -603,11 +603,61 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
return NO_ERROR;
}
-int SurfaceFlinger::getActiveConfig(const sp<IBinder>&) {
- return 0;
+int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
+ return getDisplayDevice(display)->getActiveConfig();
}
-status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>&, int) {
+void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode) {
+ ALOGD("Set active config mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
+ this);
+ int32_t type = hw->getDisplayType();
+ int currentMode = hw->getActiveConfig();
+
+ if (mode == currentMode) {
+ ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
+ return;
+ }
+
+ if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ ALOGW("Trying to set config for virtual display");
+ return;
+ }
+
+ hw->setActiveConfig(mode);
+ getHwComposer().setActiveConfig(type, mode);
+}
+
+status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
+ class MessageSetActiveConfig: public MessageBase {
+ SurfaceFlinger& mFlinger;
+ sp<IBinder> mDisplay;
+ int mMode;
+ public:
+ MessageSetActiveConfig(SurfaceFlinger& flinger, const sp<IBinder>& disp,
+ int mode) :
+ mFlinger(flinger), mDisplay(disp) { mMode = mode; }
+ virtual bool handler() {
+ Vector<DisplayInfo> configs;
+ mFlinger.getDisplayConfigs(mDisplay, &configs);
+ if(mMode < 0 || mMode >= configs.size()) {
+ ALOGE("Attempt to set active config = %d for display with %zu configs",
+ mMode, configs.size());
+ }
+ sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
+ if (hw == NULL) {
+ ALOGE("Attempt to set active config = %d for null display %p",
+ mMode, mDisplay.get());
+ } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
+ ALOGW("Attempt to set active config = %d for virtual display",
+ mMode);
+ } else {
+ mFlinger.setActiveConfigInternal(hw, mMode);
+ }
+ return true;
+ }
+ };
+ sp<MessageBase> msg = new MessageSetActiveConfig(*this, display, mode);
+ postMessageSync(msg);
return NO_ERROR;
}
@@ -1214,6 +1264,9 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
disp->setProjection(state.orientation,
state.viewport, state.frame);
}
+ if (state.width != draw[i].width || state.height != draw[i].height) {
+ disp->setDisplaySize(state.width, state.height);
+ }
}
}
}
@@ -1244,13 +1297,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
bqProducer, bqConsumer, state.displayName);
dispSurface = vds;
- if (hwcDisplayId >= 0) {
- producer = vds;
- } else {
- // There won't be any interaction with HWC for this virtual display,
- // so the GLES driver can pass buffers directly to the sink.
- producer = state.surface;
- }
+ producer = vds;
}
} else {
ALOGE_IF(state.surface!=NULL,
@@ -1589,9 +1636,24 @@ void SurfaceFlinger::handlePageFlip()
bool visibleRegions = false;
const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
+
+ // Store the set of layers that need updates. This set must not change as
+ // buffers are being latched, as this could result in a deadlock.
+ // Example: Two producers share the same command stream and:
+ // 1.) Layer 0 is latched
+ // 2.) Layer 0 gets a new frame
+ // 2.) Layer 1 gets a new frame
+ // 3.) Layer 1 is latched.
+ // Display is now waiting on Layer 1's frame, which is behind layer 0's
+ // second frame. But layer 0's second frame could be waiting on display.
+ Vector<Layer*> layersWithQueuedFrames;
+ for (size_t i = 0, count = layers.size(); i<count ; i++) {
const sp<Layer>& layer(layers[i]);
+ if (layer->hasQueuedFrame())
+ layersWithQueuedFrames.push_back(layer.get());
+ }
+ for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
+ Layer* layer = layersWithQueuedFrames[i];
const Region dirty(layer->latchBuffer(visibleRegions));
const Layer::State& s(layer->getDrawingState());
invalidateLayerStack(s.layerStack, dirty);
@@ -1948,6 +2010,16 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
flags |= eDisplayTransactionNeeded;
}
}
+ if (what & DisplayState::eDisplaySizeChanged) {
+ if (disp.width != s.width) {
+ disp.width = s.width;
+ flags |= eDisplayTransactionNeeded;
+ }
+ if (disp.height != s.height) {
+ disp.height = s.height;
+ flags |= eDisplayTransactionNeeded;
+ }
+ }
}
return flags;
}
@@ -2134,6 +2206,8 @@ void SurfaceFlinger::onInitializeDisplays() {
d.orientation = DisplayState::eOrientationDefault;
d.frame.makeInvalid();
d.viewport.makeInvalid();
+ d.width = 0;
+ d.height = 0;
displays.add(d);
setTransactionState(state, displays, 0);
setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
@@ -2214,7 +2288,7 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
if (hw == NULL) {
ALOGE("Attempt to set power mode = %d for null display %p",
- mDisplay.get(), mMode);
+ mMode, mDisplay.get());
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
ALOGW("Attempt to set power mode = %d for virtual display",
mMode);
@@ -3162,11 +3236,11 @@ int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
// ---------------------------------------------------------------------------
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
- : type(DisplayDevice::DISPLAY_ID_INVALID) {
+ : type(DisplayDevice::DISPLAY_ID_INVALID), width(0), height(0) {
}
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
- : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0) {
+ : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0), width(0), height(0) {
viewport.makeInvalid();
frame.makeInvalid();
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 476e549..d5547b3 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -170,6 +170,7 @@ private:
Rect viewport;
Rect frame;
uint8_t orientation;
+ uint32_t width, height;
String8 displayName;
bool isSecure;
};
@@ -239,6 +240,8 @@ private:
// called on the main thread in response to initializeDisplays()
void onInitializeDisplays();
+ // called on the main thread in response to setActiveConfig()
+ void setActiveConfigInternal(const sp<DisplayDevice>& hw, int mode);
// called on the main thread in response to setPowerMode()
void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);