return composition_map_[display]->AddLayer(layer, bo, crtc, plane);
}
+int DrmComposition::AddDpmsMode(int display, uint32_t dpms_mode) {
+ return composition_map_[display]->AddDpmsMode(dpms_mode);
+}
+
std::unique_ptr<DrmDisplayComposition> DrmComposition::TakeDisplayComposition(
int display) {
return std::move(composition_map_[display]);
virtual unsigned GetRemainingLayers(int display, unsigned num_needed) const;
virtual int AddLayer(int display, hwc_layer_1_t *layer, hwc_drm_bo_t *bo);
+ int AddDpmsMode(int display, uint32_t dpms_mode);
std::unique_ptr<DrmDisplayComposition> TakeDisplayComposition(int display);
#include <cutils/log.h>
#include <sw_sync.h>
#include <sync/sync.h>
+#include <xf86drmMode.h>
namespace android {
importer_(NULL),
type_(DRM_COMPOSITION_TYPE_EMPTY),
timeline_fd_(-1),
- timeline_(0) {
+ timeline_(0),
+ dpms_mode_(DRM_MODE_DPMS_ON) {
}
DrmDisplayComposition::~DrmDisplayComposition() {
return 0;
}
+int DrmDisplayComposition::AddDpmsMode(uint32_t dpms_mode) {
+ if (!validate_composition_type(DRM_COMPOSITION_TYPE_DPMS))
+ return -EINVAL;
+ dpms_mode_ = dpms_mode;
+ type_ = DRM_COMPOSITION_TYPE_DPMS;
+ return 0;
+}
+
int DrmDisplayComposition::FinishComposition() {
int ret = sw_sync_timeline_inc(timeline_fd_, timeline_);
if (ret)
DrmCompositionLayerVector_t *DrmDisplayComposition::GetCompositionLayers() {
return &layers_;
}
+
+uint32_t DrmDisplayComposition::dpms_mode() const {
+ return dpms_mode_;
+}
}
enum DrmCompositionType {
DRM_COMPOSITION_TYPE_EMPTY,
DRM_COMPOSITION_TYPE_FRAME,
+ DRM_COMPOSITION_TYPE_DPMS,
};
typedef struct DrmCompositionLayer {
int AddLayer(hwc_layer_1_t *layer, hwc_drm_bo_t *bo, DrmCrtc *crtc,
DrmPlane *plane);
+ int AddDpmsMode(uint32_t dpms_mode);
int FinishComposition();
DrmCompositionLayerVector_t *GetCompositionLayers();
+ uint32_t dpms_mode() const;
private:
DrmDisplayComposition(const DrmDisplayComposition &) = delete;
int timeline_;
DrmCompositionLayerVector_t layers_;
+ uint32_t dpms_mode_;
};
}
worker_(this),
frame_no_(0),
initialized_(false),
+ active_(false),
dump_frames_composited_(0),
dump_last_timestamp_ns_(0) {
struct timespec ts;
std::unique_ptr<DrmDisplayComposition> composition) {
switch (composition->type()) {
case DRM_COMPOSITION_TYPE_FRAME:
+ if (!active_)
+ return -ENODEV;
+ break;
+ case DRM_COMPOSITION_TYPE_DPMS:
+ /*
+ * Update the state as soon as we get it so we can start/stop queuing
+ * frames asap.
+ */
+ active_ = (composition->dpms_mode() == DRM_MODE_DPMS_ON);
break;
case DRM_COMPOSITION_TYPE_EMPTY:
return 0;
return ret;
}
+int DrmDisplayCompositor::ApplyDpms(DrmDisplayComposition *display_comp) {
+ DrmConnector *conn = drm_->GetConnectorForDisplay(display_);
+ if (!conn) {
+ ALOGE("Failed to get DrmConnector for display %d", display_);
+ return -ENODEV;
+ }
+
+ const DrmProperty &prop = conn->dpms_property();
+ int ret = drmModeConnectorSetProperty(drm_->fd(), conn->id(), prop.id(),
+ display_comp->dpms_mode());
+ if (ret) {
+ ALOGE("Failed to set DPMS property for connector %d", conn->id());
+ return ret;
+ }
+ return 0;
+}
+
int DrmDisplayCompositor::Composite() {
ATRACE_CALL();
int ret = pthread_mutex_lock(&lock_);
}
++dump_frames_composited_;
break;
+ case DRM_COMPOSITION_TYPE_DPMS:
+ ret = ApplyDpms(composition.get());
+ if (ret)
+ ALOGE("Failed to apply dpms for display %d", display_);
+ return ret;
default:
ALOGE("Unknown composition type %d", composition->type());
return -EINVAL;
DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
int ApplyFrame(DrmDisplayComposition *display_comp);
+ int ApplyDpms(DrmDisplayComposition *display_comp);
DrmResources *drm_;
int display_;
uint64_t frame_no_;
bool initialized_;
+ bool active_;
// mutable since we need to acquire in HaveQueuedComposites
mutable pthread_mutex_t lock_;
return -EINVAL;
}
- DrmConnector *c = GetConnectorForDisplay(display);
- if (!c) {
- ALOGE("Failed to get DrmConnector for display %d", display);
- return -ENODEV;
+ DrmComposition *comp = (DrmComposition *)compositor_.CreateComposition(NULL);
+ if (!comp) {
+ ALOGE("Failed to create composition for dpms on %d", display);
+ return -ENOMEM;
}
-
- const DrmProperty &prop = c->dpms_property();
- int ret = drmModeConnectorSetProperty(fd_, c->id(), prop.id(), mode);
+ int ret = comp->AddDpmsMode(display, mode);
if (ret) {
- ALOGE("Failed to set DPMS property for connector %d", c->id());
+ ALOGE("Failed to add dpms %ld to composition on %d %d", mode, display, ret);
+ delete comp;
+ return ret;
+ }
+ ret = compositor_.QueueComposition((Composition *)comp);
+ if (ret) {
+ ALOGE("Failed to queue dpms composition on %d %d", display, ret);
return ret;
}
-
return 0;
}