diff options
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); |