#include "displayqueue.h"
#include "displayplanemanager.h"
+#include "drmdisplaymanager.h"
namespace hwcomposer {
static const int32_t kUmPerInch = 25400;
-DrmDisplay::DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id)
- : PhysicalDisplay(gpu_fd, pipe_id), crtc_id_(crtc_id), connector_(0) {
+DrmDisplay::DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id,
+ DrmDisplayManager *manager)
+ : PhysicalDisplay(gpu_fd, pipe_id),
+ crtc_id_(crtc_id),
+ connector_(0),
+ manager_(manager) {
memset(¤t_mode_, 0, sizeof(current_mode_));
}
}
bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info,
- const drmModeConnector *connector) {
+ const drmModeConnector *connector,
+ uint32_t config) {
IHOTPLUGEVENTTRACE("DrmDisplay::Connect recieved.");
// TODO(kalyan): Add support for multi monitor case.
if (connector_ && connector->connector_id == connector_) {
mmWidth_ = connector->mmWidth;
mmHeight_ = connector->mmHeight;
SetDisplayAttribute(mode_info);
+ config_ = config;
ScopedDrmObjectPropertyPtr connector_props(drmModeObjectGetProperties(
gpu_fd_, connector_, DRM_MODE_OBJECT_CONNECTOR));
if (!configs) {
display_lock_.lock();
*num_configs = modes_.size();
+ IHOTPLUGEVENTTRACE(
+ "GetDisplayConfigs: Total Configs: %d pipe: %d display: %p",
+ *num_configs, pipe_, this);
display_lock_.unlock();
return true;
}
+ IHOTPLUGEVENTTRACE(
+ "GetDisplayConfigs: Populating Configs: %d pipe: %d display: %p",
+ *num_configs, pipe_, this);
uint32_t size = *num_configs;
for (uint32_t i = 0; i < size; i++)
configs[i] = i;
return true;
}
+void DrmDisplay::NotifyClientsOfDisplayChangeStatus() {
+ manager_->NotifyClientsOfDisplayChangeStatus();
+}
+
bool DrmDisplay::TestCommit(
const std::vector<OverlayPlane> &commit_planes) const {
ScopedDrmAtomicReqPtr pset(drmModeAtomicAlloc());
#include "physicaldisplay.h"
namespace hwcomposer {
+class DrmDisplayManager;
class DisplayPlaneState;
class DisplayQueue;
class NativeBufferHandler;
class DrmDisplay : public PhysicalDisplay {
public:
- DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id);
+ DrmDisplay(uint32_t gpu_fd, uint32_t pipe_id, uint32_t crtc_id,
+ DrmDisplayManager *manager);
~DrmDisplay() override;
bool GetDisplayAttribute(uint32_t config, HWCDisplayAttribute attribute,
}
bool ConnectDisplay(const drmModeModeInfo &mode_info,
- const drmModeConnector *connector);
+ const drmModeConnector *connector, uint32_t config);
void SetDrmModeInfo(const std::vector<drmModeModeInfo> &mode_info);
void SetDisplayAttribute(const drmModeModeInfo &mode_info);
std::unique_ptr<DisplayPlane> &cursor_plane,
std::vector<std::unique_ptr<DisplayPlane>> &overlay_planes) override;
+ void NotifyClientsOfDisplayChangeStatus() override;
+
private:
void ShutDownPipe();
void GetDrmObjectPropertyValue(const char *name,
drmModeModeInfo current_mode_;
std::vector<drmModeModeInfo> modes_;
SpinLock display_lock_;
+ DrmDisplayManager *manager_;
};
} // namespace hwcomposer
return false;
}
- std::unique_ptr<DrmDisplay> display(new DrmDisplay(fd_, i, c->crtc_id));
+ std::unique_ptr<DrmDisplay> display(
+ new DrmDisplay(fd_, i, c->crtc_id, this));
if (!display->Initialize(buffer_handler_.get())) {
ETRACE("Failed to Initialize Display %d", c->crtc_id);
return false;
// At initilaization preferred mode is set!
if (!display->IsConnected() &&
encoder->crtc_id == display->CrtcId() &&
- display->ConnectDisplay(mode.at(preferred_mode),
- connector.get())) {
+ display->ConnectDisplay(mode.at(preferred_mode), connector.get(),
+ preferred_mode)) {
IHOTPLUGEVENTTRACE("Connected %d with crtc: %d \n",
encoder->crtc_id, display->CrtcId());
// Set the modes supported for each display
display->SetDrmModeInfo(mode);
- display->NotifyClientOfConnectedState();
break;
}
}
for (auto &display : displays_) {
if (!display->IsConnected() &&
(encoder->possible_crtcs & (1 << display->Pipe())) &&
- display->ConnectDisplay(mode.at(preferred_mode),
- connector.get())) {
+ display->ConnectDisplay(mode.at(preferred_mode), connector.get(),
+ preferred_mode)) {
IHOTPLUGEVENTTRACE("connected pipe:%d \n", display->Pipe());
// Set the modes supported for each display
display->SetDrmModeInfo(mode);
- display->NotifyClientOfConnectedState();
break;
}
}
for (auto &display : displays_) {
if (!display->IsConnected()) {
display->DisConnect();
- display->NotifyClientOfDisConnectedState();
} else {
connected_displays_.emplace_back(display.get());
}
}
spin_lock_.unlock();
+
+ NotifyClientsOfDisplayChangeStatus();
return true;
}
+void DrmDisplayManager::NotifyClientsOfDisplayChangeStatus() {
+ spin_lock_.lock();
+ for (auto &display : displays_) {
+ if (!display->IsConnected()) {
+ display->NotifyClientOfDisConnectedState();
+ } else {
+ display->NotifyClientOfConnectedState();
+ }
+ }
+
+ spin_lock_.unlock();
+}
+
NativeDisplay *DrmDisplayManager::GetDisplay(uint32_t display_id) {
CTRACE();
spin_lock_.lock();
void RegisterHotPlugEventCallback(
std::shared_ptr<DisplayHotPlugEventCallback> callback) override;
+ void NotifyClientsOfDisplayChangeStatus();
+
protected:
void HandleWait() override;
void HandleRoutine() override;
IHOTPLUGEVENTTRACE("PhysicalDisplay::MarkForDisconnect recieved.");
display_state_ |= kDisconnectionInProgress;
display_state_ |= kRefreshClonedDisplays;
+ if (pipe_ == 0 && !(display_state_ & kInitialized))
+ display_state_ |= kHandlePendingHotPlugNotifications;
+
modeset_lock_.unlock();
}
bool PhysicalDisplay::SetActiveConfig(uint32_t config) {
// update the activeConfig
+ IHOTPLUGEVENTTRACE(
+ "SetActiveConfig: New config to be used %d pipe: %p display: %p", config,
+ pipe_, this);
config_ = config;
display_queue_->DisplayConfigurationChanged();
display_state_ |= kNeedsModeset;
bool PhysicalDisplay::GetActiveConfig(uint32_t *config) {
if (!config)
return false;
-
+ IHOTPLUGEVENTTRACE(
+ "GetActiveConfig: Current config being used Config: %d pipe: %d display: "
+ "%p",
+ config_, pipe_, this);
*config = config_;
return true;
}
if (display_state_ & kRefreshClonedDisplays) {
RefreshClones();
}
+
+ bool handle_hoplug_notifications = false;
+ if (display_state_ & kHandlePendingHotPlugNotifications) {
+ display_state_ &= ~kHandlePendingHotPlugNotifications;
+ handle_hoplug_notifications = true;
+ }
modeset_lock_.unlock();
+ if (handle_hoplug_notifications) {
+ NotifyClientsOfDisplayChangeStatus();
+ }
+
bool cloned = !clones_.empty();
bool success =
display_queue_->QueueUpdate(source_layers, retire_fence, false);
hotplug_callback_ = callback;
bool connected = display_state_ & kConnected;
modeset_lock_.unlock();
-
- if (hotplug_callback_) {
+ if (hotplug_callback_ && pipe_ == 0) {
if (connected) {
hotplug_callback_->Callback(hot_plug_display_id_, true);
} else {
*/
virtual bool InitializeDisplay() = 0;
+ virtual void NotifyClientsOfDisplayChangeStatus() = 0;
+
/**
* API for informing the display that it might be disconnected in near
* future.
kUpdateDisplay = 1 << 4,
kDisconnectionInProgress = 1 << 5,
kInitialized = 1 << 6, // Display Queue is initialized.
- kRefreshClonedDisplays = 1 << 7
+ kRefreshClonedDisplays = 1 << 7,
+ kHandlePendingHotPlugNotifications = 1 << 8
};
uint32_t pipe_;