summaryrefslogtreecommitdiff
path: root/sdm
diff options
context:
space:
mode:
Diffstat (limited to 'sdm')
-rw-r--r--sdm/libs/hwc2/Android.mk5
-rw-r--r--sdm/libs/hwc2/hwc_display.cpp25
-rw-r--r--sdm/libs/hwc2/hwc_display.h12
-rw-r--r--sdm/libs/hwc2/hwc_display_builtin.cpp54
-rw-r--r--sdm/libs/hwc2/hwc_display_builtin.h20
-rw-r--r--sdm/libs/hwc2/hwc_session.cpp66
-rw-r--r--sdm/libs/hwc2/hwc_session.h2
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);