Merge changes I2ce11db5,Idba8278b
* changes:
Fix logging implicit sign conversions
Fix libgui warnings
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index ce858d2..08115ea 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -46,8 +46,7 @@
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
#LOCAL_CFLAGS += -DENABLE_FENCE_TRACKING
-USE_HWC2 := false
-ifeq ($(USE_HWC2),true)
+ifeq ($(TARGET_USES_HWC2),true)
LOCAL_CFLAGS += -DUSE_HWC2
LOCAL_SRC_FILES += \
SurfaceFlinger.cpp \
@@ -149,6 +148,10 @@
LOCAL_CFLAGS += -DENABLE_CPUSETS
endif
+ifeq ($(TARGET_USES_HWC2),true)
+ LOCAL_CFLAGS += -DUSE_HWC2
+endif
+
LOCAL_SRC_FILES := \
main_surfaceflinger.cpp
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 2a025b8..3e48cd2 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -43,10 +43,7 @@
{
const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) {
- sp<Layer> layer(mLayers.valueAt(i).promote());
- if (layer != 0) {
- mFlinger->removeLayer(layer);
- }
+ mFlinger->removeLayer(mLayers.valueAt(i));
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index ed8cc08..ae6ba98 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -149,7 +149,12 @@
}
for (auto element : mDisplays) {
- auto display = element.second;
+ auto display = element.second.lock();
+ if (!display) {
+ ALOGE("~Device: Found a display (%" PRId64 " that has already been"
+ " destroyed", element.first);
+ continue;
+ }
DisplayType displayType = HWC2::DisplayType::Invalid;
auto error = display->getType(&displayType);
@@ -208,6 +213,10 @@
ALOGI("Created virtual display");
*format = static_cast<android_pixel_format_t>(intFormat);
*outDisplay = getDisplayById(displayId);
+ if (!*outDisplay) {
+ ALOGE("Failed to get display by id");
+ return Error::BadDisplay;
+ }
(*outDisplay)->setVirtual();
return Error::None;
}
@@ -289,7 +298,10 @@
std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
if (mDisplays.count(id) != 0) {
- return mDisplays.at(id);
+ auto strongDisplay = mDisplays[id].lock();
+ ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
+ " longer alive", id);
+ return strongDisplay;
}
auto display = std::make_shared<Display>(*this, id);
@@ -430,6 +442,7 @@
auto error = static_cast<Error>(intError);
ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
" %s (%d)", display, to_string(error).c_str(), intError);
+ mDisplays.erase(display);
}
// Display methods
@@ -810,6 +823,7 @@
auto handle = buffer->getNativeBuffer()->handle;
int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
fenceFd);
+ close(fenceFd);
return static_cast<Error>(intError);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 1aa4205..25a7d89 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -88,7 +88,8 @@
// Other Device methods
// This will create a Display if one is not found, but it will not be marked
- // as connected
+ // as connected. This Display may be null if the display has been torn down
+ // but has not been removed from the map yet.
std::shared_ptr<Display> getDisplayById(hwc2_display_t id);
bool hasCapability(HWC2::Capability capability) const;
@@ -181,7 +182,7 @@
HWC2_PFN_SET_LAYER_Z_ORDER mSetLayerZOrder;
std::vector<Capability> mCapabilities;
- std::unordered_map<hwc2_display_t, std::shared_ptr<Display>> mDisplays;
+ std::unordered_map<hwc2_display_t, std::weak_ptr<Display>> mDisplays;
HotplugCallback mHotplug;
std::vector<std::pair<std::shared_ptr<Display>, Connection>>
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2629794..216bbc9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -422,6 +422,10 @@
Mutex::Autolock _l(mDisplayLock);
auto displayId = displayDevice.getHwcDisplayId();
+ if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
+ ALOGV("Skipping HWComposer prepare for non-HWC display");
+ return NO_ERROR;
+ }
if (!isValidDisplay(displayId)) {
return BAD_INDEX;
}
@@ -515,6 +519,11 @@
}
bool HWComposer::hasDeviceComposition(int32_t displayId) const {
+ if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
+ // Displays without a corresponding HWC display are never composed by
+ // the device
+ return false;
+ }
if (!isValidDisplay(displayId)) {
ALOGE("hasDeviceComposition: Invalid display %d", displayId);
return false;
@@ -523,6 +532,11 @@
}
bool HWComposer::hasClientComposition(int32_t displayId) const {
+ if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
+ // Displays without a corresponding HWC display are always composed by
+ // the client
+ return true;
+ }
if (!isValidDisplay(displayId)) {
ALOGE("hasClientComposition: Invalid display %d", displayId);
return true;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 44db852..9173165 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -716,18 +716,33 @@
return;
}
- // Client or SolidColor layers
- if (mActiveBuffer == nullptr || mActiveBuffer->handle == nullptr ||
- mHwcLayers[hwcId].forceClientComposition) {
- // TODO: This also includes solid color layers, but no API exists to
- // setup a solid color layer yet
+ // Client layers
+ if (mHwcLayers[hwcId].forceClientComposition ||
+ (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
ALOGV("[%s] Requesting Client composition", mName.string());
setCompositionType(hwcId, HWC2::Composition::Client);
- error = hwcLayer->setBuffer(nullptr, Fence::NO_FENCE);
+ return;
+ }
+
+ // SolidColor layers
+ if (mActiveBuffer == nullptr) {
+ setCompositionType(hwcId, HWC2::Composition::SolidColor);
+
+ // For now, we only support black for DimLayer
+ error = hwcLayer->setColor({0, 0, 0, 255});
if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set null buffer: %s (%d)", mName.string(),
+ ALOGE("[%s] Failed to set color: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
+
+ // Clear out the transform, because it doesn't make sense absent a
+ // source buffer
+ error = hwcLayer->setTransform(HWC2::Transform::None);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
return;
}
@@ -1058,8 +1073,13 @@
}
HWC2::Composition Layer::getCompositionType(int32_t hwcId) const {
+ if (hwcId == DisplayDevice::DISPLAY_ID_INVALID) {
+ // If we're querying the composition type for a display that does not
+ // have a HWC counterpart, then it will always be Client
+ return HWC2::Composition::Client;
+ }
if (mHwcLayers.count(hwcId) == 0) {
- ALOGE("getCompositionType called without a valid HWC layer");
+ ALOGE("getCompositionType called with an invalid HWC layer");
return HWC2::Composition::Invalid;
}
return mHwcLayers.at(hwcId).compositionType;
@@ -1269,9 +1289,14 @@
// If this transaction is waiting on the receipt of a frame, generate a sync
// point and send it to the remote layer.
if (mCurrentState.handle != nullptr) {
- sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
- sp<Layer> handleLayer = handle->owner.promote();
- if (handleLayer == nullptr) {
+ sp<IBinder> strongBinder = mCurrentState.handle.promote();
+ sp<Handle> handle = nullptr;
+ sp<Layer> handleLayer = nullptr;
+ if (strongBinder != nullptr) {
+ handle = static_cast<Handle*>(strongBinder.get());
+ handleLayer = handle->owner.promote();
+ }
+ if (strongBinder == nullptr || handleLayer == nullptr) {
ALOGE("[%s] Unable to promote Layer handle", mName.string());
// If we can't promote the layer we are intended to wait on,
// then it is expired or otherwise invalid. Allow this transaction
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 55e3b54..c96e7d5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -124,7 +124,7 @@
// If set, defers this state update until the Layer identified by handle
// receives a frame with the given frameNumber
- sp<IBinder> handle;
+ wp<IBinder> handle;
uint64_t frameNumber;
// the transparentRegion hint is a bit special, it's latched only
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c700116..47f5401 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1022,7 +1022,12 @@
}
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
- status_t result = mDisplays[displayId]->prepareFrame(*mHwc);
+ auto& displayDevice = mDisplays[displayId];
+ if (!displayDevice->isDisplayOn()) {
+ continue;
+ }
+
+ status_t result = displayDevice->prepareFrame(*mHwc);
ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
" %d (%s)", displayId, result, strerror(-result));
}
@@ -1248,7 +1253,12 @@
}
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
- status_t result = mDisplays[displayId]->prepareFrame(*mHwc);
+ auto& displayDevice = mDisplays[displayId];
+ if (!displayDevice->isDisplayOn()) {
+ continue;
+ }
+
+ status_t result = displayDevice->prepareFrame(*mHwc);
ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
" %d (%s)", displayId, result, strerror(-result));
}
@@ -1286,6 +1296,9 @@
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
+ if (!displayDevice->isDisplayOn()) {
+ continue;
+ }
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId >= 0) {
mHwc->commit(hwcId);
@@ -2093,8 +2106,14 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
Mutex::Autolock _l(mStateLock);
+ sp<Layer> layer = weakLayer.promote();
+ if (layer == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ }
+
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersPendingRemoval.push(layer);
@@ -2435,14 +2454,7 @@
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- status_t err = NO_ERROR;
- sp<Layer> l(layer.promote());
- if (l != NULL) {
- err = removeLayer(l);
- ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
- }
- return err;
+ return removeLayer(layer);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 633e956..8279a85 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -311,7 +311,7 @@
status_t onLayerDestroyed(const wp<Layer>& layer);
// remove a layer from SurfaceFlinger immediately
- status_t removeLayer(const sp<Layer>& layer);
+ status_t removeLayer(const wp<Layer>& layer);
// add a layer to SurfaceFlinger
status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 7f3b269..072de81 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -2096,8 +2096,14 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
Mutex::Autolock _l(mStateLock);
+ sp<Layer> layer = weakLayer.promote();
+ if (layer == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ }
+
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersPendingRemoval.push(layer);
@@ -2438,14 +2444,7 @@
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- status_t err = NO_ERROR;
- sp<Layer> l(layer.promote());
- if (l != NULL) {
- err = removeLayer(l);
- ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
- }
- return err;
+ return removeLayer(layer);
}
// ---------------------------------------------------------------------------