Merge "Add debug output for lights."
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 0bedc74..49a6b12 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -164,6 +164,9 @@
}
mCallback.clear();
mDevice->closeOutputStream(mStream);
+ // Closing the output stream in the HAL waits for the callback to finish,
+ // and joins the callback thread. Thus is it guaranteed that the callback
+ // thread will not be accessing our object anymore.
mStream = nullptr;
}
@@ -404,6 +407,8 @@
Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback) {
if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
+ // Safe to pass 'this' because it is guaranteed that the callback thread
+ // is joined prior to exit from StreamOut's destructor.
int result = mStream->set_callback(mStream, StreamOut::asyncCallback, this);
if (result == 0) {
mCallback = callback;
@@ -420,19 +425,27 @@
// static
int StreamOut::asyncCallback(stream_callback_event_t event, void*,
void* cookie) {
- wp<StreamOut> weakSelf(reinterpret_cast<StreamOut*>(cookie));
- sp<StreamOut> self = weakSelf.promote();
- if (self == nullptr || self->mCallback == nullptr) return 0;
+ // It is guaranteed that the callback thread is joined prior
+ // to exiting from StreamOut's destructor. Must *not* use sp<StreamOut>
+ // here because it can make this code the last owner of StreamOut,
+ // and an attempt to run the destructor on the callback thread
+ // will cause a deadlock in the legacy HAL code.
+ StreamOut *self = reinterpret_cast<StreamOut*>(cookie);
+ // It's correct to hold an sp<> to callback because the reference
+ // in the StreamOut instance can be cleared in the meantime. There is
+ // no difference on which thread to run IStreamOutCallback's destructor.
+ sp<IStreamOutCallback> callback = self->mCallback;
+ if (callback.get() == nullptr) return 0;
ALOGV("asyncCallback() event %d", event);
switch (event) {
case STREAM_CBK_EVENT_WRITE_READY:
- self->mCallback->onWriteReady();
+ callback->onWriteReady();
break;
case STREAM_CBK_EVENT_DRAIN_READY:
- self->mCallback->onDrainReady();
+ callback->onDrainReady();
break;
case STREAM_CBK_EVENT_ERROR:
- self->mCallback->onError();
+ callback->onError();
break;
default:
ALOGW("asyncCallback() unknown event %d", event);
diff --git a/graphics/composer/2.1/default/ComposerBase.h b/graphics/composer/2.1/default/ComposerBase.h
index 85b1a4d..e1c9d33 100644
--- a/graphics/composer/2.1/default/ComposerBase.h
+++ b/graphics/composer/2.1/default/ComposerBase.h
@@ -38,6 +38,8 @@
public:
virtual ~ComposerBase() {};
+ virtual bool hasCapability(hwc2_capability_t capability) = 0;
+
virtual void removeClient() = 0;
virtual void enableCallback(bool enable) = 0;
virtual uint32_t getMaxVirtualDisplayCount() = 0;
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index e792034..4e6dd4f 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -748,15 +748,17 @@
}
// First try to Present as is.
- int presentFence = -1;
- std::vector<Layer> layers;
- std::vector<int> fences;
- auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
- if (err == Error::NONE) {
- mWriter.setPresentOrValidateResult(1);
- mWriter.setPresentFence(presentFence);
- mWriter.setReleaseFences(layers, fences);
- return true;
+ if (mHal.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
+ int presentFence = -1;
+ std::vector<Layer> layers;
+ std::vector<int> fences;
+ auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
+ if (err == Error::NONE) {
+ mWriter.setPresentOrValidateResult(1);
+ mWriter.setPresentFence(presentFence);
+ mWriter.setReleaseFences(layers, fences);
+ return true;
+ }
}
// Present has failed. We need to fallback to validate
@@ -766,9 +768,8 @@
std::vector<Layer> requestedLayers;
std::vector<uint32_t> requestMasks;
- err = mHal.validateDisplay(mDisplay, &changedLayers,
- &compositionTypes, &displayRequestMask,
- &requestedLayers, &requestMasks);
+ auto err = mHal.validateDisplay(mDisplay, &changedLayers, &compositionTypes,
+ &displayRequestMask, &requestedLayers, &requestMasks);
if (err == Error::NONE) {
mWriter.setPresentOrValidateResult(0);
mWriter.setChangedCompositionTypes(changedLayers,
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 80ec1cd..d431a6c 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -49,8 +49,7 @@
}
initCapabilities();
- if (majorVersion >= 2 &&
- hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
+ if (majorVersion >= 2 && hasCapability(HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE)) {
ALOGE("Present fence must be reliable from HWC2 on.");
abort();
}
@@ -116,12 +115,14 @@
uint32_t count = 0;
mDevice->getCapabilities(mDevice, &count, nullptr);
- std::vector<Capability> caps(count);
- mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
- std::underlying_type<Capability>::type*>(caps.data()));
+ std::vector<int32_t> caps(count);
+ mDevice->getCapabilities(mDevice, &count, caps.data());
caps.resize(count);
- mCapabilities.insert(caps.cbegin(), caps.cend());
+ mCapabilities.reserve(count);
+ for (auto cap : caps) {
+ mCapabilities.insert(static_cast<hwc2_capability_t>(cap));
+ }
}
template<typename T>
@@ -190,7 +191,7 @@
initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
&mDispatch.setLayerPlaneAlpha);
- if (hasCapability(Capability::SIDEBAND_STREAM)) {
+ if (hasCapability(HWC2_CAPABILITY_SIDEBAND_STREAM)) {
initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
&mDispatch.setLayerSidebandStream);
}
@@ -210,15 +211,26 @@
initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay);
}
-bool HwcHal::hasCapability(Capability capability) const
-{
+bool HwcHal::hasCapability(hwc2_capability_t capability) {
return (mCapabilities.count(capability) > 0);
}
Return<void> HwcHal::getCapabilities(getCapabilities_cb hidl_cb)
{
- std::vector<Capability> caps(
- mCapabilities.cbegin(), mCapabilities.cend());
+ std::vector<Capability> caps;
+ caps.reserve(mCapabilities.size());
+ for (auto cap : mCapabilities) {
+ switch (cap) {
+ case HWC2_CAPABILITY_SIDEBAND_STREAM:
+ case HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM:
+ case HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE:
+ caps.push_back(static_cast<Capability>(cap));
+ break;
+ default:
+ // not all HWC2 caps are defined in HIDL
+ break;
+ }
+ }
hidl_vec<Capability> caps_reply;
caps_reply.setToExternal(caps.data(), caps.size());
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index 32c6b0b..e3f5ce6 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -58,14 +58,13 @@
HwcHal(const hw_module_t* module);
virtual ~HwcHal();
- bool hasCapability(Capability capability) const;
-
// IComposer interface
Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
Return<void> createClient(createClient_cb hidl_cb) override;
// ComposerBase interface
+ bool hasCapability(hwc2_capability_t capability) override;
void removeClient() override;
void enableCallback(bool enable) override;
uint32_t getMaxVirtualDisplayCount() override;
@@ -168,7 +167,7 @@
hwc2_device_t* mDevice;
- std::unordered_set<Capability> mCapabilities;
+ std::unordered_set<hwc2_capability_t> mCapabilities;
struct {
HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;