HDR layer info listener
Bug: 182312559
Test: SilkFX's layer listener
Change-Id: Iaaf5065f1adc871ce2890840e19756293dd21871
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 97f8f47..177f339 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -982,6 +982,34 @@
return NO_ERROR;
}
+ status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) override {
+ Parcel data, reply;
+ SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+ SAFE_PARCEL(data.writeStrongBinder, displayToken);
+ SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
+ const status_t error =
+ remote()->transact(BnSurfaceComposer::ADD_HDR_LAYER_INFO_LISTENER, data, &reply);
+ if (error != OK) {
+ ALOGE("addHdrLayerInfoListener: Failed to transact; error = %d", error);
+ }
+ return error;
+ }
+
+ status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) override {
+ Parcel data, reply;
+ SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+ SAFE_PARCEL(data.writeStrongBinder, displayToken);
+ SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
+ const status_t error =
+ remote()->transact(BnSurfaceComposer::REMOVE_HDR_LAYER_INFO_LISTENER, data, &reply);
+ if (error != OK) {
+ ALOGE("removeHdrLayerInfoListener: Failed to transact; error = %d", error);
+ }
+ return error;
+ }
+
status_t notifyPowerBoost(int32_t boostId) override {
Parcel data, reply;
status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -1862,6 +1890,38 @@
}
return setDisplayBrightness(displayToken, brightness);
}
+ case ADD_HDR_LAYER_INFO_LISTENER: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> displayToken;
+ status_t error = data.readNullableStrongBinder(&displayToken);
+ if (error != NO_ERROR) {
+ ALOGE("addHdrLayerInfoListener: Failed to read display token");
+ return error;
+ }
+ sp<gui::IHdrLayerInfoListener> listener;
+ error = data.readNullableStrongBinder(&listener);
+ if (error != NO_ERROR) {
+ ALOGE("addHdrLayerInfoListener: Failed to read listener");
+ return error;
+ }
+ return addHdrLayerInfoListener(displayToken, listener);
+ }
+ case REMOVE_HDR_LAYER_INFO_LISTENER: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> displayToken;
+ status_t error = data.readNullableStrongBinder(&displayToken);
+ if (error != NO_ERROR) {
+ ALOGE("removeHdrLayerInfoListener: Failed to read display token");
+ return error;
+ }
+ sp<gui::IHdrLayerInfoListener> listener;
+ error = data.readNullableStrongBinder(&listener);
+ if (error != NO_ERROR) {
+ ALOGE("removeHdrLayerInfoListener: Failed to read listener");
+ return error;
+ }
+ return removeHdrLayerInfoListener(displayToken, listener);
+ }
case NOTIFY_POWER_BOOST: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
int32_t boostId;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0b01084..07618a4 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2053,6 +2053,17 @@
return ComposerService::getComposerService()->setDisplayBrightness(displayToken, brightness);
}
+status_t SurfaceComposerClient::addHdrLayerInfoListener(
+ const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
+ return ComposerService::getComposerService()->addHdrLayerInfoListener(displayToken, listener);
+}
+
+status_t SurfaceComposerClient::removeHdrLayerInfoListener(
+ const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
+ return ComposerService::getComposerService()->removeHdrLayerInfoListener(displayToken,
+ listener);
+}
+
status_t SurfaceComposerClient::notifyPowerBoost(int32_t boostId) {
return ComposerService::getComposerService()->notifyPowerBoost(boostId);
}
diff --git a/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl b/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
new file mode 100644
index 0000000..fc809c4
--- /dev/null
+++ b/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 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.
+ */
+
+package android.gui;
+
+/** @hide */
+oneway interface IHdrLayerInfoListener {
+ // Callback with the total number of HDR layers, the dimensions of the largest layer,
+ // and a placeholder flags
+ // TODO (b/182312559): Define the flags (likely need an indicator that a UDFPS layer is present)
+ void onHdrLayerInfoChanged(int numberOfHdrLayers, int maxW, int maxH, int flags);
+}
\ No newline at end of file
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 9f9ca74..50198c6 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -18,6 +18,7 @@
#include <android/gui/DisplayBrightness.h>
#include <android/gui/IFpsListener.h>
+#include <android/gui/IHdrLayerInfoListener.h>
#include <android/gui/IScreenCaptureListener.h>
#include <android/gui/ITransactionTraceListener.h>
#include <binder/IBinder.h>
@@ -431,6 +432,25 @@
const gui::DisplayBrightness& brightness) = 0;
/*
+ * Adds a listener that receives HDR layer information. This is used in combination
+ * with setDisplayBrightness to adjust the display brightness depending on factors such
+ * as whether or not HDR is in use.
+ *
+ * Returns NO_ERROR upon success or NAME_NOT_FOUND if the display is invalid.
+ */
+ virtual status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) = 0;
+ /*
+ * Removes a listener that was added with addHdrLayerInfoListener.
+ *
+ * Returns NO_ERROR upon success, NAME_NOT_FOUND if the display is invalid, and BAD_VALUE if
+ * the listener wasn't registered.
+ *
+ */
+ virtual status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) = 0;
+
+ /*
* Sends a power boost to the composer. This function is asynchronous.
*
* boostId
@@ -578,6 +598,8 @@
ADD_FPS_LISTENER,
REMOVE_FPS_LISTENER,
OVERRIDE_HDR_TYPES,
+ ADD_HDR_LAYER_INFO_LISTENER,
+ REMOVE_HDR_LAYER_INFO_LISTENER,
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index c38375c..7bf2e2d 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -215,6 +215,11 @@
static status_t setDisplayBrightness(const sp<IBinder>& displayToken,
const gui::DisplayBrightness& brightness);
+ static status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener);
+ static status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener);
+
/*
* Sends a power boost to the composer. This function is asynchronous.
*
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5ac3f19..9da731a 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -819,6 +819,16 @@
return NO_ERROR;
}
+ status_t addHdrLayerInfoListener(const sp<IBinder>&,
+ const sp<gui::IHdrLayerInfoListener>&) override {
+ return NO_ERROR;
+ }
+
+ status_t removeHdrLayerInfoListener(const sp<IBinder>&,
+ const sp<gui::IHdrLayerInfoListener>&) override {
+ return NO_ERROR;
+ }
+
status_t addRegionSamplingListener(const Rect& /*samplingArea*/,
const sp<IBinder>& /*stopLayerHandle*/,
const sp<IRegionSamplingListener>& /*listener*/) override {
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 470059a..b976eb5 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -157,6 +157,7 @@
"FpsReporter.cpp",
"FrameTracer/FrameTracer.cpp",
"FrameTracker.cpp",
+ "HdrLayerInfoReporter.cpp",
"Layer.cpp",
"LayerProtoHelper.cpp",
"LayerRejecter.cpp",
diff --git a/services/surfaceflinger/HdrLayerInfoReporter.cpp b/services/surfaceflinger/HdrLayerInfoReporter.cpp
new file mode 100644
index 0000000..c06e300
--- /dev/null
+++ b/services/surfaceflinger/HdrLayerInfoReporter.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "HdrLayerInfoReporter"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <utils/Trace.h>
+
+#include "HdrLayerInfoReporter.h"
+
+namespace android {
+
+void HdrLayerInfoReporter::dispatchHdrLayerInfo(const HdrLayerInfo& info) {
+ ATRACE_CALL();
+ std::vector<sp<gui::IHdrLayerInfoListener>> toInvoke;
+ {
+ std::scoped_lock lock(mMutex);
+ toInvoke.reserve(mListeners.size());
+ for (auto& [key, it] : mListeners) {
+ if (it.lastInfo != info) {
+ it.lastInfo = info;
+ toInvoke.push_back(it.listener);
+ }
+ }
+ }
+
+ for (const auto& listener : toInvoke) {
+ ATRACE_NAME("invoking onHdrLayerInfoChanged");
+ listener->onHdrLayerInfoChanged(info.numberOfHdrLayers, info.maxW, info.maxH, info.flags);
+ }
+}
+
+void HdrLayerInfoReporter::binderDied(const wp<IBinder>& who) {
+ std::scoped_lock lock(mMutex);
+ mListeners.erase(who);
+}
+
+void HdrLayerInfoReporter::addListener(const sp<gui::IHdrLayerInfoListener>& listener) {
+ sp<IBinder> asBinder = IInterface::asBinder(listener);
+ asBinder->linkToDeath(this);
+ std::lock_guard lock(mMutex);
+ mListeners.emplace(wp<IBinder>(asBinder), TrackedListener{listener, HdrLayerInfo{}});
+}
+
+void HdrLayerInfoReporter::removeListener(const sp<gui::IHdrLayerInfoListener>& listener) {
+ std::lock_guard lock(mMutex);
+ mListeners.erase(wp<IBinder>(IInterface::asBinder(listener)));
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/HdrLayerInfoReporter.h b/services/surfaceflinger/HdrLayerInfoReporter.h
new file mode 100644
index 0000000..671395f
--- /dev/null
+++ b/services/surfaceflinger/HdrLayerInfoReporter.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <android-base/thread_annotations.h>
+#include <android/gui/IHdrLayerInfoListener.h>
+#include <binder/IBinder.h>
+
+#include <unordered_map>
+
+namespace android {
+
+class HdrLayerInfoReporter final : public IBinder::DeathRecipient {
+public:
+ struct HdrLayerInfo {
+ int32_t numberOfHdrLayers = 0;
+ int32_t maxW = 0;
+ int32_t maxH = 0;
+ int32_t flags = 0;
+
+ bool operator==(const HdrLayerInfo& other) const {
+ return numberOfHdrLayers == other.numberOfHdrLayers && maxW == other.maxW &&
+ maxH == other.maxH && flags == other.flags;
+ }
+
+ bool operator!=(const HdrLayerInfo& other) const { return !(*this == other); }
+ };
+
+ HdrLayerInfoReporter() = default;
+ ~HdrLayerInfoReporter() final = default;
+
+ // Dispatches updated layer fps values for the registered listeners
+ // This method promotes Layer weak pointers and performs layer stack traversals, so mStateLock
+ // must be held when calling this method.
+ void dispatchHdrLayerInfo(const HdrLayerInfo& info) EXCLUDES(mMutex);
+
+ // Override for IBinder::DeathRecipient
+ void binderDied(const wp<IBinder>&) override EXCLUDES(mMutex);
+
+ // Registers an Fps listener that listens to fps updates for the provided layer
+ void addListener(const sp<gui::IHdrLayerInfoListener>& listener) EXCLUDES(mMutex);
+ // Deregisters an Fps listener
+ void removeListener(const sp<gui::IHdrLayerInfoListener>& listener) EXCLUDES(mMutex);
+
+ bool hasListeners() const EXCLUDES(mMutex) {
+ std::scoped_lock lock(mMutex);
+ return !mListeners.empty();
+ }
+
+private:
+ mutable std::mutex mMutex;
+ struct WpHash {
+ size_t operator()(const wp<IBinder>& p) const {
+ return std::hash<IBinder*>()(p.unsafe_get());
+ }
+ };
+
+ struct TrackedListener {
+ sp<gui::IHdrLayerInfoListener> listener;
+ HdrLayerInfo lastInfo;
+ };
+
+ std::unordered_map<wp<IBinder>, TrackedListener, WpHash> mListeners GUARDED_BY(mMutex);
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 525b043..544727f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -112,6 +112,7 @@
#include "FpsReporter.h"
#include "FrameTimeline/FrameTimeline.h"
#include "FrameTracer/FrameTracer.h"
+#include "HdrLayerInfoReporter.h"
#include "Layer.h"
#include "LayerRenderArea.h"
#include "LayerVector.h"
@@ -285,6 +286,7 @@
const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER");
const String16 sRotateSurfaceFlinger("android.permission.ROTATE_SURFACE_FLINGER");
const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
+const String16 sControlDisplayBrightness("android.permission.CONTROL_DISPLAY_BRIGHTNESS");
const String16 sDump("android.permission.DUMP");
const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled";
@@ -1492,6 +1494,47 @@
.get();
}
+status_t SurfaceFlinger::addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) {
+ if (!displayToken) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mStateLock);
+
+ const auto display = getDisplayDeviceLocked(displayToken);
+ if (!display) {
+ return NAME_NOT_FOUND;
+ }
+ const auto displayId = display->getId();
+ sp<HdrLayerInfoReporter>& hdrInfoReporter = mHdrLayerInfoListeners[displayId];
+ if (!hdrInfoReporter) {
+ hdrInfoReporter = sp<HdrLayerInfoReporter>::make();
+ }
+ hdrInfoReporter->addListener(listener);
+ return OK;
+}
+
+status_t SurfaceFlinger::removeHdrLayerInfoListener(
+ const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
+ if (!displayToken) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mStateLock);
+
+ const auto display = getDisplayDeviceLocked(displayToken);
+ if (!display) {
+ return NAME_NOT_FOUND;
+ }
+ const auto displayId = display->getId();
+ sp<HdrLayerInfoReporter>& hdrInfoReporter = mHdrLayerInfoListeners[displayId];
+ if (hdrInfoReporter) {
+ hdrInfoReporter->removeListener(listener);
+ }
+ return OK;
+}
+
status_t SurfaceFlinger::notifyPowerBoost(int32_t boostId) {
Boost powerBoost = static_cast<Boost>(boostId);
@@ -2155,11 +2198,58 @@
}
});
+ std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>>
+ hdrInfoListeners;
{
Mutex::Autolock lock(mStateLock);
if (mFpsReporter) {
mFpsReporter->dispatchLayerFps();
}
+ hdrInfoListeners.reserve(mHdrLayerInfoListeners.size());
+ for (auto& [key, value] : mHdrLayerInfoListeners) {
+ if (value && value->hasListeners()) {
+ auto listenersDisplay = getDisplayById(key);
+ if (listenersDisplay) {
+ hdrInfoListeners.emplace_back(listenersDisplay->getCompositionDisplay(), value);
+ }
+ }
+ }
+ }
+
+ for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
+ HdrLayerInfoReporter::HdrLayerInfo info;
+ int32_t maxArea = 0;
+ mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
+ if (layer->isVisible() &&
+ compositionDisplay->belongsInOutput(layer->getCompositionEngineLayerFE())) {
+ bool isHdr = false;
+ switch (layer->getDataSpace()) {
+ case ui::Dataspace::BT2020:
+ case ui::Dataspace::BT2020_HLG:
+ case ui::Dataspace::BT2020_PQ:
+ case ui::Dataspace::BT2020_ITU:
+ case ui::Dataspace::BT2020_ITU_HLG:
+ case ui::Dataspace::BT2020_ITU_PQ:
+ isHdr = true;
+ break;
+ default:
+ isHdr = false;
+ break;
+ }
+
+ if (isHdr) {
+ info.numberOfHdrLayers++;
+ auto bufferRect = layer->getCompositionState()->geomBufferSize;
+ int32_t area = bufferRect.width() * bufferRect.height();
+ if (area > maxArea) {
+ maxArea = area;
+ info.maxW = bufferRect.width();
+ info.maxH = bufferRect.height();
+ }
+ }
+ }
+ });
+ listener->dispatchHdrLayerInfo(info);
}
mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0]);
@@ -5109,6 +5199,20 @@
// This is not sensitive information, so should not require permission control.
return OK;
}
+ case ADD_HDR_LAYER_INFO_LISTENER:
+ case REMOVE_HDR_LAYER_INFO_LISTENER: {
+ // TODO (b/183985553): Should getting & setting brightness be part of this...?
+ // codes that require permission check
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
+ if ((uid != AID_GRAPHICS) &&
+ !PermissionCache::checkPermission(sControlDisplayBrightness, pid, uid)) {
+ ALOGE("Permission Denial: can't control brightness pid=%d, uid=%d", pid, uid);
+ return PERMISSION_DENIED;
+ }
+ return OK;
+ }
case ADD_FPS_LISTENER:
case REMOVE_FPS_LISTENER:
case ADD_REGION_SAMPLING_LISTENER:
@@ -5670,6 +5774,15 @@
return getDisplayByLayerStack(displayOrLayerStack);
}
+sp<DisplayDevice> SurfaceFlinger::getDisplayById(DisplayId displayId) const {
+ for (const auto& [token, display] : mDisplays) {
+ if (display->getId() == displayId) {
+ return display;
+ }
+ }
+ return nullptr;
+}
+
sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) {
for (const auto& [token, display] : mDisplays) {
if (display->getLayerStack() == layerStack) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e4ff6c9..c6cbc51 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -90,6 +90,7 @@
class Client;
class EventThread;
class FpsReporter;
+class HdrLayerInfoReporter;
class HWComposer;
struct SetInputWindowsListener;
class IGraphicBufferProducer;
@@ -684,6 +685,10 @@
bool* outSupport) const override;
status_t setDisplayBrightness(const sp<IBinder>& displayToken,
const gui::DisplayBrightness& brightness) override;
+ status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) override;
+ status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+ const sp<gui::IHdrLayerInfoListener>& listener) override;
status_t notifyPowerBoost(int32_t boostId) override;
status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
float lightPosY, float lightPosZ, float lightRadius) override;
@@ -908,6 +913,7 @@
bool grayscale, ScreenCaptureResults&);
sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
+ sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock);
sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock);
// If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
@@ -1386,6 +1392,9 @@
sp<IBinder> mDebugFrameRateFlexibilityToken;
BufferCountTracker mBufferCountTracker;
+
+ std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners
+ GUARDED_BY(mStateLock);
};
} // namespace android