Revert "SF: Predict HWC composition strategy"
This reverts commit 7234fa59245e20b934a15ebbd27d4e189ad224d0.
Change-Id: I908f9c279bb91ce2ee654a05eb8ac8d0057caa47
Bug: 223543469
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 09648c3..6a75283 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -221,12 +221,12 @@
setReleasedLayers(std::move(releasedLayers));
}
-std::optional<android::HWComposer::DeviceRequestedChanges> Display::chooseCompositionStrategy() {
+void Display::chooseCompositionStrategy() {
ATRACE_CALL();
ALOGV(__FUNCTION__);
if (mIsDisconnected) {
- return {};
+ return;
}
// Default to the base settings -- client composition only.
@@ -235,7 +235,7 @@
// If we don't have a HWC display, then we are done.
const auto halDisplayId = HalDisplayId::tryCast(mId);
if (!halDisplayId) {
- return {};
+ return;
}
// Get any composition changes requested by the HWC device, and apply them.
@@ -260,13 +260,8 @@
result != NO_ERROR) {
ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
strerror(-result));
- return {};
+ return;
}
-
- return changes;
-}
-
-void Display::applyCompositionStrategy(const std::optional<DeviceRequestedChanges>& changes) {
if (changes) {
applyChangedTypesToLayers(changes->changedTypes);
applyDisplayRequests(changes->displayRequests);
@@ -292,6 +287,12 @@
return hwc.hasCapability(Capability::SKIP_CLIENT_COLOR_TRANSFORM);
}
+bool Display::anyLayersRequireClientComposition() const {
+ const auto layers = getOutputLayersOrderedByZ();
+ return std::any_of(layers.begin(), layers.end(),
+ [](const auto& layer) { return layer->requiresClientComposition(); });
+}
+
bool Display::allLayersRequireClientComposition() const {
const auto layers = getOutputLayersOrderedByZ();
return std::all_of(layers.begin(), layers.end(),
@@ -389,8 +390,7 @@
}
}
-void Display::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs,
- GpuCompositionResult&& result) {
+void Display::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
// We only need to actually compose the display if:
// 1) It is being handled by hardware composer, which may need this to
// keep its virtual display state machine in sync, or
@@ -400,7 +400,7 @@
return;
}
- impl::Output::finishFrame(refreshArgs, std::move(result));
+ impl::Output::finishFrame(refreshArgs);
}
} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplaySurface.cpp b/services/surfaceflinger/CompositionEngine/src/DisplaySurface.cpp
index 28900af..db6d4f2 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplaySurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplaySurface.cpp
@@ -20,8 +20,4 @@
DisplaySurface::~DisplaySurface() = default;
-bool DisplaySurface::supportsCompositionStrategyPrediction() const {
- return true;
-}
-
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/src/HwcAsyncWorker.cpp b/services/surfaceflinger/CompositionEngine/src/HwcAsyncWorker.cpp
deleted file mode 100644
index 497424a..0000000
--- a/services/surfaceflinger/CompositionEngine/src/HwcAsyncWorker.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <compositionengine/impl/HwcAsyncWorker.h>
-#include <processgroup/sched_policy.h>
-#include <pthread.h>
-#include <sched.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <system/thread_defs.h>
-
-#include <android-base/thread_annotations.h>
-#include <cutils/sched_policy.h>
-
-namespace android::compositionengine::impl {
-
-HwcAsyncWorker::HwcAsyncWorker() {
- mThread = std::thread(&HwcAsyncWorker::run, this);
- pthread_setname_np(mThread.native_handle(), "HwcAsyncWorker");
-}
-
-HwcAsyncWorker::~HwcAsyncWorker() {
- {
- std::scoped_lock lock(mMutex);
- mDone = true;
- mCv.notify_all();
- }
- if (mThread.joinable()) {
- mThread.join();
- }
-}
-std::future<std::optional<android::HWComposer::DeviceRequestedChanges>> HwcAsyncWorker::send(
- std::function<std::optional<android::HWComposer::DeviceRequestedChanges>()> task) {
- std::unique_lock<std::mutex> lock(mMutex);
- android::base::ScopedLockAssertion assumeLock(mMutex);
- mTask = std::packaged_task<std::optional<android::HWComposer::DeviceRequestedChanges>()>(
- [task = std::move(task)]() { return task(); });
- mTaskRequested = true;
- mCv.notify_one();
- return mTask.get_future();
-}
-
-void HwcAsyncWorker::run() {
- set_sched_policy(0, SP_FOREGROUND);
- struct sched_param param = {0};
- param.sched_priority = 2;
- sched_setscheduler(gettid(), SCHED_FIFO, ¶m);
-
- std::unique_lock<std::mutex> lock(mMutex);
- android::base::ScopedLockAssertion assumeLock(mMutex);
- while (!mDone) {
- mCv.wait(lock);
- if (mTaskRequested && mTask.valid()) {
- mTask();
- mTaskRequested = false;
- }
- }
-}
-
-} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index cd10bc1..aef55d4 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -22,7 +22,6 @@
#include <compositionengine/LayerFE.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/RenderSurface.h>
-#include <compositionengine/impl/HwcAsyncWorker.h>
#include <compositionengine/impl/Output.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
@@ -435,17 +434,9 @@
writeCompositionState(refreshArgs);
setColorTransform(refreshArgs);
beginFrame();
-
- GpuCompositionResult result;
- const bool predictCompositionStrategy = canPredictCompositionStrategy(refreshArgs);
- if (predictCompositionStrategy) {
- result = prepareFrameAsync(refreshArgs);
- } else {
- prepareFrame();
- }
-
+ prepareFrame();
devOptRepaintFlash(refreshArgs);
- finishFrame(refreshArgs, std::move(result));
+ finishFrame(refreshArgs);
postFramebuffer();
renderCachedSets(refreshArgs);
}
@@ -960,62 +951,19 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
- auto& outputState = editState();
+ const auto& outputState = getState();
if (!outputState.isEnabled) {
return;
}
- auto changes = chooseCompositionStrategy();
- outputState.previousDeviceRequestedChanges = changes;
- if (changes) {
- applyCompositionStrategy(changes);
- }
- finishPrepareFrame();
-}
+ chooseCompositionStrategy();
-std::future<std::optional<android::HWComposer::DeviceRequestedChanges>>
-Output::chooseCompositionStrategyAsync() {
- return mHwComposerAsyncWorker->send([&]() { return chooseCompositionStrategy(); });
-}
-
-GpuCompositionResult Output::prepareFrameAsync(const CompositionRefreshArgs& refreshArgs) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
- auto& state = editState();
- const auto& previousChanges = state.previousDeviceRequestedChanges;
- auto hwcResult = chooseCompositionStrategyAsync();
- applyCompositionStrategy(previousChanges);
- finishPrepareFrame();
-
- base::unique_fd bufferFence;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
- updateProtectedContentState();
- const bool dequeueSucceeded = dequeueRenderBuffer(&bufferFence, &buffer);
- GpuCompositionResult compositionResult;
- if (dequeueSucceeded) {
- std::optional<base::unique_fd> optFd =
- composeSurfaces(Region::INVALID_REGION, refreshArgs, buffer, bufferFence);
- if (optFd) {
- compositionResult.fence = std::move(*optFd);
- }
+ if (mPlanner) {
+ mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
}
- auto changes = hwcResult.valid() ? hwcResult.get() : std::nullopt;
- const bool predictionSucceeded = dequeueSucceeded && changes == previousChanges;
- compositionResult.succeeded = predictionSucceeded;
- if (!predictionSucceeded) {
- ATRACE_NAME("CompositionStrategyPredictionMiss");
- if (changes) {
- applyCompositionStrategy(changes);
- }
- finishPrepareFrame();
- // Track the dequeued buffer to reuse so we don't need to dequeue another one.
- compositionResult.buffer = buffer;
- } else {
- ATRACE_NAME("CompositionStrategyPredictionHit");
- }
- state.previousDeviceRequestedChanges = std::move(changes);
- return compositionResult;
+ mRenderSurface->prepareFrame(outputState.usesClientComposition,
+ outputState.usesDeviceComposition);
}
void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& refreshArgs) {
@@ -1025,11 +973,7 @@
if (getState().isEnabled) {
if (const auto dirtyRegion = getDirtyRegion(); !dirtyRegion.isEmpty()) {
- base::unique_fd bufferFence;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
- updateProtectedContentState();
- dequeueRenderBuffer(&bufferFence, &buffer);
- static_cast<void>(composeSurfaces(dirtyRegion, refreshArgs, buffer, bufferFence));
+ static_cast<void>(composeSurfaces(dirtyRegion, refreshArgs));
mRenderSurface->queueBuffer(base::unique_fd());
}
}
@@ -1041,7 +985,7 @@
prepareFrame();
}
-void Output::finishFrame(const CompositionRefreshArgs& refreshArgs, GpuCompositionResult&& result) {
+void Output::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
@@ -1049,25 +993,9 @@
return;
}
- std::optional<base::unique_fd> optReadyFence;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
- base::unique_fd bufferFence;
- if (result.succeeded) {
- optReadyFence = std::move(result.fence);
- } else {
- if (result.bufferAvailable()) {
- buffer = std::move(result.buffer);
- bufferFence = std::move(result.fence);
- } else {
- updateProtectedContentState();
- if (!dequeueRenderBuffer(&bufferFence, &buffer)) {
- return;
- }
- }
- // Repaint the framebuffer (if needed), getting the optional fence for when
- // the composition completes.
- optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs, buffer, bufferFence);
- }
+ // Repaint the framebuffer (if needed), getting the optional fence for when
+ // the composition completes.
+ auto optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs);
if (!optReadyFence) {
return;
}
@@ -1076,8 +1004,16 @@
mRenderSurface->queueBuffer(std::move(*optReadyFence));
}
-void Output::updateProtectedContentState() {
+std::optional<base::unique_fd> Output::composeSurfaces(
+ const Region& debugRegion, const compositionengine::CompositionRefreshArgs& refreshArgs) {
+ ATRACE_CALL();
+ ALOGV(__FUNCTION__);
+
const auto& outputState = getState();
+ OutputCompositionState& outputCompositionState = editState();
+ const TracedOrdinal<bool> hasClientComposition = {"hasClientComposition",
+ outputState.usesClientComposition};
+
auto& renderEngine = getCompositionEngine().getRenderEngine();
const bool supportsProtectedContent = renderEngine.supportsProtectedContent();
@@ -1099,48 +1035,29 @@
} else if (!outputState.isSecure && renderEngine.isProtected()) {
renderEngine.useProtectedContext(false);
}
-}
-bool Output::dequeueRenderBuffer(base::unique_fd* bufferFence,
- std::shared_ptr<renderengine::ExternalTexture>* tex) {
- const auto& outputState = getState();
+ base::unique_fd fd;
+
+ std::shared_ptr<renderengine::ExternalTexture> tex;
// If we aren't doing client composition on this output, but do have a
// flipClientTarget request for this frame on this output, we still need to
// dequeue a buffer.
- if (outputState.usesClientComposition || outputState.flipClientTarget) {
- *tex = mRenderSurface->dequeueBuffer(bufferFence);
- if (*tex == nullptr) {
+ if (hasClientComposition || outputState.flipClientTarget) {
+ tex = mRenderSurface->dequeueBuffer(&fd);
+ if (tex == nullptr) {
ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
"client composition for this frame",
mName.c_str());
- return false;
+ return {};
}
}
- return true;
-}
-std::optional<base::unique_fd> Output::composeSurfaces(
- const Region& debugRegion, const compositionengine::CompositionRefreshArgs& refreshArgs,
- std::shared_ptr<renderengine::ExternalTexture> tex, base::unique_fd& fd) {
- ATRACE_CALL();
- ALOGV(__FUNCTION__);
-
- const auto& outputState = getState();
- const TracedOrdinal<bool> hasClientComposition = {"hasClientComposition",
- outputState.usesClientComposition};
if (!hasClientComposition) {
setExpensiveRenderingExpected(false);
return base::unique_fd();
}
- if (tex == nullptr) {
- ALOGW("Buffer not valid for display [%s], bailing out of "
- "client composition for this frame",
- mName.c_str());
- return {};
- }
-
ALOGV("hasClientComposition");
renderengine::DisplaySettings clientCompositionDisplay;
@@ -1168,8 +1085,6 @@
outputState.usesDeviceComposition || getSkipColorTransform();
// Generate the client composition requests for the layers on this output.
- auto& renderEngine = getCompositionEngine().getRenderEngine();
- const bool supportsProtectedContent = renderEngine.supportsProtectedContent();
std::vector<LayerFE*> clientCompositionLayersFE;
std::vector<LayerFE::LayerSettings> clientCompositionLayers =
generateClientCompositionRequests(supportsProtectedContent,
@@ -1177,19 +1092,16 @@
clientCompositionLayersFE);
appendRegionFlashRequests(debugRegion, clientCompositionLayers);
- OutputCompositionState& outputCompositionState = editState();
// Check if the client composition requests were rendered into the provided graphic buffer. If
// so, we can reuse the buffer and avoid client composition.
if (mClientCompositionRequestCache) {
if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(),
clientCompositionDisplay,
clientCompositionLayers)) {
- ATRACE_NAME("ClientCompositionCacheHit");
outputCompositionState.reusedClientComposition = true;
setExpensiveRenderingExpected(false);
return base::unique_fd();
}
- ATRACE_NAME("ClientCompositionCacheMiss");
mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
clientCompositionLayers);
}
@@ -1441,13 +1353,12 @@
outputState.dirtyRegion.set(outputState.displaySpace.getBoundsAsRect());
}
-std::optional<android::HWComposer::DeviceRequestedChanges> Output::chooseCompositionStrategy() {
+void Output::chooseCompositionStrategy() {
// The base output implementation can only do client composition
auto& outputState = editState();
outputState.usesClientComposition = true;
outputState.usesDeviceComposition = false;
outputState.reusedClientComposition = false;
- return {};
}
bool Output::getSkipColorTransform() const {
@@ -1462,63 +1373,5 @@
return result;
}
-void Output::setPredictCompositionStrategy(bool predict) {
- if (predict) {
- mHwComposerAsyncWorker = std::make_unique<HwcAsyncWorker>();
- } else {
- mHwComposerAsyncWorker.reset(nullptr);
- }
-}
-
-bool Output::canPredictCompositionStrategy(const CompositionRefreshArgs& refreshArgs) {
- if (!getState().isEnabled || !mHwComposerAsyncWorker) {
- ALOGV("canPredictCompositionStrategy disabled");
- return false;
- }
-
- if (!getState().previousDeviceRequestedChanges) {
- ALOGV("canPredictCompositionStrategy previous changes not available");
- return false;
- }
-
- if (!mRenderSurface->supportsCompositionStrategyPrediction()) {
- ALOGV("canPredictCompositionStrategy surface does not support");
- return false;
- }
-
- if (refreshArgs.devOptFlashDirtyRegionsDelay) {
- ALOGV("canPredictCompositionStrategy devOptFlashDirtyRegionsDelay");
- return false;
- }
-
- // If no layer uses clientComposition, then don't predict composition strategy
- // because we have less work to do in parallel.
- if (!anyLayersRequireClientComposition()) {
- ALOGV("canPredictCompositionStrategy no layer uses clientComposition");
- return false;
- }
-
- if (!refreshArgs.updatingOutputGeometryThisFrame) {
- return true;
- }
-
- ALOGV("canPredictCompositionStrategy updatingOutputGeometryThisFrame");
- return false;
-}
-
-bool Output::anyLayersRequireClientComposition() const {
- const auto layers = getOutputLayersOrderedByZ();
- return std::any_of(layers.begin(), layers.end(),
- [](const auto& layer) { return layer->requiresClientComposition(); });
-}
-
-void Output::finishPrepareFrame() {
- const auto& state = getState();
- if (mPlanner) {
- mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
- }
- mRenderSurface->prepareFrame(state.usesClientComposition, state.usesDeviceComposition);
-}
-
} // namespace impl
} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 5a3af7b..12c2c8e 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -289,9 +289,5 @@
return mTexture;
}
-bool RenderSurface::supportsCompositionStrategyPrediction() const {
- return mDisplaySurface->supportsCompositionStrategyPrediction();
-}
-
} // namespace impl
} // namespace android::compositionengine