Home | History | Annotate | Download | only in src
      1 #include <stdio.h>
      2 #include <iostream>
      3 #include <unistd.h>
      4 #include <fcntl.h>
      5 #include <cassert>
      6 
      7 #include <kms++/kms++.h>
      8 #include "helpers.h"
      9 
     10 using namespace std;
     11 
     12 namespace kms
     13 {
     14 
     15 struct CrtcPriv
     16 {
     17 	drmModeCrtcPtr drm_crtc;
     18 };
     19 
     20 Crtc::Crtc(Card &card, uint32_t id, uint32_t idx)
     21 	:DrmPropObject(card, id, DRM_MODE_OBJECT_CRTC, idx)
     22 {
     23 	m_priv = new CrtcPriv();
     24 	m_priv->drm_crtc = drmModeGetCrtc(this->card().fd(), this->id());
     25 	assert(m_priv->drm_crtc);
     26 }
     27 
     28 Crtc::~Crtc()
     29 {
     30 	drmModeFreeCrtc(m_priv->drm_crtc);
     31 	delete m_priv;
     32 }
     33 
     34 void Crtc::refresh()
     35 {
     36 	drmModeFreeCrtc(m_priv->drm_crtc);
     37 
     38 	m_priv->drm_crtc = drmModeGetCrtc(this->card().fd(), this->id());
     39 	assert(m_priv->drm_crtc);
     40 }
     41 
     42 void Crtc::setup()
     43 {
     44 	for (Plane* plane : card().get_planes()) {
     45 		if (plane->supports_crtc(this))
     46 			m_possible_planes.push_back(plane);
     47 	}
     48 }
     49 
     50 void Crtc::restore_mode(Connector* conn)
     51 {
     52 	auto c = m_priv->drm_crtc;
     53 
     54 	uint32_t conns[] = { conn->id() };
     55 
     56 	drmModeSetCrtc(card().fd(), id(), c->buffer_id,
     57 		       c->x, c->y,
     58 		       conns, 1, &c->mode);
     59 }
     60 
     61 int Crtc::set_mode(Connector* conn, const Videomode& mode)
     62 {
     63 	AtomicReq req(card());
     64 
     65 	unique_ptr<Blob> blob = mode.to_blob(card());
     66 
     67 	req.add(conn, {
     68 			{ "CRTC_ID", this->id() },
     69 		});
     70 
     71 	req.add(this, {
     72 			{ "ACTIVE", 1 },
     73 			{ "MODE_ID", blob->id() },
     74 		});
     75 
     76 	int r = req.commit_sync(true);
     77 
     78 	refresh();
     79 
     80 	return r;
     81 }
     82 
     83 int Crtc::set_mode(Connector* conn, Framebuffer& fb, const Videomode& mode)
     84 {
     85 	uint32_t conns[] = { conn->id() };
     86 	drmModeModeInfo drmmode = video_mode_to_drm_mode(mode);
     87 
     88 	return drmModeSetCrtc(card().fd(), id(), fb.id(),
     89 			      0, 0,
     90 			      conns, 1, &drmmode);
     91 }
     92 
     93 int Crtc::disable_mode()
     94 {
     95 	return drmModeSetCrtc(card().fd(), id(), 0, 0, 0, 0, 0, 0);
     96 }
     97 
     98 static inline uint32_t conv(float x)
     99 {
    100 	// XXX fix the conversion for fractional part
    101 	return ((uint32_t)x) << 16;
    102 }
    103 
    104 int Crtc::set_plane(Plane* plane, Framebuffer& fb,
    105 		    int32_t dst_x, int32_t dst_y, uint32_t dst_w, uint32_t dst_h,
    106 		    float src_x, float src_y, float src_w, float src_h)
    107 {
    108 	return drmModeSetPlane(card().fd(), plane->id(), id(), fb.id(), 0,
    109 			       dst_x, dst_y, dst_w, dst_h,
    110 			       conv(src_x), conv(src_y), conv(src_w), conv(src_h));
    111 }
    112 
    113 int Crtc::disable_plane(Plane* plane)
    114 {
    115 	return drmModeSetPlane(card().fd(), plane->id(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    116 }
    117 
    118 Plane* Crtc::get_primary_plane()
    119 {
    120 	Plane *primary = nullptr;
    121 
    122 	for (Plane* p : get_possible_planes()) {
    123 		if (p->plane_type() != PlaneType::Primary)
    124 			continue;
    125 
    126 		if (p->crtc_id() == id())
    127 			return p;
    128 
    129 		primary = p;
    130 	}
    131 
    132 	if (primary)
    133 		return primary;
    134 
    135 	throw invalid_argument(string("No primary plane for crtc ") + to_string(id()));
    136 }
    137 
    138 int Crtc::page_flip(Framebuffer& fb, void *data)
    139 {
    140 	return drmModePageFlip(card().fd(), id(), fb.id(), DRM_MODE_PAGE_FLIP_EVENT, data);
    141 }
    142 
    143 uint32_t Crtc::buffer_id() const
    144 {
    145 	return m_priv->drm_crtc->buffer_id;
    146 }
    147 
    148 uint32_t Crtc::x() const
    149 {
    150 	return m_priv->drm_crtc->x;
    151 }
    152 
    153 uint32_t Crtc::y() const
    154 {
    155 	return m_priv->drm_crtc->y;
    156 }
    157 
    158 uint32_t Crtc::width() const
    159 {
    160 	return m_priv->drm_crtc->width;
    161 }
    162 
    163 uint32_t Crtc::height() const
    164 {
    165 	return m_priv->drm_crtc->height;
    166 }
    167 
    168 int Crtc::mode_valid() const
    169 {
    170 	return m_priv->drm_crtc->mode_valid;
    171 }
    172 
    173 Videomode Crtc::mode() const
    174 {
    175 	return drm_mode_to_video_mode(m_priv->drm_crtc->mode);
    176 }
    177 
    178 int Crtc::gamma_size() const
    179 {
    180 	return m_priv->drm_crtc->gamma_size;
    181 }
    182 
    183 }
    184