blob: 4be49b205a8112d2b973a2547a9664073b403aff [file] [log] [blame]
/*
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright 2015 The Android Open Source Project
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* 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.
*/
/*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __HWC_SESSION_H__
#define __HWC_SESSION_H__
#include <vendor/qti/hardware/display/composer/3.1/IQtiComposerClient.h>
#include <config/device_interface.h>
#include <aidl/vendor/qti/hardware/display/config/BnDisplayConfig.h>
#include <aidl/vendor/qti/hardware/display/config/BnDisplayConfigCallback.h>
#include <binder/Status.h>
#include <core/core_interface.h>
#include <core/ipc_interface.h>
#include <utils/locker.h>
#include <utils/constants.h>
#include <display_config.h>
#include <vector>
#include <queue>
#include <utility>
#include <future> // NOLINT
#include <map>
#include <unordered_map>
#include <string>
#include <memory>
#include <atomic>
#include <core/display_interface.h>
#include "hwc_callbacks.h"
#include "hwc_layers.h"
#include "hwc_display.h"
#include "hwc_display_builtin.h"
#include "hwc_display_pluggable.h"
#include "hwc_display_dummy.h"
#include "hwc_display_virtual.h"
#include "hwc_display_pluggable_test.h"
#include "hwc_color_manager.h"
#include "hwc_socket_handler.h"
#include "hwc_display_event_handler.h"
#include "hwc_buffer_sync_handler.h"
#include "hwc_display_virtual_factory.h"
using ::android::hardware::Return;
using ::android::hardware::hidl_string;
using android::hardware::hidl_handle;
using ::android::hardware::hidl_vec;
using ::android::sp;
using ::android::hardware::Void;
namespace composer_V2_3 = ::android::hardware::graphics::composer::V2_3;
namespace composer_V2_4 = ::android::hardware::graphics::composer::V2_4;
using HwcDisplayCapability = composer_V2_4::IComposerClient::DisplayCapability;
using HwcDisplayConnectionType = composer_V2_4::IComposerClient::DisplayConnectionType;
using HwcClientTargetProperty = composer_V2_4::IComposerClient::ClientTargetProperty;
using ::aidl::vendor::qti::hardware::display::config::IDisplayConfig;
using ::aidl::vendor::qti::hardware::display::config::IDisplayConfigCallback;
using ::aidl::vendor::qti::hardware::display::config::CameraSmoothOp;
using ::aidl::vendor::qti::hardware::display::config::Attributes;
using ::aidl::vendor::qti::hardware::display::config::DisplayPortType;
namespace aidl::vendor::qti::hardware::display::config {
class DisplayConfigAIDL;
}
namespace sdm {
using vendor::qti::hardware::display::composer::V3_1::IQtiComposerClient;
int32_t GetDataspaceFromColorMode(ColorMode mode);
typedef DisplayConfig::DisplayType DispType;
// Create a singleton uevent listener thread valid for life of hardware composer process.
// This thread blocks on uevents poll inside uevent library implementation. This poll exits
// only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle
// of this thread with HWC session cause HWC deinitialization to wait infinitely for the
// thread to exit.
class HWCUEventListener {
public:
virtual ~HWCUEventListener() {}
virtual void UEventHandler(int connected) = 0;
int connected = -1;
int hpd_bpp_ = 0;
int hpd_pattern_ = 0;
std::atomic<int> uevent_counter_ = 0;
};
class HWCUEvent {
public:
HWCUEvent();
static void UEventThreadTop(HWCUEvent *hwc_event);
static void UEventThreadBottom(HWCUEvent *hwc_event);
void Register(HWCUEventListener *uevent_listener);
inline bool InitDone() { return init_done_; }
private:
std::mutex mutex_;
std::condition_variable caller_cv_;
std::mutex evt_mutex_;
std::condition_variable evt_cv_;
HWCUEventListener *uevent_listener_ = nullptr;
bool init_done_ = false;
};
constexpr int32_t kDataspaceSaturationMatrixCount = 16;
constexpr int32_t kDataspaceSaturationPropertyElements = 9;
constexpr int32_t kPropertyMax = 256;
class HWCSession : hwc2_device_t, HWCUEventListener, public qClient::BnQClient,
public HWCDisplayEventHandler, public DisplayConfig::ClientContext {
friend class aidl::vendor::qti::hardware::display::config::DisplayConfigAIDL;
public:
enum HotPlugEvent {
kHotPlugNone,
kHotPlugEvent,
};
enum ClientCommitDone {
kClientPartialUpdate,
kClientIdlepowerCollapse,
kClientTeardownCWB,
kClientTrustedUI,
kClientMax
};
HWCSession();
int Init();
int Deinit();
HWC2::Error CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
hwc2_display_t *out_display_id);
template <typename... Args>
int32_t CallDisplayFunction(hwc2_display_t display, HWC2::Error (HWCDisplay::*member)(Args...),
Args... args) {
if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
{
// Power state transition start.
SCOPE_LOCK(power_state_[display]);
if (power_state_transition_[display]) {
display = map_hwc_display_.find(display)->second;
}
}
SCOPE_LOCK(locker_[display]);
auto status = HWC2::Error::BadDisplay;
if (hwc_display_[display]) {
auto hwc_display = hwc_display_[display];
status = (hwc_display->*member)(std::forward<Args>(args)...);
}
return INT32(status);
}
template <typename... Args>
int32_t CallLayerFunction(hwc2_display_t display, hwc2_layer_t layer,
HWC2::Error (HWCLayer::*member)(Args...), Args... args) {
if (display >= HWCCallbacks::kNumDisplays) {
return HWC2_ERROR_BAD_DISPLAY;
}
{
// Power state transition start.
SCOPE_LOCK(power_state_[display]);
if (power_state_transition_[display]) {
display = map_hwc_display_.find(display)->second;
}
}
SCOPE_LOCK(locker_[display]);
auto status = HWC2::Error::BadDisplay;
if (hwc_display_[display]) {
status = HWC2::Error::BadLayer;
auto hwc_layer = hwc_display_[display]->GetHWCLayer(layer);
if (hwc_layer != nullptr) {
status = (hwc_layer->*member)(std::forward<Args>(args)...);
}
}
return INT32(status);
}
// HWC2 Functions that require a concrete implementation in hwc session
// and hence need to be member functions
static HWCSession *GetInstance();
void GetCapabilities(uint32_t *outCount, int32_t *outCapabilities);
void Dump(uint32_t *out_size, char *out_buffer);
int32_t AcceptDisplayChanges(hwc2_display_t display);
int32_t CreateLayer(hwc2_display_t display, hwc2_layer_t *out_layer_id);
int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format,
hwc2_display_t *out_display_id);
int32_t DestroyLayer(hwc2_display_t display, hwc2_layer_t layer);
int32_t DestroyVirtualDisplay(hwc2_display_t display);
int32_t PresentDisplay(hwc2_display_t display, shared_ptr<Fence> *out_retire_fence);
void RegisterCallback(int32_t descriptor, hwc2_callback_data_t callback_data,
hwc2_function_pointer_t pointer);
int32_t SetOutputBuffer(hwc2_display_t display, buffer_handle_t buffer,
const shared_ptr<Fence> &release_fence);
int32_t SetPowerMode(hwc2_display_t display, int32_t int_mode);
int32_t SetColorMode(hwc2_display_t display, int32_t /*ColorMode*/ int_mode);
int32_t SetColorModeWithRenderIntent(hwc2_display_t display, int32_t /*ColorMode*/ int_mode,
int32_t /*RenderIntent*/ int_render_intent);
int32_t SetColorTransform(hwc2_display_t display, const float *matrix,
int32_t /*android_color_transform_t*/ hint);
int32_t GetReadbackBufferAttributes(hwc2_display_t display,
int32_t *format, int32_t *dataspace);
int32_t SetReadbackBuffer(hwc2_display_t display, const native_handle_t *buffer,
const shared_ptr<Fence> &acquire_fence);
int32_t GetReadbackBufferFence(hwc2_display_t display, shared_ptr<Fence> *release_fence);
uint32_t GetMaxVirtualDisplayCount();
int32_t GetDisplayIdentificationData(hwc2_display_t display, uint8_t *outPort,
uint32_t *outDataSize, uint8_t *outData);
int32_t GetDisplayCapabilities(hwc2_display_t display,
hidl_vec<HwcDisplayCapability> *capabilities);
int32_t GetDisplayBrightnessSupport(hwc2_display_t display, bool *outSupport);
int32_t SetDisplayBrightness(hwc2_display_t display, float brightness);
int32_t WaitForResources(bool wait_for_resources, hwc2_display_t active_builtin_id,
hwc2_display_t display_id);
// newly added
int32_t GetDisplayType(hwc2_display_t display, int32_t *out_type);
int32_t GetDisplayAttribute(hwc2_display_t display, hwc2_config_t config, HwcAttribute attribute,
int32_t *out_value);
int32_t GetActiveConfig(hwc2_display_t display, hwc2_config_t *out_config);
int32_t GetColorModes(hwc2_display_t display, uint32_t *out_num_modes,
int32_t /*ColorMode*/ *int_out_modes);
int32_t GetRenderIntents(hwc2_display_t display, int32_t /*ColorMode*/ int_mode,
uint32_t *out_num_intents, int32_t /*RenderIntent*/ *int_out_intents);
int32_t GetHdrCapabilities(hwc2_display_t display, uint32_t* out_num_types, int32_t* out_types,
float* out_max_luminance, float* out_max_average_luminance,
float* out_min_luminance);
int32_t GetPerFrameMetadataKeys(hwc2_display_t display, uint32_t *out_num_keys,
int32_t *int_out_keys);
int32_t GetClientTargetSupport(hwc2_display_t display, uint32_t width, uint32_t height,
int32_t format, int32_t dataspace);
int32_t GetDisplayName(hwc2_display_t display, uint32_t *out_size, char *out_name);
int32_t SetActiveConfig(hwc2_display_t display, hwc2_config_t config);
int32_t GetChangedCompositionTypes(hwc2_display_t display, uint32_t *out_num_elements,
hwc2_layer_t *out_layers, int32_t *out_types);
int32_t GetDisplayRequests(hwc2_display_t display, int32_t *out_display_requests,
uint32_t *out_num_elements, hwc2_layer_t *out_layers,
int32_t *out_layer_requests);
int32_t GetReleaseFences(hwc2_display_t display, uint32_t *out_num_elements,
hwc2_layer_t *out_layers, std::vector<shared_ptr<Fence>> *out_fences);
int32_t SetClientTarget(hwc2_display_t display, buffer_handle_t target,
shared_ptr<Fence> acquire_fence,
int32_t dataspace, hwc_region_t damage);
int32_t SetClientTarget_3_1(hwc2_display_t display, buffer_handle_t target,
shared_ptr<Fence> acquire_fence,
int32_t dataspace, hwc_region_t damage);
int32_t SetCursorPosition(hwc2_display_t display, hwc2_layer_t layer, int32_t x, int32_t y);
int32_t GetDataspaceSaturationMatrix(int32_t /*Dataspace*/ int_dataspace, float *out_matrix);
int32_t SetDisplayBrightnessScale(const android::Parcel *input_parcel);
int32_t GetDisplayConnectionType(hwc2_display_t display, HwcDisplayConnectionType *type);
int32_t SetDimmingEnable(hwc2_display_t display, int32_t int_enabled);
int32_t SetDimmingMinBl(hwc2_display_t display, int32_t min_bl);
int32_t GetClientTargetProperty(hwc2_display_t display,
HwcClientTargetProperty *outClientTargetProperty);
// Layer functions
int32_t SetLayerBuffer(hwc2_display_t display, hwc2_layer_t layer, buffer_handle_t buffer,
const shared_ptr<Fence> &acquire_fence);
int32_t SetLayerBlendMode(hwc2_display_t display, hwc2_layer_t layer, int32_t int_mode);
int32_t SetLayerDisplayFrame(hwc2_display_t display, hwc2_layer_t layer, hwc_rect_t frame);
int32_t SetLayerPlaneAlpha(hwc2_display_t display, hwc2_layer_t layer, float alpha);
int32_t SetLayerSourceCrop(hwc2_display_t display, hwc2_layer_t layer, hwc_frect_t crop);
int32_t SetLayerTransform(hwc2_display_t display, hwc2_layer_t layer, int32_t int_transform);
int32_t SetLayerZOrder(hwc2_display_t display, hwc2_layer_t layer, uint32_t z);
int32_t SetLayerType(hwc2_display_t display, hwc2_layer_t layer,
IQtiComposerClient::LayerType type);
int32_t SetLayerFlag(hwc2_display_t display, hwc2_layer_t layer,
IQtiComposerClient::LayerFlag flag);
int32_t SetLayerSurfaceDamage(hwc2_display_t display, hwc2_layer_t layer, hwc_region_t damage);
int32_t SetLayerVisibleRegion(hwc2_display_t display, hwc2_layer_t layer, hwc_region_t damage);
int32_t SetLayerCompositionType(hwc2_display_t display, hwc2_layer_t layer, int32_t int_type);
int32_t SetLayerColor(hwc2_display_t display, hwc2_layer_t layer, hwc_color_t color);
int32_t SetLayerDataspace(hwc2_display_t display, hwc2_layer_t layer, int32_t dataspace);
int32_t SetLayerPerFrameMetadata(hwc2_display_t display, hwc2_layer_t layer,
uint32_t num_elements, const int32_t *int_keys,
const float *metadata);
int32_t SetLayerColorTransform(hwc2_display_t display, hwc2_layer_t layer, const float *matrix);
int32_t SetLayerPerFrameMetadataBlobs(hwc2_display_t display, hwc2_layer_t layer,
uint32_t num_elements, const int32_t *int_keys,
const uint32_t *sizes, const uint8_t *metadata);
int32_t SetDisplayedContentSamplingEnabled(hwc2_display_t display, int32_t enabled,
uint8_t component_mask, uint64_t max_frames);
int32_t GetDisplayedContentSamplingAttributes(hwc2_display_t display, int32_t *format,
int32_t *dataspace, uint8_t *supported_components);
int32_t GetDisplayedContentSample(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]);
int32_t SetDisplayElapseTime(hwc2_display_t display, uint64_t time);
int SetCameraSmoothInfo(CameraSmoothOp op, int32_t fps);
int RegisterCallbackClient(const std::shared_ptr<IDisplayConfigCallback>& callback,
int64_t *client_handle);
int UnregisterCallbackClient(const int64_t client_handle);
int NotifyResolutionChange(int32_t disp_id, Attributes& attr);
virtual int RegisterClientContext(std::shared_ptr<DisplayConfig::ConfigCallback> callback,
DisplayConfig::ConfigInterface **intf);
virtual void UnRegisterClientContext(DisplayConfig::ConfigInterface *intf);
// HWCDisplayEventHandler
virtual void DisplayPowerReset();
virtual void PerformDisplayPowerReset();
virtual void PerformQsyncCallback(hwc2_display_t display, bool qsync_enabled,
uint32_t refresh_rate, uint32_t qsync_refresh_rate);
virtual void VmReleaseDone(hwc2_display_t display);
virtual int NotifyCwbDone(hwc2_display_t display, int32_t status, uint64_t handle_id);
int32_t SetVsyncEnabled(hwc2_display_t display, int32_t int_enabled);
int32_t GetDozeSupport(hwc2_display_t display, int32_t *out_support);
int32_t GetDisplayConfigs(hwc2_display_t display, uint32_t *out_num_configs,
hwc2_config_t *out_configs);
int32_t GetVsyncPeriod(hwc2_display_t disp, uint32_t *vsync_period);
void Refresh(hwc2_display_t display);
int32_t GetDisplayVsyncPeriod(hwc2_display_t display, VsyncPeriodNanos *out_vsync_period);
int32_t SetActiveConfigWithConstraints(
hwc2_display_t display, hwc2_config_t config,
const VsyncPeriodChangeConstraints *vsync_period_change_constraints,
VsyncPeriodChangeTimeline *out_timeline);
HWC2::Error CommitOrPrepare(hwc2_display_t display, bool validate_only,
shared_ptr<Fence> *out_retire_fence,
uint32_t *out_num_types, uint32_t *out_num_requests,
bool *needs_commit);
HWC2::Error TryDrawMethod(hwc2_display_t display, IQtiComposerClient::DrawMethod drawMethod);
static Locker locker_[HWCCallbacks::kNumDisplays];
static Locker power_state_[HWCCallbacks::kNumDisplays];
static Locker hdr_locker_[HWCCallbacks::kNumDisplays];
static Locker display_config_locker_;
static std::mutex command_seq_mutex_;
static std::bitset<kClientMax> clients_waiting_for_commit_[HWCCallbacks::kNumDisplays];
static shared_ptr<Fence> retire_fence_[HWCCallbacks::kNumDisplays];
static int commit_error_[HWCCallbacks::kNumDisplays];
static Locker vm_release_locker_[HWCCallbacks::kNumDisplays];
static std::bitset<HWCCallbacks::kNumDisplays> clients_waiting_for_vm_release_;
private:
class CWB {
public:
explicit CWB(HWCSession *hwc_session) : hwc_session_(hwc_session) { }
int32_t PostBuffer(std::weak_ptr<DisplayConfig::ConfigCallback> callback,
const CwbConfig &cwb_config, const native_handle_t *buffer,
hwc2_display_t display_type);
bool IsCwbActiveOnDisplay(hwc2_display_t disp_type);
int OnCWBDone(hwc2_display_t display_type, int32_t status, uint64_t handle_id);
private:
enum CWBNotifiedStatus {
kCwbNotifiedFailure = -1,
kCwbNotifiedSuccess,
kCwbNotifiedNone,
};
struct QueueNode {
QueueNode(std::weak_ptr<DisplayConfig::ConfigCallback> cb, const CwbConfig &cwb_conf,
const hidl_handle &buf, hwc2_display_t disp_type, uint64_t buf_id)
: callback(cb), cwb_config(cwb_conf), buffer(buf), display_type(disp_type),
handle_id(buf_id) {}
std::weak_ptr<DisplayConfig::ConfigCallback> callback;
CwbConfig cwb_config = {};
const native_handle_t *buffer;
hwc2_display_t display_type;
uint64_t handle_id;
CWBNotifiedStatus notified_status = kCwbNotifiedNone;
bool request_completed = false;
};
struct DisplayCWBSession{
std::deque<QueueNode *> queue;
std::mutex lock;
std::condition_variable cv;
std::future<void> future;
bool async_thread_running = false;
};
static void AsyncTaskToProcessCWBStatus(CWB *cwb, hwc2_display_t display_type);
void ProcessCWBStatus(hwc2_display_t display_type);
void NotifyCWBStatus(int status, QueueNode *cwb_node);
std::map<hwc2_display_t, DisplayCWBSession> display_cwb_session_map_;
HWCSession *hwc_session_ = nullptr;
};
class DisplayConfigImpl: public DisplayConfig::ConfigInterface {
public:
explicit DisplayConfigImpl(std::weak_ptr<DisplayConfig::ConfigCallback> callback,
HWCSession *hwc_session);
private:
virtual int IsDisplayConnected(DispType dpy, bool *connected);
virtual int SetDisplayStatus(DispType dpy, DisplayConfig::ExternalStatus status);
virtual int ConfigureDynRefreshRate(DisplayConfig::DynRefreshRateOp op, uint32_t refresh_rate);
virtual int GetConfigCount(DispType dpy, uint32_t *count);
virtual int GetActiveConfig(DispType dpy, uint32_t *config);
virtual int SetActiveConfig(DispType dpy, uint32_t config);
virtual int GetDisplayAttributes(uint32_t config_index, DispType dpy,
DisplayConfig::Attributes *attributes);
virtual int SetPanelBrightness(uint32_t level);
virtual int GetPanelBrightness(uint32_t *level);
virtual int MinHdcpEncryptionLevelChanged(DispType dpy, uint32_t min_enc_level);
virtual int RefreshScreen();
virtual int ControlPartialUpdate(DispType dpy, bool enable);
virtual int ToggleScreenUpdate(bool on);
virtual int SetIdleTimeout(uint32_t value);
virtual int GetHDRCapabilities(DispType dpy, DisplayConfig::HDRCapsParams *caps);
virtual int SetCameraLaunchStatus(uint32_t on);
virtual int DisplayBWTransactionPending(bool *status);
virtual int SetDisplayAnimating(uint64_t display_id, bool animating);
virtual int ControlIdlePowerCollapse(bool enable, bool synchronous);
virtual int GetWriteBackCapabilities(bool *is_wb_ubwc_supported);
virtual int SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start, uint32_t h_end,
uint32_t v_start, uint32_t v_end, uint32_t factor_in,
uint32_t factor_out);
virtual int UpdateVSyncSourceOnPowerModeOff();
virtual int UpdateVSyncSourceOnPowerModeDoze();
virtual int SetPowerMode(uint32_t disp_id, DisplayConfig::PowerMode power_mode);
virtual int IsPowerModeOverrideSupported(uint32_t disp_id, bool *supported);
virtual int IsHDRSupported(uint32_t disp_id, bool *supported);
virtual int IsWCGSupported(uint32_t disp_id, bool *supported);
virtual int SetLayerAsMask(uint32_t disp_id, uint64_t layer_id);
virtual int GetDebugProperty(const std::string prop_name, std::string value) {return -EINVAL;}
virtual int GetDebugProperty(const std::string prop_name, std::string *value);
virtual int GetActiveBuiltinDisplayAttributes(DisplayConfig::Attributes *attr);
virtual int SetPanelLuminanceAttributes(uint32_t disp_id, float min_lum, float max_lum);
virtual int IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin);
virtual int IsAsyncVDSCreationSupported(bool *supported);
virtual int CreateVirtualDisplay(uint32_t width, uint32_t height, int format);
virtual int GetSupportedDSIBitClks(uint32_t disp_id,
std::vector<uint64_t> bit_clks) {return -EINVAL;}
virtual int GetSupportedDSIBitClks(uint32_t disp_id, std::vector<uint64_t> *bit_clks);
virtual int GetDSIClk(uint32_t disp_id, uint64_t *bit_clk);
virtual int SetDSIClk(uint32_t disp_id, uint64_t bit_clk);
virtual int SetCWBOutputBuffer(uint32_t disp_id, const DisplayConfig::Rect rect,
bool post_processed, const native_handle_t *buffer);
virtual int SetQsyncMode(uint32_t disp_id, DisplayConfig::QsyncMode mode);
virtual int IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart);
virtual int IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported);
virtual int ControlQsyncCallback(bool enable);
virtual int GetDisplayHwId(uint32_t disp_id, uint32_t *display_hw_id);
virtual int SendTUIEvent(DispType dpy, DisplayConfig::TUIEventType event_type);
virtual int GetSupportedDisplayRefreshRates(DispType dpy,
std::vector<uint32_t> *supported_refresh_rates);
virtual int IsRCSupported(uint32_t disp_id, bool *supported);
virtual int IsSupportedConfigSwitch(uint32_t disp_id, uint32_t config, bool *supported);
virtual int ControlIdleStatusCallback(bool enable);
virtual int GetDisplayType(uint64_t physical_disp_id, DispType *disp_type);
virtual int AllowIdleFallback();
std::weak_ptr<DisplayConfig::ConfigCallback> callback_;
HWCSession *hwc_session_ = nullptr;
};
struct DisplayMapInfo {
hwc2_display_t client_id = HWCCallbacks::kNumDisplays; // mapped sf id for this display
int32_t sdm_id = -1; // sdm id for this display
sdm:: DisplayType disp_type = kDisplayTypeMax; // sdm display type
bool test_pattern = false; // display will show test pattern
void Reset() {
// Do not clear client id
sdm_id = -1;
disp_type = kDisplayTypeMax;
test_pattern = false;
}
};
static const int kExternalConnectionTimeoutMs = 500;
static const int kVmReleaseTimeoutMs = 100;
static const int kCommitDoneTimeoutMs = 100;
static const int kVmReleaseRetry = 3;
static const int kDenomNstoMs = 1000000;
static const int kNumDrawCycles = 3;
uint32_t throttling_refresh_rate_ = 60;
std::mutex hotplug_mutex_;
std::condition_variable hotplug_cv_;
bool resource_ready_ = false;
hwc2_display_t active_display_id_ = 0;
shared_ptr<Fence> cached_retire_fence_ = nullptr;
void UpdateThrottlingRate();
void SetNewThrottlingRate(uint32_t new_rate);
void ResetPanel();
void InitSupportedDisplaySlots();
void InitSupportedNullDisplaySlots();
int GetDisplayIndex(int dpy);
int CreatePrimaryDisplay();
void CreateDummyDisplay(hwc2_display_t client_id);
int HandleBuiltInDisplays();
int HandlePluggableDisplays(bool delay_hotplug);
int HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool delay_hotplug);
int HandleDisconnectedDisplays(HWDisplaysInfo *hw_displays_info);
void DestroyDisplay(DisplayMapInfo *map_info);
void DestroyPluggableDisplay(DisplayMapInfo *map_info);
void DestroyNonPluggableDisplay(DisplayMapInfo *map_info);
int GetConfigCount(int disp_id, uint32_t *count);
int GetActiveConfigIndex(int disp_id, uint32_t *config);
int SetActiveConfigIndex(int disp_id, uint32_t config);
int SetNoisePlugInOverride(int32_t disp_id, bool override_en, int32_t attn,
int32_t noise_zpos);
int ControlPartialUpdate(int dpy, bool enable);
int DisplayBWTransactionPending(bool *status);
int SetDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status);
int MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level);
int IsWbUbwcSupported(bool *value);
int SetIdleTimeout(uint32_t value);
int ToggleScreenUpdate(bool on);
int SetCameraLaunchStatus(uint32_t on);
int SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start, uint32_t h_end,
uint32_t v_start, uint32_t v_end, uint32_t factor_in,
uint32_t factor_out);
int ControlIdlePowerCollapse(bool enable, bool synchronous);
int GetSupportedDisplayRefreshRates(int disp_id, std::vector<uint32_t> *supported_refresh_rates);
int32_t SetDynamicDSIClock(int64_t disp_id, uint32_t bitrate);
int32_t getDisplayBrightness(uint32_t display, float *brightness);
int32_t setDisplayBrightness(uint32_t display, float brightness);
int32_t getDisplayMaxBrightness(uint32_t display, uint32_t *max_brightness_level);
bool HasHDRSupport(HWCDisplay *hwc_display);
void PostInit();
int GetDispTypeFromPhysicalId(uint64_t physical_disp_id, DispType *disp_type);
#ifdef PROFILE_COVERAGE_DATA
android::status_t DumpCodeCoverage(const android::Parcel *input_parcel);
#endif
// Uevent handler
virtual void UEventHandler(int connected);
// service methods
void StartServices();
// QClient methods
virtual android::status_t notifyCallback(uint32_t command, const android::Parcel *input_parcel,
android::Parcel *output_parcel);
void DynamicDebug(const android::Parcel *input_parcel);
android::status_t SetFrameDumpConfig(const android::Parcel *input_parcel);
android::status_t SetMaxMixerStages(const android::Parcel *input_parcel);
android::status_t SetDisplayMode(const android::Parcel *input_parcel);
android::status_t ConfigureRefreshRate(const android::Parcel *input_parcel);
android::status_t QdcmCMDHandler(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t QdcmCMDDispatch(uint32_t display_id,
const PPDisplayAPIPayload &req_payload,
PPDisplayAPIPayload *resp_payload,
PPPendingParams *pending_action);
android::status_t GetDisplayAttributesForConfig(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t GetVisibleDisplayRect(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t SetMixerResolution(const android::Parcel *input_parcel);
android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
android::status_t SetColorModeWithRenderIntentOverride(const android::Parcel *input_parcel);
android::status_t SetColorModeById(const android::Parcel *input_parcel);
android::status_t SetColorModeFromClient(const android::Parcel *input_parcel);
android::status_t getComposerStatus();
android::status_t SetQSyncMode(const android::Parcel *input_parcel);
android::status_t SetIdlePC(const android::Parcel *input_parcel);
android::status_t RefreshScreen(const android::Parcel *input_parcel);
android::status_t SetAd4RoiConfig(const android::Parcel *input_parcel);
android::status_t SetJitterConfig(const android::Parcel *input_parcel);
android::status_t SetDsiClk(const android::Parcel *input_parcel);
android::status_t GetDsiClk(const android::Parcel *input_parcel, android::Parcel *output_parcel);
android::status_t GetSupportedDsiClk(const android::Parcel *input_parcel,
android::Parcel *output_parcel);
android::status_t SetFrameTriggerMode(const android::Parcel *input_parcel);
android::status_t SetPanelLuminanceAttributes(const android::Parcel *input_parcel);
android::status_t setColorSamplingEnabled(const android::Parcel *input_parcel);
android::status_t HandleTUITransition(int disp_id, int event);
android::status_t GetDisplayPortId(uint32_t display, int *port_id);
android::status_t UpdateTransferTime(const android::Parcel *input_parcel);
// Internal methods
void HandleSecureSession();
void HandlePendingPowerMode(hwc2_display_t display, const shared_ptr<Fence> &retire_fence);
void HandlePendingHotplug(hwc2_display_t disp_id, const shared_ptr<Fence> &retire_fence);
bool IsPluggableDisplayConnected();
bool IsVirtualDisplayConnected();
hwc2_display_t GetActiveBuiltinDisplay();
void HandlePendingRefresh();
void NotifyClientStatus(bool connected);
int32_t GetVirtualDisplayId(HWDisplayInfo& info);
android::status_t TUITransitionPrepare(int disp_id);
android::status_t TUITransitionStart(int disp_id);
android::status_t TUITransitionEnd(int disp_id);
android::status_t TUITransitionUnPrepare(int disp_id);
void PerformIdleStatusCallback(hwc2_display_t display);
DispType GetDisplayConfigDisplayType(int qdutils_disp_type);
HWC2::Error TeardownConcurrentWriteback(hwc2_display_t display);
void PostCommitUnlocked(hwc2_display_t display, const shared_ptr<Fence> &retire_fence);
void PostCommitLocked(hwc2_display_t display, shared_ptr<Fence> &retire_fence);
int WaitForCommitDone(hwc2_display_t display, int client_id);
int WaitForCommitDoneAsync(hwc2_display_t display, int client_id);
void NotifyDisplayAttributes(hwc2_display_t display, hwc2_config_t config);
int WaitForVmRelease(hwc2_display_t display, int timeout_ms);
void GetVirtualDisplayList();
HWC2::Error CheckWbAvailability();
CoreInterface *core_intf_ = nullptr;
HWCDisplay *hwc_display_[HWCCallbacks::kNumDisplays] = {nullptr};
QSyncMode hwc_display_qsync_[HWCCallbacks::kNumDisplays] = {QSyncMode::kQSyncModeNone};
uint32_t idle_time_active_ms_ = 0;
uint32_t idle_time_inactive_ms_ = 0;
HWCCallbacks callbacks_;
HWCBufferAllocator buffer_allocator_;
HWCVirtualDisplayFactory virtual_display_factory_;
HWCColorManager *color_mgr_ = nullptr;
DisplayMapInfo map_info_primary_; // Primary display (either builtin or pluggable)
std::vector<DisplayMapInfo> map_info_builtin_; // Builtin displays excluding primary
std::vector<DisplayMapInfo> map_info_pluggable_; // Pluggable displays excluding primary
std::vector<DisplayMapInfo> map_info_virtual_; // Virtual displays
bool update_vsync_on_power_off_ = false;
bool update_vsync_on_doze_ = false;
std::vector<bool> is_hdr_display_; // info on HDR supported
std::map <hwc2_display_t, hwc2_display_t> map_hwc_display_; // Real and dummy display pairs.
bool reset_panel_ = false;
bool client_connected_ = false;
bool new_bw_mode_ = false;
int bw_mode_release_fd_ = -1;
qService::QService *qservice_ = nullptr;
HWCSocketHandler socket_handler_;
bool hdmi_is_primary_ = false;
bool is_composer_up_ = false;
std::mutex mutex_lum_;
static bool pending_power_mode_[HWCCallbacks::kNumDisplays];
static int null_display_mode_;
HotPlugEvent pending_hotplug_event_ = kHotPlugNone;
struct VirtualDisplayData {
uint32_t width;
uint32_t height;
int32_t format;
bool in_use = false;
};
std::unordered_map<hwc2_display_t, VirtualDisplayData> virtual_id_map_;
Locker pluggable_handler_lock_;
uint32_t idle_pc_ref_cnt_ = 0;
int32_t disable_hotplug_bwcheck_ = 0;
int32_t disable_mask_layer_hint_ = 0;
int32_t enable_primary_reconfig_req_ = 0;
float set_max_lum_ = -1.0;
float set_min_lum_ = -1.0;
std::bitset<HWCCallbacks::kNumDisplays> pending_refresh_;
CWB cwb_;
std::weak_ptr<DisplayConfig::ConfigCallback> qsync_callback_;
std::weak_ptr<DisplayConfig::ConfigCallback> idle_callback_;
std::mutex callbacks_lock_;
std::unordered_map<int64_t, std::shared_ptr<IDisplayConfigCallback>> callback_clients_;
uint64_t callback_client_id_ = 0;
bool async_powermode_ = false;
bool async_power_mode_triggered_ = false;
bool async_vds_creation_ = false;
bool power_state_transition_[HWCCallbacks::kNumDisplays] = {};
bool tui_state_transition_[HWCCallbacks::kNumDisplays] = {};
std::bitset<HWCCallbacks::kNumDisplays> display_ready_;
bool secure_session_active_ = false;
bool is_idle_time_up_ = false;
std::shared_ptr<IPCIntf> ipc_intf_ = nullptr;
bool primary_pending_ = true;
Locker primary_display_lock_;
std::map <hwc2_display_t, sdm::DisplayType> map_active_displays_;
vector<HWDisplayInfo> virtual_display_list_ = {};
bool tui_start_success_ = false;
std::future<int> commit_done_future_;
};
} // namespace sdm
#endif // __HWC_SESSION_H__