diff options
5 files changed, 69 insertions, 31 deletions
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp index 76ebf9d0c2..edf734271a 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaRenderEngine.cpp @@ -397,12 +397,10 @@ void SkiaRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, } // 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 @@ void SkiaRenderEngine::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) { 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 @@ void SkiaRenderEngine::drawLayersInternal( 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 @@ void SkiaRenderEngine::drawLayersInternal( 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 193847bb9f..ad0ed4ab70 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -1055,12 +1055,7 @@ bool SensorService::threadLoop() { 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 7062a4e3a7..effbfdb896 100644 --- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp +++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp @@ -56,29 +56,33 @@ void WindowInfosListenerInvoker::removeWindowInfosListener( 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); - } - } + eraseListenerAndAckMessages(who); + }}); +} + +void WindowInfosListenerInvoker::eraseListenerAndAckMessages(const wp<IBinder>& binder) { + auto it = mWindowInfosListeners.find(binder); + int64_t listenerId = it->second.first; + mWindowInfosListeners.erase(binder); - for (int64_t vsyncId : vsyncIds) { - ackWindowInfosReceived(vsyncId, listenerId); + 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( diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.h b/services/surfaceflinger/WindowInfosListenerInvoker.h index f36b0edd7d..261fd0ff3b 100644 --- a/services/surfaceflinger/WindowInfosListenerInvoker.h +++ b/services/surfaceflinger/WindowInfosListenerInvoker.h @@ -67,6 +67,7 @@ private: 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 c7b845e668..cfb047c877 100644 --- a/services/surfaceflinger/tests/unittests/WindowInfosListenerInvokerTest.cpp +++ b/services/surfaceflinger/tests/unittests/WindowInfosListenerInvokerTest.cpp @@ -245,4 +245,42 @@ TEST_F(WindowInfosListenerInvokerTest, noListeners) { 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 |