Merge "ComposerClient 2.4: Clean cache on hotplug" into sc-dev
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
index 3d74af4..46f5d6e 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
@@ -98,7 +98,7 @@
// display change and thus the framework may want to reallocate buffers. We
// need to free all cached handles, since they are holding a strong reference
// to the underlying buffers.
- cleanDisplayResources(display);
+ cleanDisplayResources(display, mResources, mHal);
mResources->removeDisplay(display);
}
mResources->addPhysicalDisplay(display);
@@ -125,56 +125,6 @@
Hal* const mHal;
const sp<IComposerCallback> mCallback;
ComposerResources* const mResources;
-
- void cleanDisplayResources(Display display) {
- size_t cacheSize;
- Error err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize);
- if (err == Error::NONE) {
- for (int slot = 0; slot < cacheSize; slot++) {
- ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
- // Replace the buffer slots with NULLs. Keep the old handle until it is
- // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
- const native_handle_t* clientTarget = nullptr;
- err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true,
- /*rawHandle*/ nullptr, &clientTarget,
- &replacedBuffer);
- if (err != Error::NONE) {
- continue;
- }
- const std::vector<hwc_rect_t> damage;
- err = mHal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage);
- ALOGE_IF(err != Error::NONE,
- "Can't clean slot %d of the client target buffer"
- "cache for display %" PRIu64,
- slot, display);
- }
- } else {
- ALOGE("Can't clean client target cache for display %" PRIu64, display);
- }
-
- err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize);
- if (err == Error::NONE) {
- for (int slot = 0; slot < cacheSize; slot++) {
- // Replace the buffer slots with NULLs. Keep the old handle until it is
- // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
- ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
- const native_handle_t* outputBuffer = nullptr;
- err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
- /*rawHandle*/ nullptr, &outputBuffer,
- &replacedBuffer);
- if (err != Error::NONE) {
- continue;
- }
- err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ -1);
- ALOGE_IF(err != Error::NONE,
- "Can't clean slot %d of the output buffer cache"
- "for display %" PRIu64,
- slot, display);
- }
- } else {
- ALOGE("Can't clean output buffer cache for display %" PRIu64, display);
- }
- }
};
Return<void> registerCallback(const sp<IComposerCallback>& callback) override {
@@ -380,6 +330,57 @@
return std::make_unique<ComposerCommandEngine>(mHal, mResources.get());
}
+ static void cleanDisplayResources(Display display, ComposerResources* const resources,
+ Hal* const hal) {
+ size_t cacheSize;
+ Error err = resources->getDisplayClientTargetCacheSize(display, &cacheSize);
+ if (err == Error::NONE) {
+ for (int slot = 0; slot < cacheSize; slot++) {
+ ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
+ // Replace the buffer slots with NULLs. Keep the old handle until it is
+ // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
+ const native_handle_t* clientTarget = nullptr;
+ err = resources->getDisplayClientTarget(display, slot, /*useCache*/ true,
+ /*rawHandle*/ nullptr, &clientTarget,
+ &replacedBuffer);
+ if (err != Error::NONE) {
+ continue;
+ }
+ const std::vector<hwc_rect_t> damage;
+ err = hal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage);
+ ALOGE_IF(err != Error::NONE,
+ "Can't clean slot %d of the client target buffer"
+ "cache for display %" PRIu64,
+ slot, display);
+ }
+ } else {
+ ALOGE("Can't clean client target cache for display %" PRIu64, display);
+ }
+
+ err = resources->getDisplayOutputBufferCacheSize(display, &cacheSize);
+ if (err == Error::NONE) {
+ for (int slot = 0; slot < cacheSize; slot++) {
+ // Replace the buffer slots with NULLs. Keep the old handle until it is
+ // replaced in ComposerHal, otherwise we risk leaving a dangling pointer.
+ ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true);
+ const native_handle_t* outputBuffer = nullptr;
+ err = resources->getDisplayOutputBuffer(display, slot, /*useCache*/ true,
+ /*rawHandle*/ nullptr, &outputBuffer,
+ &replacedBuffer);
+ if (err != Error::NONE) {
+ continue;
+ }
+ err = hal->setOutputBuffer(display, outputBuffer, /*fence*/ -1);
+ ALOGE_IF(err != Error::NONE,
+ "Can't clean slot %d of the output buffer cache"
+ "for display %" PRIu64,
+ slot, display);
+ }
+ } else {
+ ALOGE("Can't clean output buffer cache for display %" PRIu64, display);
+ }
+ }
+
void destroyResources() {
// We want to call hwc2_close here (and move hwc2_open to the
// constructor), with the assumption that hwc2_close would
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index c889069..3464342 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -45,12 +45,21 @@
class HalEventCallback : public Hal::EventCallback_2_4 {
public:
- HalEventCallback(const sp<IComposerCallback> callback,
+ HalEventCallback(Hal* hal, const sp<IComposerCallback> callback,
V2_1::hal::ComposerResources* resources)
- : mCallback(callback), mResources(resources) {}
+ : mHal(hal), mCallback(callback), mResources(resources) {}
void onHotplug(Display display, IComposerCallback::Connection connected) override {
if (connected == IComposerCallback::Connection::CONNECTED) {
+ if (mResources->hasDisplay(display)) {
+ // This is a subsequent hotplug "connected" for a display. This signals a
+ // display change and thus the framework may want to reallocate buffers. We
+ // need to free all cached handles, since they are holding a strong reference
+ // to the underlying buffers.
+ V2_1::hal::detail::ComposerClientImpl<Interface, Hal>::cleanDisplayResources(
+ display, mResources, mHal);
+ mResources->removeDisplay(display);
+ }
mResources->addPhysicalDisplay(display);
} else if (connected == IComposerCallback::Connection::DISCONNECTED) {
mResources->removeDisplay(display);
@@ -91,13 +100,15 @@
}
protected:
+ Hal* const mHal;
const sp<IComposerCallback> mCallback;
V2_1::hal::ComposerResources* const mResources;
};
Return<void> registerCallback_2_4(const sp<IComposerCallback>& callback) override {
// no locking as we require this function to be called only once
- mHalEventCallback_2_4 = std::make_unique<HalEventCallback>(callback, mResources.get());
+ mHalEventCallback_2_4 =
+ std::make_unique<HalEventCallback>(mHal, callback, mResources.get());
mHal->registerEventCallback_2_4(mHalEventCallback_2_4.get());
return Void();
}