summaryrefslogtreecommitdiff
path: root/sdm/libs/hwc2
diff options
context:
space:
mode:
authorKevin DuBois <kevindubois@google.com>2018-09-12 11:24:26 -0700
committerlinpeter <linpeter@google.com>2019-11-21 14:24:20 +0800
commit799235ef2abb08ba1f43359df07eb6610113625b (patch)
treed7daad106cdf3fbe0ec2d3dc498e155d86dcf05e /sdm/libs/hwc2
parent0c81b1770a0eef52556d7579ae7694df864c8bc0 (diff)
downloaddisplay-799235ef2abb08ba1f43359df07eb6610113625b.tar.gz
sm7150: cherry pick histogram code from sm8150
This ports the sm8150 code for the histogram collection to the sm7150 code base. This is mostly porting the libhistogram helper library, code is not used. Bug: 143513619 Test: ./color_sampling_test Test: libgui_test --gtest_filter=DisplayedContentSamplingTest* Test: dumpsys SurfaceFlinger Change-Id: I819ed037488fa18e3248ecf5505d80cbe474f233
Diffstat (limited to 'sdm/libs/hwc2')
-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);