1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <xf86drm.h>
6 #include <xf86drmMode.h>
7 #include <drm_fourcc.h>
8
9 #include "modeset.h"
10 #include "bo.h"
11 #include "dev.h"
12
initialize_screens(struct sp_dev * dev)13 int initialize_screens(struct sp_dev* dev) {
14 int ret, i, j;
15
16 for (i = 0; i < dev->num_connectors; i++) {
17 drmModeConnectorPtr c = dev->connectors[i];
18 drmModeModeInfoPtr m = NULL;
19 drmModeEncoderPtr e = NULL;
20 struct sp_crtc* cr = NULL;
21
22 if (c->connection != DRM_MODE_CONNECTED)
23 continue;
24
25 if (!c->count_modes) {
26 printf("connector has no modes, skipping\n");
27 continue;
28 }
29
30 /* Take the first unless there's a preferred mode */
31 m = &c->modes[0];
32 for (j = 0; j < c->count_modes; j++) {
33 drmModeModeInfoPtr tmp_m = &c->modes[j];
34
35 if (!(tmp_m->type & DRM_MODE_TYPE_PREFERRED))
36 continue;
37
38 m = tmp_m;
39 break;
40 }
41
42 if (!c->encoder_id) {
43 /*
44 * default drm encoder not attached connector, just
45 * select the first one.
46 */
47 if (dev->num_encoders) {
48 e = dev->encoders[0];
49 c->encoder_id = e->encoder_id;
50 } else {
51 printf("no encoder attached to the connector\n");
52 continue;
53 }
54 }
55
56 for (j = 0; j < dev->num_encoders; j++) {
57 e = dev->encoders[j];
58 if (e->encoder_id == c->encoder_id)
59 break;
60 }
61 if (j == dev->num_encoders) {
62 printf("could not find encoder for the connector\n");
63 continue;
64 }
65
66 if (!e->crtc_id) {
67 /*
68 * default drm crtc not attached encoder, just
69 * select the first one.
70 */
71 if (dev->num_crtcs) {
72 cr = &dev->crtcs[j];
73 e->crtc_id = cr->crtc->crtc_id;
74 } else {
75 printf("no crtc attached to the encoder\n");
76 continue;
77 }
78 }
79
80 for (j = 0; j < dev->num_crtcs; j++) {
81 cr = &dev->crtcs[j];
82
83 if (cr->crtc->crtc_id == e->crtc_id)
84 break;
85 }
86 if (j == dev->num_crtcs) {
87 printf("could not find crtc for the encoder\n");
88 continue;
89 }
90 if (cr->scanout) {
91 printf("crtc already in use\n");
92 continue;
93 }
94
95 /* XXX: Hardcoding the format here... :| */
96 cr->scanout = create_sp_bo(dev, m->hdisplay, m->vdisplay,
97 24, 32, DRM_FORMAT_XRGB8888, 0);
98 if (!cr->scanout) {
99 printf("failed to create new scanout bo\n");
100 continue;
101 }
102
103 ret = add_fb_sp_bo(cr->scanout, DRM_FORMAT_XRGB8888);
104 if (ret) {
105 printf("failed to add fb ret=%d\n", ret);
106 continue;
107 }
108
109 //fill_bo(cr->scanout, 0xFF, 0x0, 0x0, 0xFF);
110
111 ret = drmModeSetCrtc(dev->fd, cr->crtc->crtc_id,
112 cr->scanout->fb_id, 0, 0, &c->connector_id,
113 1, m);
114 if (ret) {
115 printf("failed to set crtc mode ret=%d\n", ret);
116 continue;
117 }
118 cr->crtc = drmModeGetCrtc(dev->fd, cr->crtc->crtc_id);
119 /*
120 * Todo:
121 * I don't know why crtc mode is empty, just copy PREFERRED mode
122 * for it.
123 */
124 memcpy(&cr->crtc->mode, m, sizeof(*m));
125 }
126 return 0;
127 }
128
get_sp_plane(struct sp_dev * dev,struct sp_crtc * crtc)129 struct sp_plane* get_sp_plane(struct sp_dev* dev, struct sp_crtc* crtc) {
130 int i;
131
132 for (i = 0; i < dev->num_planes; i++) {
133 struct sp_plane* p = &dev->planes[i];
134
135 if (p->in_use)
136 continue;
137
138 if (!(p->plane->possible_crtcs & (1 << crtc->pipe)))
139 continue;
140
141 p->in_use = 1;
142 return p;
143 }
144 return NULL;
145 }
146
put_sp_plane(struct sp_plane * plane)147 void put_sp_plane(struct sp_plane* plane) {
148 drmModePlanePtr p;
149
150 /* Get the latest plane information (most notably the crtc_id) */
151 p = drmModeGetPlane(plane->dev->fd, plane->plane->plane_id);
152 if (p)
153 plane->plane = p;
154
155 if (plane->plane->crtc_id)
156 drmModeSetPlane(plane->dev->fd, plane->plane->plane_id,
157 plane->plane->crtc_id, 0, 0,
158 0, 0, 0, 0, 0, 0, 0, 0);
159
160 if (plane->bo) {
161 free_sp_bo(plane->bo);
162 plane->bo = NULL;
163 }
164 plane->in_use = 0;
165 }
166
set_sp_plane(struct sp_dev * dev,struct sp_plane * plane,struct sp_crtc * crtc,int x,int y)167 int set_sp_plane(struct sp_dev* dev, struct sp_plane* plane,
168 struct sp_crtc* crtc, int x, int y) {
169 int ret;
170 uint32_t w, h;
171
172 w = plane->bo->width;
173 h = plane->bo->height;
174
175 if ((w + x) > crtc->crtc->mode.hdisplay)
176 w = crtc->crtc->mode.hdisplay - x;
177 if ((h + y) > crtc->crtc->mode.vdisplay)
178 h = crtc->crtc->mode.vdisplay - y;
179
180 ret = drmModeSetPlane(dev->fd, plane->plane->plane_id,
181 crtc->crtc->crtc_id, plane->bo->fb_id, 0, x, y, w, h,
182 0, 0, w << 16, h << 16);
183 if (ret) {
184 printf("failed to set plane to crtc ret=%d\n", ret);
185 return ret;
186 }
187
188 return ret;
189 }
190 #ifdef USE_ATOMIC_API
set_sp_plane_pset(struct sp_dev * dev,struct sp_plane * plane,drmModePropertySetPtr pset,struct sp_crtc * crtc,int x,int y)191 int set_sp_plane_pset(struct sp_dev* dev, struct sp_plane* plane,
192 drmModePropertySetPtr pset, struct sp_crtc* crtc, int x, int y) {
193 int ret;
194 uint32_t w, h;
195
196 w = plane->bo->width;
197 h = plane->bo->height;
198
199 if ((w + x) > crtc->crtc->mode.hdisplay)
200 w = crtc->crtc->mode.hdisplay - x;
201 if ((h + y) > crtc->crtc->mode.vdisplay)
202 h = crtc->crtc->mode.vdisplay - y;
203
204 ret = drmModePropertySetAdd(pset, plane->plane->plane_id,
205 plane->crtc_pid, crtc->crtc->crtc_id)
206 || drmModePropertySetAdd(pset, plane->plane->plane_id,
207 plane->fb_pid, plane->bo->fb_id)
208 || drmModePropertySetAdd(pset, plane->plane->plane_id,
209 plane->crtc_x_pid, x)
210 || drmModePropertySetAdd(pset, plane->plane->plane_id,
211 plane->crtc_y_pid, y)
212 || drmModePropertySetAdd(pset, plane->plane->plane_id,
213 plane->crtc_w_pid, w)
214 || drmModePropertySetAdd(pset, plane->plane->plane_id,
215 plane->crtc_h_pid, h)
216 || drmModePropertySetAdd(pset, plane->plane->plane_id,
217 plane->src_x_pid, 0)
218 || drmModePropertySetAdd(pset, plane->plane->plane_id,
219 plane->src_y_pid, 0)
220 || drmModePropertySetAdd(pset, plane->plane->plane_id,
221 plane->src_w_pid, w << 16)
222 || drmModePropertySetAdd(pset, plane->plane->plane_id,
223 plane->src_h_pid, h << 16);
224 if (ret) {
225 printf("failed to add properties to the set\n");
226 return -1;
227 }
228
229 return ret;
230 }
231 #endif
232