diff options
Diffstat (limited to 'sdm')
-rw-r--r-- | sdm/libs/hwc2/Android.mk | 5 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display.cpp | 25 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display.h | 12 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display_builtin.cpp | 54 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_display_builtin.h | 20 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_session.cpp | 66 | ||||
-rw-r--r-- | sdm/libs/hwc2/hwc_session.h | 2 |
7 files changed, 182 insertions, 2 deletions
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk index 042b9cd9..3a7c9bdd 100644 --- a/sdm/libs/hwc2/Android.mk +++ b/sdm/libs/hwc2/Android.mk @@ -39,7 +39,10 @@ LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware li vendor.display.config@1.8 \ vendor.display.config@1.9 \ vendor.display.config@1.10 \ - vendor.display.config@1.11 + vendor.display.config@1.11 \ + libdrm.vendor + +LOCAL_STATIC_LIBRARIES := libhistogram ifeq ($(TARGET_BOARD_AUTO), true) LOCAL_CFLAGS += -DCONFIG_BASEID_FROM_PROP diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp index beeb61fc..67f9fafe 100644 --- a/sdm/libs/hwc2/hwc_display.cpp +++ b/sdm/libs/hwc2/hwc_display.cpp @@ -2314,6 +2314,31 @@ bool HWCDisplay::IsDisplayCommandMode() { return is_cmd_mode_; } +HWC2::Error HWCDisplay::SetDisplayedContentSamplingEnabledVndService(bool enabled) { + return HWC2::Error::Unsupported; +} + +HWC2::Error HWCDisplay::SetDisplayedContentSamplingEnabled(int32_t enabled, + uint8_t component_mask, uint64_t max_frames) { + + DLOGV("Request to start/stop histogram thread not supported on this display"); + return HWC2::Error::Unsupported; +} + +HWC2::Error HWCDisplay::GetDisplayedContentSamplingAttributes(int32_t* format, + int32_t* dataspace, + uint8_t* supported_components) { + return HWC2::Error::Unsupported; +} + +HWC2::Error HWCDisplay::GetDisplayedContentSample(uint64_t max_frames, + uint64_t timestamp, + uint64_t* numFrames, + int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS], + uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) { + return HWC2::Error::Unsupported; +} + // Skip SDM prepare if all the layers in the current draw cycle are marked as Skip and // previous draw cycle had GPU Composition, as the resources for GPU Target layer have // already been validated and configured to the driver. diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h index 84c0eef6..71eb5a45 100644 --- a/sdm/libs/hwc2/hwc_display.h +++ b/sdm/libs/hwc2/hwc_display.h @@ -40,6 +40,7 @@ #include "hwc_layers.h" #include "display_null.h" #include "hwc_display_event_handler.h" +#include "histogram_collector.h" using android::hardware::graphics::common::V1_1::ColorMode; using android::hardware::graphics::common::V1_1::Dataspace; @@ -341,6 +342,17 @@ class HWCDisplay : public DisplayEventHandler { virtual void PostPowerMode(); virtual void NotifyClientStatus(bool connected) { client_connected_ = connected; } + virtual HWC2::Error SetDisplayedContentSamplingEnabledVndService(bool enabled); + virtual HWC2::Error SetDisplayedContentSamplingEnabled(int32_t enabled, uint8_t component_mask, uint64_t max_frames); + virtual HWC2::Error GetDisplayedContentSamplingAttributes(int32_t* format, + int32_t* dataspace, + uint8_t* supported_components); + virtual HWC2::Error GetDisplayedContentSample(uint64_t max_frames, + uint64_t timestamp, + uint64_t* numFrames, + int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS], + uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]); + protected: static uint32_t throttling_refresh_rate_; // Maximum number of layers supported by display manager. diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp index cadac358..ef8ebb50 100644 --- a/sdm/libs/hwc2/hwc_display_builtin.cpp +++ b/sdm/libs/hwc2/hwc_display_builtin.cpp @@ -179,6 +179,7 @@ int HWCDisplayBuiltIn::Init() { } int HWCDisplayBuiltIn::Deinit() { + histogram.stop(); int status = HWCDisplay::Deinit(); if (status) { return status; @@ -189,6 +190,10 @@ int HWCDisplayBuiltIn::Deinit() { return 0; } +std::string HWCDisplayBuiltIn::Dump() { + return HWCDisplay::Dump() + histogram.Dump(); +} + HWC2::Error HWCDisplayBuiltIn::Validate(uint32_t *out_num_types, uint32_t *out_num_requests) { auto status = HWC2::Error::None; DisplayError error = kErrorNone; @@ -877,6 +882,55 @@ DisplayError HWCDisplayBuiltIn::DisablePartialUpdateOneFrame() { return error; } +HWC2::Error HWCDisplayBuiltIn::SetDisplayedContentSamplingEnabledVndService(bool enabled) { + std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex); + vndservice_sampling_vote = enabled; + if (api_sampling_vote || vndservice_sampling_vote) { + histogram.start(); + } else { + histogram.stop(); + } + return HWC2::Error::None; +} + +HWC2::Error HWCDisplayBuiltIn::SetDisplayedContentSamplingEnabled(int32_t enabled, uint8_t component_mask, uint64_t max_frames) { + if ((enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) && + (enabled != HWC2_DISPLAYED_CONTENT_SAMPLING_DISABLE)) + return HWC2::Error::BadParameter; + + std::unique_lock<decltype(sampling_mutex)> lk(sampling_mutex); + if (enabled == HWC2_DISPLAYED_CONTENT_SAMPLING_ENABLE) { + api_sampling_vote = true; + } else { + api_sampling_vote = false; + } + + auto start = api_sampling_vote || vndservice_sampling_vote; + if (start && max_frames == 0) { + histogram.start(); + } else if (start) { + histogram.start(max_frames); + } else { + histogram.stop(); + } + return HWC2::Error::None; +} + +HWC2::Error HWCDisplayBuiltIn::GetDisplayedContentSamplingAttributes(int32_t* format, + int32_t* dataspace, + uint8_t* supported_components) { + return histogram.getAttributes(format, dataspace, supported_components); +} + +HWC2::Error HWCDisplayBuiltIn::GetDisplayedContentSample(uint64_t max_frames, + uint64_t timestamp, + uint64_t* numFrames, + int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS], + uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) +{ + histogram.collect(max_frames, timestamp, samples_size, samples, numFrames); + return HWC2::Error::None; +} DisplayError HWCDisplayBuiltIn::SetMixerResolution(uint32_t width, uint32_t height) { DisplayError error = display_intf_->SetMixerResolution(width, height); diff --git a/sdm/libs/hwc2/hwc_display_builtin.h b/sdm/libs/hwc2/hwc_display_builtin.h index eeeb9c38..3e9e6ebe 100644 --- a/sdm/libs/hwc2/hwc_display_builtin.h +++ b/sdm/libs/hwc2/hwc_display_builtin.h @@ -32,6 +32,7 @@ #include <string> #include <vector> +#include <mutex> #include "cpuhint.h" #include "hwc_display.h" @@ -55,7 +56,7 @@ class HWCDisplayBuiltIn : public HWCDisplay { HWCDisplay **hwc_display); static void Destroy(HWCDisplay *hwc_display); virtual int Init(); - virtual int Deinit(); + virtual int Deinit() override; virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests); virtual HWC2::Error Present(int32_t *out_retire_fence); virtual HWC2::Error CommitLayerStack(); @@ -98,6 +99,16 @@ class HWCDisplayBuiltIn : public HWCDisplay { virtual HWC2::Error UpdatePowerMode(HWC2::PowerMode mode); virtual HWC2::Error PostCommitLayerStack(int32_t *out_retire_fence); + virtual HWC2::Error SetDisplayedContentSamplingEnabledVndService(bool enabled); + virtual HWC2::Error SetDisplayedContentSamplingEnabled(int32_t enabled, uint8_t component_mask, uint64_t max_frames) override; + virtual HWC2::Error GetDisplayedContentSamplingAttributes(int32_t* format, int32_t* dataspace, + uint8_t* supported_components) override; + virtual HWC2::Error GetDisplayedContentSample(uint64_t max_frames, + uint64_t timestamp, uint64_t* numFrames, + int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS], + uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) override; + std::string Dump() override; + private: HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator, HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler, @@ -152,6 +163,13 @@ class HWCDisplayBuiltIn : public HWCDisplay { // PMIC interface to notify secure display start/end PMICInterface *pmic_intf_ = nullptr; bool pmic_notification_pending_ = false; + + // Members for Color sampling feature + histogram::HistogramCollector histogram; + std::mutex sampling_mutex; + bool api_sampling_vote = false; + bool vndservice_sampling_vote = false; + }; } // namespace sdm diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp index 7b60720d..d0a6c59c 100644 --- a/sdm/libs/hwc2/hwc_session.cpp +++ b/sdm/libs/hwc2/hwc_session.cpp @@ -677,6 +677,39 @@ static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t di num_elements, keys, metadata); } +static int32_t SetDisplayedContentSamplingEnabled(hwc2_device_t* device, + hwc2_display_t display, + int32_t enabled, uint8_t component_mask, + uint64_t max_frames) { + static constexpr int32_t validComponentMask = + HWC2_FORMAT_COMPONENT_0 | HWC2_FORMAT_COMPONENT_1 | + HWC2_FORMAT_COMPONENT_2 | HWC2_FORMAT_COMPONENT_3; + if (component_mask & ~validComponentMask) return HWC2_ERROR_BAD_PARAMETER; + return HWCSession::CallDisplayFunction(device, display, + &HWCDisplay::SetDisplayedContentSamplingEnabled, + enabled, component_mask, max_frames); +} + +static int32_t GetDisplayedContentSamplingAttributes(hwc2_device_t* device, + hwc2_display_t display, + int32_t* format, + int32_t* dataspace, + uint8_t* supported_components) { + return HWCSession::CallDisplayFunction(device, display, + &HWCDisplay::GetDisplayedContentSamplingAttributes, + format, dataspace, supported_components); +} + +static int32_t GetDisplayedContentSample( + hwc2_device_t* device, hwc2_display_t display, uint64_t max_frames, uint64_t timestamp, + uint64_t* numFrames, + int32_t samples_size[NUM_HISTOGRAM_COLOR_COMPONENTS], + uint64_t* samples[NUM_HISTOGRAM_COLOR_COMPONENTS]) { + + return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetDisplayedContentSample, + max_frames, timestamp, numFrames, samples_size, samples); +} + static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display, hwc2_config_t config, int32_t int_attribute, int32_t *out_value) { @@ -1297,6 +1330,12 @@ hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device, return AsFP<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(HWCSession::GetDisplayCapabilities); case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport: return AsFP<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(HWCSession::GetDisplayBrightnessSupport); + case HWC2::FunctionDescriptor::SetDisplayedContentSamplingEnabled: + return AsFP<HWC2_PFN_SET_DISPLAYED_CONTENT_SAMPLING_ENABLED>(SetDisplayedContentSamplingEnabled); + case HWC2::FunctionDescriptor::GetDisplayedContentSamplingAttributes: + return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES>(GetDisplayedContentSamplingAttributes); + case HWC2::FunctionDescriptor::GetDisplayedContentSample: + return AsFP<HWC2_PFN_GET_DISPLAYED_CONTENT_SAMPLE>(GetDisplayedContentSample); default: DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor, to_string(descriptor).c_str()); @@ -1661,6 +1700,14 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa status = SetQSyncMode(input_parcel); break; + case qService::IQService::SET_COLOR_SAMPLING_ENABLED: + if (!input_parcel) { + DLOGE("QService command = %d: input_parcel needed.", command); + break; + } + status = setColorSamplingEnabled(input_parcel); + break; + case qService::IQService::SET_IDLE_PC: if (!input_parcel) { DLOGE("QService command = %d: input_parcel needed.", command); @@ -1758,6 +1805,25 @@ android::status_t HWCSession::GetDisplayAttributesForConfig(const android::Parce return error; } +android::status_t HWCSession::setColorSamplingEnabled(const android::Parcel* input_parcel) +{ + int dpy = input_parcel->readInt32(); + int enabled_cmd = input_parcel->readInt32(); + if (dpy < HWC_DISPLAY_PRIMARY || dpy >= HWC_NUM_DISPLAY_TYPES || + enabled_cmd < 0 || enabled_cmd > 1) { + return android::BAD_VALUE; + } + + SEQUENCE_WAIT_SCOPE_LOCK(locker_[dpy]); + if (!hwc_display_[dpy]) { + DLOGW("No display id %i active to enable histogram event", dpy); + return android::BAD_VALUE; + } + + auto error = hwc_display_[dpy]->SetDisplayedContentSamplingEnabledVndService(enabled_cmd); + return (error == HWC2::Error::None) ? android::OK : android::BAD_VALUE; +} + android::status_t HWCSession::ConfigureRefreshRate(const android::Parcel *input_parcel) { SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]); diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h index e19a1667..965e29a5 100644 --- a/sdm/libs/hwc2/hwc_session.h +++ b/sdm/libs/hwc2/hwc_session.h @@ -368,6 +368,8 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli android::Parcel *output_parcel); android::status_t SetPanelLuminanceAttributes(const android::Parcel *input_parcel); + android::status_t setColorSamplingEnabled(const android::Parcel *input_parcel); + void Refresh(hwc2_display_t display); void HotPlug(hwc2_display_t display, HWC2::Connection state); |