Merge "Vulkan: log dlerror on error" into main am: 67d71c0552
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2825857
Change-Id: I555a307e8afb5c4621bee467e867be96a782a2ba
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 3da06ba..fc273e0 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -73,8 +73,8 @@
ALOGV("MemoryHeapBase: Attempting to force MemFD");
fd = memfd_create_region(name ? name : "MemoryHeapBase", size);
if (fd < 0 || (mapfd(fd, true, size) != NO_ERROR)) return;
- const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) |
- ((mFlags & MEMFD_ALLOW_SEALING_FLAG) ? 0 : F_SEAL_SEAL);
+ const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) | F_SEAL_GROW |
+ F_SEAL_SHRINK | ((mFlags & MEMFD_ALLOW_SEALING_FLAG) ? 0 : F_SEAL_SEAL);
if (SEAL_FLAGS && (fcntl(fd, F_ADD_SEALS, SEAL_FLAGS) == -1)) {
ALOGE("MemoryHeapBase: MemFD %s sealing with flags %x failed with error %s", name,
SEAL_FLAGS, strerror(errno));
diff --git a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
index 278dd2b..140270f 100644
--- a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
+++ b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp
@@ -37,7 +37,8 @@
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
TEST(MemoryHeapBase, MemfdUnsealed) {
@@ -48,7 +49,8 @@
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), 0);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
TEST(MemoryHeapBase, MemfdSealedProtected) {
@@ -59,7 +61,9 @@
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL | F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS),
+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL | F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
TEST(MemoryHeapBase, MemfdUnsealedProtected) {
@@ -71,7 +75,8 @@
ASSERT_NE(mHeap.get(), nullptr);
int fd = mHeap->getHeapID();
EXPECT_NE(fd, -1);
- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_FUTURE_WRITE);
+ EXPECT_EQ(ftruncate(fd, 4096), -1);
}
#else
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index 76ebf9d..edf7342 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -397,12 +397,10 @@
}
// We don't attempt to map a buffer if the buffer contains protected content. In GL this is
// important because GPU resources for protected buffers are much more limited. (In Vk we
- // simply match the existing behavior for protected buffers.) In Vk, we never cache any
- // buffers while in a protected context, since Vk cannot share across contexts, and protected
- // is less common.
+ // simply match the existing behavior for protected buffers.) We also never cache any
+ // buffers while in a protected context.
const bool isProtectedBuffer = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
- if (isProtectedBuffer ||
- (mRenderEngineType == RenderEngineType::SKIA_VK_THREADED && isProtected())) {
+ if (isProtectedBuffer || isProtected()) {
return;
}
ATRACE_CALL();
@@ -467,9 +465,8 @@
std::shared_ptr<AutoBackendTexture::LocalRef> SkiaRenderEngine::getOrCreateBackendTexture(
const sp<GraphicBuffer>& buffer, bool isOutputBuffer) {
- // Do not lookup the buffer in the cache for protected contexts with the SkiaVk back-end
- if (mRenderEngineType == RenderEngineType::SKIA_GL_THREADED ||
- (mRenderEngineType == RenderEngineType::SKIA_VK_THREADED && !isProtected())) {
+ // Do not lookup the buffer in the cache for protected contexts
+ if (!isProtected()) {
if (const auto& it = mTextureCache.find(buffer->getId()); it != mTextureCache.end()) {
return it->second;
}
@@ -711,7 +708,9 @@
SkCanvas* canvas = dstCanvas;
SkiaCapture::OffscreenState offscreenCaptureState;
const LayerSettings* blurCompositionLayer = nullptr;
- if (mBlurFilter) {
+
+ // TODO (b/270314344): Enable blurs in protected context.
+ if (mBlurFilter && !mInProtectedContext) {
bool requiresCompositionLayer = false;
for (const auto& layer : layers) {
// if the layer doesn't have blur or it is not visible then continue
@@ -805,7 +804,8 @@
const auto [bounds, roundRectClip] =
getBoundsAndClip(layer.geometry.boundaries, layer.geometry.roundedCornersCrop,
layer.geometry.roundedCornersRadius);
- if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha)) {
+ // TODO (b/270314344): Enable blurs in protected context.
+ if (mBlurFilter && layerHasBlur(layer, ctModifiesAlpha) && !mInProtectedContext) {
std::unordered_map<uint32_t, sk_sp<SkImage>> cachedBlurs;
// if multiple layers have blur, then we need to take a snapshot now because
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 193847b..ad0ed4a 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1055,12 +1055,7 @@
if (count < 0) {
if(count == DEAD_OBJECT && device.isReconnecting()) {
device.reconnect();
- // There are no "real" events at this point, but do not skip the rest of the loop
- // if there are pending runtime events.
- Mutex::Autolock _l(&mLock);
- if (mRuntimeSensorEventQueue.empty()) {
- continue;
- }
+ continue;
} else {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
index 7062a4e..effbfdb 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
@@ -56,31 +56,35 @@
ATRACE_NAME("WindowInfosListenerInvoker::removeWindowInfosListener");
sp<IBinder> asBinder = IInterface::asBinder(listener);
asBinder->unlinkToDeath(sp<DeathRecipient>::fromExisting(this));
- mWindowInfosListeners.erase(asBinder);
+ eraseListenerAndAckMessages(asBinder);
}});
}
void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
BackgroundExecutor::getInstance().sendCallbacks({[this, who]() {
ATRACE_NAME("WindowInfosListenerInvoker::binderDied");
- auto it = mWindowInfosListeners.find(who);
- int64_t listenerId = it->second.first;
- mWindowInfosListeners.erase(who);
-
- std::vector<int64_t> vsyncIds;
- for (auto& [vsyncId, state] : mUnackedState) {
- if (std::find(state.unackedListenerIds.begin(), state.unackedListenerIds.end(),
- listenerId) != state.unackedListenerIds.end()) {
- vsyncIds.push_back(vsyncId);
- }
- }
-
- for (int64_t vsyncId : vsyncIds) {
- ackWindowInfosReceived(vsyncId, listenerId);
- }
+ eraseListenerAndAckMessages(who);
}});
}
+void WindowInfosListenerInvoker::eraseListenerAndAckMessages(const wp<IBinder>& binder) {
+ auto it = mWindowInfosListeners.find(binder);
+ int64_t listenerId = it->second.first;
+ mWindowInfosListeners.erase(binder);
+
+ std::vector<int64_t> vsyncIds;
+ for (auto& [vsyncId, state] : mUnackedState) {
+ if (std::find(state.unackedListenerIds.begin(), state.unackedListenerIds.end(),
+ listenerId) != state.unackedListenerIds.end()) {
+ vsyncIds.push_back(vsyncId);
+ }
+ }
+
+ for (int64_t vsyncId : vsyncIds) {
+ ackWindowInfosReceived(vsyncId, listenerId);
+ }
+}
+
void WindowInfosListenerInvoker::windowInfosChanged(
gui::WindowInfosUpdate update, WindowInfosReportedListenerSet reportedListeners,
bool forceImmediateCall) {
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h
index f36b0ed..261fd0f 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.h
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.h
@@ -67,6 +67,7 @@
std::optional<gui::WindowInfosUpdate> mDelayedUpdate;
WindowInfosReportedListenerSet mReportedListeners;
+ void eraseListenerAndAckMessages(const wp<IBinder>&);
struct UnackedState {
ftl::SmallVector<int64_t, kStaticCapacity> unackedListenerIds;
diff --git a/services/surfaceflinger/tests/unittests/WindowInfosListenerInvokerTest.cpp b/services/surfaceflinger/tests/unittests/WindowInfosListenerInvokerTest.cpp
index c7b845e..cfb047c 100644
--- a/services/surfaceflinger/tests/unittests/WindowInfosListenerInvokerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/WindowInfosListenerInvokerTest.cpp
@@ -245,4 +245,42 @@
EXPECT_EQ(callCount, 1);
}
+// Test that WindowInfosListenerInvoker#removeWindowInfosListener acks any unacked messages for
+// the removed listener.
+TEST_F(WindowInfosListenerInvokerTest, removeListenerAcks) {
+ // Don't ack in this listener to ensure there's an unacked message when the listener is later
+ // removed.
+ gui::WindowInfosListenerInfo listenerToBeRemovedInfo;
+ auto listenerToBeRemoved = sp<Listener>::make([](const gui::WindowInfosUpdate&) {});
+ mInvoker->addWindowInfosListener(listenerToBeRemoved, &listenerToBeRemovedInfo);
+
+ std::mutex mutex;
+ std::condition_variable cv;
+ int callCount = 0;
+ gui::WindowInfosListenerInfo listenerInfo;
+ mInvoker->addWindowInfosListener(sp<Listener>::make([&](const gui::WindowInfosUpdate& update) {
+ std::scoped_lock lock{mutex};
+ callCount++;
+ cv.notify_one();
+ listenerInfo.windowInfosPublisher
+ ->ackWindowInfosReceived(update.vsyncId,
+ listenerInfo.listenerId);
+ }),
+ &listenerInfo);
+
+ BackgroundExecutor::getInstance().sendCallbacks(
+ {[&]() { mInvoker->windowInfosChanged({}, {}, false); }});
+ mInvoker->removeWindowInfosListener(listenerToBeRemoved);
+ BackgroundExecutor::getInstance().sendCallbacks(
+ {[&]() { mInvoker->windowInfosChanged({}, {}, false); }});
+
+ // Verify that the second listener is called twice. If unacked messages aren't removed when the
+ // first listener is removed, this will fail.
+ {
+ std::unique_lock lock{mutex};
+ cv.wait(lock, [&]() { return callCount == 2; });
+ }
+ EXPECT_EQ(callCount, 2);
+}
+
} // namespace android